@sap-ux/preview-middleware 0.6.3 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base/flp.d.ts +1 -0
- package/dist/base/flp.js +49 -8
- package/dist/client/adp/controllers/AddFragment.controller.js +1 -27
- package/dist/client/adp/controllers/AddFragment.controller.ts +2 -24
- package/dist/client/cpe/changes/flex-change.js +46 -0
- package/dist/client/cpe/changes/flex-change.ts +49 -0
- package/dist/client/cpe/changes/index.js +12 -0
- package/dist/client/cpe/changes/index.ts +1 -0
- package/dist/client/cpe/changes/service.js +164 -0
- package/dist/client/cpe/changes/service.ts +264 -0
- package/dist/client/cpe/control-data.js +201 -0
- package/dist/client/cpe/control-data.ts +304 -0
- package/dist/client/cpe/documentation.js +166 -0
- package/dist/client/cpe/documentation.ts +166 -0
- package/dist/client/cpe/facade.js +95 -0
- package/dist/client/cpe/facade.ts +95 -0
- package/dist/client/cpe/init.js +62 -12
- package/dist/client/cpe/init.ts +70 -5
- package/dist/client/cpe/logger.js +32 -0
- package/dist/client/cpe/logger.ts +26 -0
- package/dist/client/cpe/outline/index.js +26 -0
- package/dist/client/cpe/outline/index.ts +34 -0
- package/dist/client/cpe/outline/nodes.js +58 -0
- package/dist/client/cpe/outline/nodes.ts +52 -0
- package/dist/client/cpe/outline/utils.js +38 -0
- package/dist/client/cpe/outline/utils.ts +29 -0
- package/dist/client/cpe/selection.js +169 -0
- package/dist/client/cpe/selection.ts +237 -0
- package/dist/client/cpe/types.js +6 -0
- package/dist/client/cpe/types.ts +53 -0
- package/dist/client/cpe/utils.js +50 -0
- package/dist/client/cpe/utils.ts +62 -0
- package/dist/client/flp/WorkspaceConnector.js +65 -0
- package/dist/client/flp/WorkspaceConnector.ts +66 -0
- package/dist/client/thirdparty/@sap-ux-private/control-property-editor-common.js +272 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/ui5/middleware.js +2 -1
- package/package.json +5 -7
- package/templates/flp/editor.html +11 -15
- package/templates/flp/sandbox.html +2 -1
- package/templates/flp/workspaceConnector.js +0 -76
package/dist/base/flp.d.ts
CHANGED
package/dist/base/flp.js
CHANGED
|
@@ -15,6 +15,15 @@ const fs_1 = require("fs");
|
|
|
15
15
|
const path_1 = require("path");
|
|
16
16
|
const express_1 = require("express");
|
|
17
17
|
const flex_1 = require("./flex");
|
|
18
|
+
const DEVELOPER_MODE_CONFIG = new Map([
|
|
19
|
+
// Run application in design time mode
|
|
20
|
+
// Adds bindingString to BindingInfo objects. Required to create and read PropertyBinding changes
|
|
21
|
+
['xx-designMode', 'true'],
|
|
22
|
+
// In design mode, the controller code will not be executed by default, which is not desired in our case, so we suppress the deactivation
|
|
23
|
+
['xx-suppressDeactivationOfControllerCode', 'true'],
|
|
24
|
+
// Make sure that XML preprocessing results are correctly invalidated
|
|
25
|
+
['xx-viewCache', 'false']
|
|
26
|
+
]);
|
|
18
27
|
/**
|
|
19
28
|
* Default theme
|
|
20
29
|
*/
|
|
@@ -93,7 +102,8 @@ class FlpSandbox {
|
|
|
93
102
|
libs: Object.keys((_g = (_f = (_e = manifest['sap.ui5']) === null || _e === void 0 ? void 0 : _e.dependencies) === null || _f === void 0 ? void 0 : _f.libs) !== null && _g !== void 0 ? _g : {}).join(','),
|
|
94
103
|
theme: ui5Theme,
|
|
95
104
|
flex,
|
|
96
|
-
resources: Object.assign(Object.assign({}, resources), { [PREVIEW_URL.client.ns]: PREVIEW_URL.client.url })
|
|
105
|
+
resources: Object.assign(Object.assign({}, resources), { [PREVIEW_URL.client.ns]: PREVIEW_URL.client.url }),
|
|
106
|
+
bootstrapOptions: ''
|
|
97
107
|
},
|
|
98
108
|
locateReuseLibsScript: (_h = this.config.libs) !== null && _h !== void 0 ? _h : (yield this.hasLocateReuseLibsScript())
|
|
99
109
|
};
|
|
@@ -107,6 +117,7 @@ class FlpSandbox {
|
|
|
107
117
|
if (this.rta) {
|
|
108
118
|
(_k = (_l = this.rta).options) !== null && _k !== void 0 ? _k : (_l.options = {});
|
|
109
119
|
this.rta.options.baseId = componentId !== null && componentId !== void 0 ? componentId : manifest['sap.app'].id;
|
|
120
|
+
this.rta.options.generator = 'changeUtils: SAPFioriTools-propertyEditor';
|
|
110
121
|
this.addEditorRoutes(this.rta);
|
|
111
122
|
}
|
|
112
123
|
this.addRoutesForAdditionalApps();
|
|
@@ -121,22 +132,33 @@ class FlpSandbox {
|
|
|
121
132
|
*/
|
|
122
133
|
addEditorRoutes(rta) {
|
|
123
134
|
var _a;
|
|
135
|
+
const cpe = (0, path_1.dirname)(require.resolve('@sap-ux/control-property-editor-sources'));
|
|
124
136
|
for (const editor of rta.editors) {
|
|
125
137
|
let previewUrl = editor.path;
|
|
126
138
|
if (editor.developerMode) {
|
|
127
139
|
previewUrl = `${previewUrl}.inner.html`;
|
|
128
140
|
(_a = editor.pluginScript) !== null && _a !== void 0 ? _a : (editor.pluginScript = 'open/ux/preview/client/cpe/init');
|
|
129
141
|
this.router.get(editor.path, ((_req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
142
|
+
var _b, _c;
|
|
130
143
|
const template = (0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../../templates/flp/editor.html'), 'utf-8');
|
|
131
144
|
const html = (0, ejs_1.render)(template, {
|
|
132
|
-
previewUrl: `${previewUrl}?sap-ui-xx-viewCache=false&fiori-tools-rta-mode=forAdaptation&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true#${this.config.intent.object}-${this.config.intent.action}
|
|
145
|
+
previewUrl: `${previewUrl}?sap-ui-xx-viewCache=false&fiori-tools-rta-mode=forAdaptation&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true#${this.config.intent.object}-${this.config.intent.action}`,
|
|
146
|
+
telemetry: (_c = (_b = rta.options) === null || _b === void 0 ? void 0 : _b.telemetry) !== null && _c !== void 0 ? _c : false
|
|
133
147
|
});
|
|
134
148
|
res.status(200).contentType('html').send(html);
|
|
135
149
|
})));
|
|
150
|
+
let path = (0, path_1.dirname)(editor.path);
|
|
151
|
+
if (!path.endsWith('/')) {
|
|
152
|
+
path = `${path}/`;
|
|
153
|
+
}
|
|
154
|
+
this.router.use(`${path}editor`, (0, express_1.static)(cpe));
|
|
136
155
|
}
|
|
137
156
|
this.router.get(previewUrl, ((_req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
138
157
|
const config = Object.assign({}, this.templateConfig);
|
|
139
158
|
config.flex = Object.assign(Object.assign({ layer: rta.layer }, rta.options), { developerMode: editor.developerMode === true, pluginScript: editor.pluginScript });
|
|
159
|
+
if (editor.developerMode === true) {
|
|
160
|
+
config.ui5.bootstrapOptions = serializeUi5Configuration(DEVELOPER_MODE_CONFIG);
|
|
161
|
+
}
|
|
140
162
|
const template = (0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../../templates/flp/sandbox.html'), 'utf-8');
|
|
141
163
|
const html = (0, ejs_1.render)(template, config);
|
|
142
164
|
res.status(200).contentType('html').send(html);
|
|
@@ -198,12 +220,7 @@ class FlpSandbox {
|
|
|
198
220
|
* @returns template configuration for flex.
|
|
199
221
|
*/
|
|
200
222
|
createFlexHandler() {
|
|
201
|
-
const workspaceConnectorPath = '/preview/WorkspaceConnector';
|
|
202
|
-
this.router.get(`/resources${workspaceConnectorPath}.js`, (_req, res) => {
|
|
203
|
-
res.status(200)
|
|
204
|
-
.contentType('text/javascript')
|
|
205
|
-
.send((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../../templates/flp/workspaceConnector.js'), 'utf-8'));
|
|
206
|
-
});
|
|
223
|
+
const workspaceConnectorPath = 'open/ux/preview/client/flp/WorkspaceConnector';
|
|
207
224
|
const api = `${PREVIEW_URL.api}/changes`;
|
|
208
225
|
this.router.use(api, (0, express_1.json)());
|
|
209
226
|
this.router.get(api, ((_req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -271,4 +288,28 @@ class FlpSandbox {
|
|
|
271
288
|
}
|
|
272
289
|
}
|
|
273
290
|
exports.FlpSandbox = FlpSandbox;
|
|
291
|
+
/**
|
|
292
|
+
* Creates an attribute string that can be added to an HTML element.
|
|
293
|
+
*
|
|
294
|
+
* @param attributes map with attributes and their values
|
|
295
|
+
* @param indent indentation thats inserted before each attribute
|
|
296
|
+
* @param prefix value that should be added at the start of to all attribute names
|
|
297
|
+
* @returns attribute string
|
|
298
|
+
*/
|
|
299
|
+
function serializeDataAttributes(attributes, indent = '', prefix = 'data') {
|
|
300
|
+
return [...attributes.entries()]
|
|
301
|
+
.map(([name, value]) => {
|
|
302
|
+
return `${indent}${prefix}-${name}="${value}"`;
|
|
303
|
+
})
|
|
304
|
+
.join('\n');
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Creates an attribute string that can be added to bootstrap script in a HTML file.
|
|
308
|
+
*
|
|
309
|
+
* @param config ui5 configuration options
|
|
310
|
+
* @returns attribute string
|
|
311
|
+
*/
|
|
312
|
+
function serializeUi5Configuration(config) {
|
|
313
|
+
return '\n' + serializeDataAttributes(config, ' ', 'data-sap-ui');
|
|
314
|
+
}
|
|
274
315
|
//# sourceMappingURL=flp.js.map
|
|
@@ -11,7 +11,6 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/core/mvc/Con
|
|
|
11
11
|
const ControlUtils = _interopRequireDefault(__ControlUtils);
|
|
12
12
|
const CommandExecutor = _interopRequireDefault(__CommandExecutor);
|
|
13
13
|
const getFragments = ___api_handler["getFragments"];
|
|
14
|
-
const getManifestAppdescr = ___api_handler["getManifestAppdescr"];
|
|
15
14
|
const writeFragment = ___api_handler["writeFragment"];
|
|
16
15
|
/**
|
|
17
16
|
* @namespace open.ux.preview.client.adp.controllers
|
|
@@ -212,32 +211,7 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/core/mvc/Con
|
|
|
212
211
|
index,
|
|
213
212
|
targetAggregation
|
|
214
213
|
} = fragmentData;
|
|
215
|
-
|
|
216
|
-
try {
|
|
217
|
-
manifest = await getManifestAppdescr();
|
|
218
|
-
if (!manifest) {
|
|
219
|
-
// Highly unlikely since adaptation projects are required to have manifest.appdescr_variant
|
|
220
|
-
throw new Error('Could not retrieve manifest');
|
|
221
|
-
}
|
|
222
|
-
} catch (e) {
|
|
223
|
-
MessageToast.show(e.message);
|
|
224
|
-
throw new Error(e.message);
|
|
225
|
-
}
|
|
226
|
-
const {
|
|
227
|
-
id,
|
|
228
|
-
reference,
|
|
229
|
-
namespace,
|
|
230
|
-
layer
|
|
231
|
-
} = manifest;
|
|
232
|
-
const flexSettings = {
|
|
233
|
-
baseId: reference,
|
|
234
|
-
developerMode: true,
|
|
235
|
-
layer: layer,
|
|
236
|
-
namespace: namespace,
|
|
237
|
-
projectId: id,
|
|
238
|
-
rootNamespace: namespace.split('/').slice(0, 2).join('/'),
|
|
239
|
-
scenario: undefined
|
|
240
|
-
};
|
|
214
|
+
const flexSettings = this.rta.getFlexSettings();
|
|
241
215
|
const overlay = OverlayRegistry.getOverlay(this.runtimeControl);
|
|
242
216
|
const designMetadata = overlay.getDesignTimeMetadata();
|
|
243
217
|
const modifiedValue = {
|
|
@@ -27,7 +27,7 @@ import type ElementOverlay from 'sap/ui/dt/ElementOverlay';
|
|
|
27
27
|
|
|
28
28
|
import ControlUtils from '../control-utils';
|
|
29
29
|
import CommandExecutor from '../command-executor';
|
|
30
|
-
import {
|
|
30
|
+
import { getFragments, writeFragment } from '../api-handler';
|
|
31
31
|
|
|
32
32
|
interface CreateFragmentProps {
|
|
33
33
|
fragmentName: string;
|
|
@@ -332,30 +332,8 @@ export default class AddFragment extends Controller {
|
|
|
332
332
|
*/
|
|
333
333
|
private async createFragmentChange(fragmentData: CreateFragmentProps) {
|
|
334
334
|
const { fragmentName, index, targetAggregation } = fragmentData;
|
|
335
|
-
let manifest: ManifestAppdescr;
|
|
336
|
-
try {
|
|
337
|
-
manifest = await getManifestAppdescr();
|
|
338
335
|
|
|
339
|
-
|
|
340
|
-
// Highly unlikely since adaptation projects are required to have manifest.appdescr_variant
|
|
341
|
-
throw new Error('Could not retrieve manifest');
|
|
342
|
-
}
|
|
343
|
-
} catch (e) {
|
|
344
|
-
MessageToast.show(e.message);
|
|
345
|
-
throw new Error(e.message);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
const { id, reference, namespace, layer } = manifest;
|
|
349
|
-
|
|
350
|
-
const flexSettings = {
|
|
351
|
-
baseId: reference,
|
|
352
|
-
developerMode: true,
|
|
353
|
-
layer: layer,
|
|
354
|
-
namespace: namespace,
|
|
355
|
-
projectId: id,
|
|
356
|
-
rootNamespace: namespace.split('/').slice(0, 2).join('/'),
|
|
357
|
-
scenario: undefined
|
|
358
|
-
};
|
|
336
|
+
const flexSettings = this.rta.getFlexSettings();
|
|
359
337
|
|
|
360
338
|
const overlay = OverlayRegistry.getOverlay(this.runtimeControl as UI5Element);
|
|
361
339
|
const designMetadata = overlay.getDesignTimeMetadata();
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
sap.ui.define(["sap/ui/rta/command/CommandFactory"], function (CommandFactory) {
|
|
4
|
+
"use strict";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Function to check a give value is a binding expression.
|
|
8
|
+
*
|
|
9
|
+
* @param value value to be checked.
|
|
10
|
+
* @returns boolean
|
|
11
|
+
*/
|
|
12
|
+
function isBindingExpression(value) {
|
|
13
|
+
return value.includes('{') && value.includes('}');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* @param options UI5 adaptation options
|
|
19
|
+
* @param change changed property of a control
|
|
20
|
+
*/
|
|
21
|
+
async function applyChange(options, change) {
|
|
22
|
+
const {
|
|
23
|
+
rta
|
|
24
|
+
} = options;
|
|
25
|
+
const modifiedControl = sap.ui.getCore().byId(change.controlId);
|
|
26
|
+
if (!modifiedControl) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const flexSettings = rta.getFlexSettings();
|
|
30
|
+
const changeType = typeof change.value === 'string' && isBindingExpression(change.value) ? 'BindProperty' : 'Property';
|
|
31
|
+
const property = typeof change.value === 'string' && isBindingExpression(change.value) ? 'newBinding' : 'newValue';
|
|
32
|
+
const modifiedValue = {
|
|
33
|
+
generator: flexSettings.generator,
|
|
34
|
+
propertyName: change.propertyName,
|
|
35
|
+
[property]: change.value
|
|
36
|
+
};
|
|
37
|
+
const command = await CommandFactory.getCommandFor(modifiedControl, changeType, modifiedValue, null, flexSettings);
|
|
38
|
+
await rta.getCommandStack().pushAndExecute(command);
|
|
39
|
+
}
|
|
40
|
+
var __exports = {
|
|
41
|
+
__esModule: true
|
|
42
|
+
};
|
|
43
|
+
__exports.applyChange = applyChange;
|
|
44
|
+
return __exports;
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=flex-change.js.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type FlexCommand from 'sap/ui/rta/command/FlexCommand';
|
|
2
|
+
import CommandFactory from 'sap/ui/rta/command/CommandFactory';
|
|
3
|
+
import type { PropertyChange } from '@sap-ux-private/control-property-editor-common';
|
|
4
|
+
import type { UI5AdaptationOptions } from '../types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Function to check a give value is a binding expression.
|
|
8
|
+
*
|
|
9
|
+
* @param value value to be checked.
|
|
10
|
+
* @returns boolean
|
|
11
|
+
*/
|
|
12
|
+
function isBindingExpression(value: string): boolean {
|
|
13
|
+
return value.includes('{') && value.includes('}');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* @param options UI5 adaptation options
|
|
19
|
+
* @param change changed property of a control
|
|
20
|
+
*/
|
|
21
|
+
export async function applyChange(options: UI5AdaptationOptions, change: PropertyChange): Promise<void> {
|
|
22
|
+
const { rta } = options;
|
|
23
|
+
const modifiedControl = sap.ui.getCore().byId(change.controlId);
|
|
24
|
+
if (!modifiedControl) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const flexSettings = rta.getFlexSettings();
|
|
29
|
+
|
|
30
|
+
const changeType =
|
|
31
|
+
typeof change.value === 'string' && isBindingExpression(change.value) ? 'BindProperty' : 'Property';
|
|
32
|
+
|
|
33
|
+
const property = typeof change.value === 'string' && isBindingExpression(change.value) ? 'newBinding' : 'newValue';
|
|
34
|
+
const modifiedValue = {
|
|
35
|
+
generator: flexSettings.generator,
|
|
36
|
+
propertyName: change.propertyName,
|
|
37
|
+
[property]: change.value
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const command = await CommandFactory.getCommandFor<FlexCommand>(
|
|
41
|
+
modifiedControl,
|
|
42
|
+
changeType,
|
|
43
|
+
modifiedValue,
|
|
44
|
+
null,
|
|
45
|
+
flexSettings
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
await rta.getCommandStack().pushAndExecute(command);
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ChangeService } from './service';
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
sap.ui.define([
|
|
3
|
+
'open/ux/preview/client/thirdparty/@sap-ux-private/control-property-editor-common',
|
|
4
|
+
'./flex-change',
|
|
5
|
+
'sap/base/Log'
|
|
6
|
+
], function (___sap_ux_private_control_property_editor_common, ___flex_change, Log) {
|
|
7
|
+
'use strict';
|
|
8
|
+
const changeProperty = ___sap_ux_private_control_property_editor_common['changeProperty'];
|
|
9
|
+
const changeStackModified = ___sap_ux_private_control_property_editor_common['changeStackModified'];
|
|
10
|
+
const deletePropertyChanges = ___sap_ux_private_control_property_editor_common['deletePropertyChanges'];
|
|
11
|
+
const propertyChangeFailed = ___sap_ux_private_control_property_editor_common['propertyChangeFailed'];
|
|
12
|
+
const FlexChangesEndPoints = ___sap_ux_private_control_property_editor_common['FlexChangesEndPoints'];
|
|
13
|
+
const applyChange = ___flex_change['applyChange'];
|
|
14
|
+
function assertProperties(properties, target) {
|
|
15
|
+
for (const property of properties) {
|
|
16
|
+
const value = target[property];
|
|
17
|
+
if (value === null || value === undefined) {
|
|
18
|
+
throw new Error(`Invalid change, missing ${ property } in the change file`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function assertChange(change) {
|
|
23
|
+
assertProperties([
|
|
24
|
+
'fileName',
|
|
25
|
+
'selector',
|
|
26
|
+
'content',
|
|
27
|
+
'creation'
|
|
28
|
+
], change);
|
|
29
|
+
assertProperties(['id'], change.selector);
|
|
30
|
+
assertProperties(['property'], change.content);
|
|
31
|
+
}
|
|
32
|
+
function modifyRTAErrorMessage(errorMessage, id, type) {
|
|
33
|
+
return errorMessage.replace('Error: Applying property changes failed:', '').replace(`${ type }#${ id }`, '');
|
|
34
|
+
}
|
|
35
|
+
class ChangeService {
|
|
36
|
+
savedChanges = [];
|
|
37
|
+
constructor(options, ui5, selectionService) {
|
|
38
|
+
this.options = options;
|
|
39
|
+
this.ui5 = ui5;
|
|
40
|
+
this.selectionService = selectionService;
|
|
41
|
+
}
|
|
42
|
+
async init(sendAction, subscribe) {
|
|
43
|
+
subscribe(async action => {
|
|
44
|
+
if (changeProperty.match(action)) {
|
|
45
|
+
try {
|
|
46
|
+
this.selectionService.applyControlPropertyChange(action.payload.controlId, action.payload.propertyName);
|
|
47
|
+
await applyChange(this.options, action.payload);
|
|
48
|
+
} catch (exception) {
|
|
49
|
+
let name = '';
|
|
50
|
+
const id = action.payload.controlId || '';
|
|
51
|
+
const control = this.ui5.getControlById(id);
|
|
52
|
+
if (control) {
|
|
53
|
+
name = control.getMetadata().getName();
|
|
54
|
+
}
|
|
55
|
+
const modifiedMessage = modifyRTAErrorMessage(exception?.toString(), id, name);
|
|
56
|
+
const errorMessage = modifiedMessage || `RTA Exception applying expression "${ action.payload.value }"`;
|
|
57
|
+
const propertyChangeFailedAction = propertyChangeFailed({
|
|
58
|
+
...action.payload,
|
|
59
|
+
errorMessage
|
|
60
|
+
});
|
|
61
|
+
sendAction(propertyChangeFailedAction);
|
|
62
|
+
}
|
|
63
|
+
} else if (deletePropertyChanges.match(action)) {
|
|
64
|
+
await this.deleteChange(action.payload.controlId, action.payload.propertyName, action.payload.fileName);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
const savedChangesResponse = await fetch(FlexChangesEndPoints.changes + `?_=${ Date.now() }`);
|
|
68
|
+
const savedChanges = await savedChangesResponse.json();
|
|
69
|
+
const changes = Object.keys(savedChanges ?? {}).map(key => {
|
|
70
|
+
const change = savedChanges[key];
|
|
71
|
+
try {
|
|
72
|
+
assertChange(change);
|
|
73
|
+
if ([
|
|
74
|
+
change.content.newValue,
|
|
75
|
+
change.content.newBinding
|
|
76
|
+
].every(item => item === undefined || item === null)) {
|
|
77
|
+
throw new Error('Invalid change, missing new value in the change file');
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
type: 'saved',
|
|
81
|
+
kind: 'valid',
|
|
82
|
+
fileName: change.fileName,
|
|
83
|
+
controlId: change.selector.id,
|
|
84
|
+
propertyName: change.content.property,
|
|
85
|
+
value: change.content.newValue ?? change.content.newBinding,
|
|
86
|
+
timestamp: new Date(change.creation).getTime(),
|
|
87
|
+
controlName: change.selector.type.split('.').pop()
|
|
88
|
+
};
|
|
89
|
+
} catch (error) {
|
|
90
|
+
if (change.fileName) {
|
|
91
|
+
const unknownChange = {
|
|
92
|
+
type: 'saved',
|
|
93
|
+
kind: 'unknown',
|
|
94
|
+
fileName: change.fileName
|
|
95
|
+
};
|
|
96
|
+
if (change.creation) {
|
|
97
|
+
unknownChange.timestamp = new Date(change.creation).getTime();
|
|
98
|
+
}
|
|
99
|
+
return unknownChange;
|
|
100
|
+
}
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
}).filter(change => !!change).sort((a, b) => b.timestamp - a.timestamp);
|
|
104
|
+
this.savedChanges = changes;
|
|
105
|
+
sendAction(changeStackModified({
|
|
106
|
+
saved: changes,
|
|
107
|
+
pending: []
|
|
108
|
+
}));
|
|
109
|
+
this.options.rta.attachUndoRedoStackModified(this.createOnStackChangeHandler(sendAction));
|
|
110
|
+
}
|
|
111
|
+
async deleteChange(controlId, propertyName, fileName) {
|
|
112
|
+
const filesToDelete = this.savedChanges.filter(change => fileName ? fileName === change.fileName : change.controlId === controlId && change.propertyName === propertyName).map(change => fetch(FlexChangesEndPoints.changes, {
|
|
113
|
+
method: 'DELETE',
|
|
114
|
+
headers: { 'Content-Type': 'application/json' },
|
|
115
|
+
body: JSON.stringify({ fileName: change.fileName })
|
|
116
|
+
}));
|
|
117
|
+
await Promise.all(filesToDelete).catch(error => Log.error(error));
|
|
118
|
+
}
|
|
119
|
+
createOnStackChangeHandler(sendAction) {
|
|
120
|
+
return () => {
|
|
121
|
+
const stack = this.options.rta.getCommandStack();
|
|
122
|
+
const allCommands = stack.getCommands();
|
|
123
|
+
const executedCommands = stack.getAllExecutedCommands();
|
|
124
|
+
const inactiveCommandCount = allCommands.length - executedCommands.length;
|
|
125
|
+
const activeChanges = allCommands.map((command, i) => {
|
|
126
|
+
let result;
|
|
127
|
+
try {
|
|
128
|
+
const selector = command.getProperty('selector');
|
|
129
|
+
const changeType = command.getProperty('changeType');
|
|
130
|
+
let value = '';
|
|
131
|
+
switch (changeType) {
|
|
132
|
+
case 'propertyChange':
|
|
133
|
+
value = command.getProperty('newValue');
|
|
134
|
+
break;
|
|
135
|
+
case 'propertyBindingChange':
|
|
136
|
+
value = command.getProperty('newBinding');
|
|
137
|
+
break;
|
|
138
|
+
default:
|
|
139
|
+
throw new Error(`Invalid changeType ${ changeType }`);
|
|
140
|
+
}
|
|
141
|
+
result = {
|
|
142
|
+
type: 'pending',
|
|
143
|
+
controlId: selector.id,
|
|
144
|
+
propertyName: command.getProperty('propertyName'),
|
|
145
|
+
isActive: i >= inactiveCommandCount,
|
|
146
|
+
value,
|
|
147
|
+
controlName: command.getElement().getMetadata().getName().split('.').pop() ?? ''
|
|
148
|
+
};
|
|
149
|
+
} catch (error) {
|
|
150
|
+
Log.error('Failed: ', error);
|
|
151
|
+
}
|
|
152
|
+
return result;
|
|
153
|
+
}).filter(change => !!change);
|
|
154
|
+
sendAction(changeStackModified({
|
|
155
|
+
saved: this.savedChanges,
|
|
156
|
+
pending: activeChanges
|
|
157
|
+
}));
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
var __exports = { __esModule: true };
|
|
162
|
+
__exports.ChangeService = ChangeService;
|
|
163
|
+
return __exports;
|
|
164
|
+
});
|