@sap-ux/preview-middleware 0.20.1 → 0.20.3
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 +2 -2
- package/dist/client/adp/command-executor.ts +4 -4
- package/dist/client/adp/controllers/AddFragment.controller.js +1 -1
- package/dist/client/adp/controllers/AddFragment.controller.ts +2 -2
- package/dist/client/adp/controllers/AddTableColumnFragments.controller.js +1 -1
- package/dist/client/adp/controllers/AddTableColumnFragments.controller.ts +2 -2
- package/dist/client/adp/controllers/BaseDialog.controller.js +2 -13
- package/dist/client/adp/controllers/BaseDialog.controller.ts +7 -25
- package/dist/client/adp/controllers/ControllerExtension.controller.js +73 -15
- package/dist/client/adp/controllers/ControllerExtension.controller.ts +110 -22
- package/dist/client/adp/dialog-factory.js +1 -1
- package/dist/client/adp/dialog-factory.ts +3 -1
- package/dist/client/adp/extend-controller.js +48 -0
- package/dist/client/adp/extend-controller.ts +49 -0
- package/dist/client/adp/init-dialogs.js +15 -35
- package/dist/client/adp/init-dialogs.ts +42 -20
- package/dist/client/adp/init.js +9 -1
- package/dist/client/adp/init.ts +6 -1
- package/dist/client/adp/quick-actions/common/add-controller-to-page.js +16 -2
- package/dist/client/adp/quick-actions/common/add-controller-to-page.ts +25 -3
- package/dist/client/adp/quick-actions/fe-v4/create-table-action.js +1 -1
- package/dist/client/adp/quick-actions/fe-v4/create-table-action.ts +1 -1
- package/dist/client/adp/ui/ControllerExtension.fragment.xml +14 -3
- package/dist/client/adp/utils.js +49 -8
- package/dist/client/adp/utils.ts +55 -7
- package/dist/client/cpe/connector-service.ts +1 -0
- package/dist/client/cpe/context-menu-service.js +6 -3
- package/dist/client/cpe/context-menu-service.ts +3 -1
- package/dist/client/cpe/quick-actions/quick-action-service.js +10 -3
- package/dist/client/cpe/quick-actions/quick-action-service.ts +7 -1
- package/dist/client/messagebundle.properties +5 -0
- package/package.json +6 -6
|
@@ -22,10 +22,10 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/rta/command/CommandFactory", "../ut
|
|
|
22
22
|
* @param runtimeControl Managed object
|
|
23
23
|
* @param commandName Command name
|
|
24
24
|
* @param modifiedValue Modified value/s
|
|
25
|
-
* @param designMetadata Design time metadata
|
|
26
25
|
* @param flexSettings Additional flex settings
|
|
26
|
+
* @param designMetadata Design time metadata
|
|
27
27
|
*/
|
|
28
|
-
async getCommand(runtimeControl, commandName, modifiedValue,
|
|
28
|
+
async getCommand(runtimeControl, commandName, modifiedValue, flexSettings, designMetadata) {
|
|
29
29
|
try {
|
|
30
30
|
return await CommandFactory.getCommandFor(runtimeControl, commandName, modifiedValue, designMetadata, flexSettings);
|
|
31
31
|
} catch (e) {
|
|
@@ -8,7 +8,7 @@ import type DesignTimeMetadata from 'sap/ui/dt/DesignTimeMetadata';
|
|
|
8
8
|
import type FlexCommand from 'sap/ui/rta/command/FlexCommand';
|
|
9
9
|
import { getError } from '../utils/error';
|
|
10
10
|
|
|
11
|
-
type CommandNames = 'addXML';
|
|
11
|
+
type CommandNames = 'addXML' | 'codeExt';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Class responsible for handling rta calls
|
|
@@ -26,15 +26,15 @@ export default class CommandExecutor {
|
|
|
26
26
|
* @param runtimeControl Managed object
|
|
27
27
|
* @param commandName Command name
|
|
28
28
|
* @param modifiedValue Modified value/s
|
|
29
|
-
* @param designMetadata Design time metadata
|
|
30
29
|
* @param flexSettings Additional flex settings
|
|
30
|
+
* @param designMetadata Design time metadata
|
|
31
31
|
*/
|
|
32
32
|
public async getCommand<T>(
|
|
33
33
|
runtimeControl: ManagedObject,
|
|
34
34
|
commandName: CommandNames,
|
|
35
35
|
modifiedValue: object,
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
flexSettings: FlexSettings,
|
|
37
|
+
designMetadata?: DesignTimeMetadata
|
|
38
38
|
): Promise<FlexCommand<T>> {
|
|
39
39
|
try {
|
|
40
40
|
return await CommandFactory.getCommandFor(
|
|
@@ -143,7 +143,7 @@ sap.ui.define([
|
|
|
143
143
|
const flexSettings = this.rta.getFlexSettings();
|
|
144
144
|
const overlay = OverlayRegistry.getOverlay(this.runtimeControl);
|
|
145
145
|
const designMetadata = overlay.getDesignTimeMetadata();
|
|
146
|
-
const command = await this.commandExecutor.getCommand(this.runtimeControl, 'addXML', modifiedValue,
|
|
146
|
+
const command = await this.commandExecutor.getCommand(this.runtimeControl, 'addXML', modifiedValue, flexSettings, designMetadata);
|
|
147
147
|
await this.commandExecutor.pushAndExecuteCommand(command);
|
|
148
148
|
}
|
|
149
149
|
});
|
|
@@ -243,8 +243,8 @@ export default class AddFragment extends BaseDialog<AddFragmentModel> {
|
|
|
243
243
|
this.runtimeControl,
|
|
244
244
|
'addXML',
|
|
245
245
|
modifiedValue,
|
|
246
|
-
|
|
247
|
-
|
|
246
|
+
flexSettings,
|
|
247
|
+
designMetadata
|
|
248
248
|
);
|
|
249
249
|
|
|
250
250
|
await this.commandExecutor.pushAndExecuteCommand(command);
|
|
@@ -160,7 +160,7 @@ sap.ui.define([
|
|
|
160
160
|
targetAggregation: fragment.targetAggregation === ITEMS_AGGREGATION ? CELLS_AGGREGATION : fragment.targetAggregation
|
|
161
161
|
};
|
|
162
162
|
const targetObject = fragment.targetAggregation === COLUMNS_AGGREGATION ? this.runtimeControl : this.runtimeControl.getAggregation(ITEMS_AGGREGATION)[0];
|
|
163
|
-
const command = await this.commandExecutor.getCommand(targetObject, 'addXML', modifiedValue,
|
|
163
|
+
const command = await this.commandExecutor.getCommand(targetObject, 'addXML', modifiedValue, flexSettings, designMetadata);
|
|
164
164
|
const templateName = fragment.targetAggregation === COLUMNS_AGGREGATION ? `V2_SMART_TABLE_COLUMN` : 'V2_SMART_TABLE_CELL';
|
|
165
165
|
const preparedChange = command.getPreparedChange();
|
|
166
166
|
setAdditionalChangeInfoForChangeFile(preparedChange.getDefinition().fileName, { templateName });
|
|
@@ -16,7 +16,7 @@ sap.ui.define([
|
|
|
16
16
|
return obj && obj.__esModule && typeof obj.default !== 'undefined' ? obj.default : obj;
|
|
17
17
|
}
|
|
18
18
|
const ValueState = sap_ui_core_library['ValueState'];
|
|
19
|
-
const
|
|
19
|
+
const checkForExistingChange = ___utils['checkForExistingChange'];
|
|
20
20
|
const getError = ____utils_error['getError'];
|
|
21
21
|
const getControlById = ____utils_core['getControlById'];
|
|
22
22
|
const ControlUtils = _interopRequireDefault(__ControlUtils);
|
|
@@ -118,7 +118,7 @@ sap.ui.define([
|
|
|
118
118
|
updateDialogState(ValueState.Error, 'A fragment file name cannot contain more than 64 characters.');
|
|
119
119
|
return;
|
|
120
120
|
}
|
|
121
|
-
const changeExists = this.
|
|
121
|
+
const changeExists = checkForExistingChange(this.rta, 'addXMLAtExtensionPoint', 'content.fragmentPath', `${ fragmentName }.fragment.xml`);
|
|
122
122
|
if (changeExists) {
|
|
123
123
|
updateDialogState(ValueState.Error, 'Enter a different name. The fragment name entered matches the name of an unsaved fragment.');
|
|
124
124
|
return;
|
|
@@ -126,17 +126,6 @@ sap.ui.define([
|
|
|
126
126
|
updateDialogState(ValueState.Success);
|
|
127
127
|
this.model.setProperty('/newFragmentName', fragmentName);
|
|
128
128
|
},
|
|
129
|
-
checkForExistingChange: function _checkForExistingChange(fragmentName) {
|
|
130
|
-
const allCommands = this.rta.getCommandStack().getCommands();
|
|
131
|
-
return allCommands.some(command => {
|
|
132
|
-
if (typeof command.getCommands === 'function') {
|
|
133
|
-
const addXmlCommand = command.getCommands().find(c => c?.getProperty('name') === 'addXMLAtExtensionPoint');
|
|
134
|
-
return addXmlCommand && matchesFragmentName(addXmlCommand, fragmentName);
|
|
135
|
-
} else {
|
|
136
|
-
return matchesFragmentName(command, fragmentName);
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
},
|
|
140
129
|
setEscapeHandler: function _setEscapeHandler() {
|
|
141
130
|
this.dialog.setEscapeHandler(_ref => {
|
|
142
131
|
let {resolve} = _ref;
|
|
@@ -7,10 +7,9 @@ import { ValueState } from 'sap/ui/core/library';
|
|
|
7
7
|
import Controller from 'sap/ui/core/mvc/Controller';
|
|
8
8
|
import JSONModel from 'sap/ui/model/json/JSONModel';
|
|
9
9
|
import RuntimeAuthoring from 'sap/ui/rta/RuntimeAuthoring';
|
|
10
|
-
import FlexCommand from 'sap/ui/rta/command/FlexCommand';
|
|
11
10
|
import MessageToast from 'sap/m/MessageToast';
|
|
12
11
|
import CommandExecutor from '../command-executor';
|
|
13
|
-
import {
|
|
12
|
+
import { checkForExistingChange } from '../utils';
|
|
14
13
|
import type { Fragments } from '../api-handler';
|
|
15
14
|
import { getError } from '../../utils/error';
|
|
16
15
|
import ManagedObjectMetadata from 'sap/ui/base/ManagedObjectMetadata';
|
|
@@ -168,7 +167,12 @@ export default abstract class BaseDialog<T extends BaseDialogModel = BaseDialogM
|
|
|
168
167
|
return;
|
|
169
168
|
}
|
|
170
169
|
|
|
171
|
-
const changeExists =
|
|
170
|
+
const changeExists = checkForExistingChange(
|
|
171
|
+
this.rta,
|
|
172
|
+
'addXMLAtExtensionPoint',
|
|
173
|
+
'content.fragmentPath',
|
|
174
|
+
`${fragmentName}.fragment.xml`
|
|
175
|
+
);
|
|
172
176
|
|
|
173
177
|
if (changeExists) {
|
|
174
178
|
updateDialogState(
|
|
@@ -182,28 +186,6 @@ export default abstract class BaseDialog<T extends BaseDialogModel = BaseDialogM
|
|
|
182
186
|
this.model.setProperty('/newFragmentName', fragmentName);
|
|
183
187
|
}
|
|
184
188
|
|
|
185
|
-
/**
|
|
186
|
-
* Checks for the existence of a change associated with a specific fragment name in the RTA command stack.
|
|
187
|
-
*
|
|
188
|
-
* @param {string} fragmentName - The name of the fragment to check for existing changes.
|
|
189
|
-
* @returns {Promise<boolean>} A promise that resolves to `true` if a matching change is found, otherwise `false`.
|
|
190
|
-
*/
|
|
191
|
-
checkForExistingChange(fragmentName: string): boolean {
|
|
192
|
-
const allCommands = this.rta.getCommandStack().getCommands();
|
|
193
|
-
|
|
194
|
-
return allCommands.some((command: FlexCommand) => {
|
|
195
|
-
if (typeof command.getCommands === 'function') {
|
|
196
|
-
const addXmlCommand = command
|
|
197
|
-
.getCommands()
|
|
198
|
-
.find((c: FlexCommand) => c?.getProperty('name') === 'addXMLAtExtensionPoint');
|
|
199
|
-
|
|
200
|
-
return addXmlCommand && matchesFragmentName(addXmlCommand, fragmentName);
|
|
201
|
-
} else {
|
|
202
|
-
return matchesFragmentName(command, fragmentName);
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
|
|
207
189
|
/**
|
|
208
190
|
* Sets custom function that fires when user presses escape key.
|
|
209
191
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/model/json/JSONModel", "../api-handler", "./BaseDialog.controller", "../utils"], function (MessageToast, sap_ui_core_library, JSONModel, ___api_handler, __BaseDialog, ___utils) {
|
|
3
|
+
sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/model/json/JSONModel", "../api-handler", "./BaseDialog.controller", "../../i18n", "../utils", "../../utils/version", "../command-executor", "../../utils/core"], function (MessageToast, sap_ui_core_library, JSONModel, ___api_handler, __BaseDialog, ____i18n, ___utils, ____utils_version, __CommandExecutor, ____utils_core) {
|
|
4
4
|
"use strict";
|
|
5
5
|
|
|
6
6
|
function _interopRequireDefault(obj) {
|
|
@@ -14,16 +14,25 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/model/json/J
|
|
|
14
14
|
const writeChange = ___api_handler["writeChange"];
|
|
15
15
|
const writeController = ___api_handler["writeController"];
|
|
16
16
|
const BaseDialog = _interopRequireDefault(__BaseDialog);
|
|
17
|
+
const getResourceModel = ____i18n["getResourceModel"];
|
|
18
|
+
const getTextBundle = ____i18n["getTextBundle"];
|
|
19
|
+
const notifyUser = ___utils["notifyUser"];
|
|
20
|
+
const checkForExistingChange = ___utils["checkForExistingChange"];
|
|
17
21
|
const getControllerInfo = ___utils["getControllerInfo"];
|
|
22
|
+
const getUi5Version = ____utils_version["getUi5Version"];
|
|
23
|
+
const isLowerThanMinimalUi5Version = ____utils_version["isLowerThanMinimalUi5Version"];
|
|
24
|
+
const CommandExecutor = _interopRequireDefault(__CommandExecutor);
|
|
25
|
+
const getControlById = ____utils_core["getControlById"];
|
|
18
26
|
/**
|
|
19
27
|
* @namespace open.ux.preview.client.adp.controllers
|
|
20
28
|
*/
|
|
21
29
|
const ControllerExtension = BaseDialog.extend("open.ux.preview.client.adp.controllers.ControllerExtension", {
|
|
22
|
-
constructor: function _constructor(name, overlays, rta, telemetryData) {
|
|
30
|
+
constructor: function _constructor(name, overlays, rta, data, telemetryData) {
|
|
23
31
|
BaseDialog.prototype.constructor.call(this, name, telemetryData);
|
|
24
32
|
this.rta = rta;
|
|
25
33
|
this.overlays = overlays;
|
|
26
34
|
this.model = new JSONModel();
|
|
35
|
+
this.data = data;
|
|
27
36
|
},
|
|
28
37
|
/**
|
|
29
38
|
* Setups the Dialog and the JSON Model
|
|
@@ -33,7 +42,10 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/model/json/J
|
|
|
33
42
|
setup: async function _setup(dialog) {
|
|
34
43
|
this.dialog = dialog;
|
|
35
44
|
this.setEscapeHandler();
|
|
45
|
+
const resourceModel = await getResourceModel('open.ux.preview.client');
|
|
46
|
+
this.bundle = await getTextBundle();
|
|
36
47
|
await this.buildDialogData();
|
|
48
|
+
this.dialog.setModel(resourceModel, 'i18n');
|
|
37
49
|
this.dialog.setModel(this.model);
|
|
38
50
|
this.dialog.open();
|
|
39
51
|
},
|
|
@@ -58,10 +70,15 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/model/json/J
|
|
|
58
70
|
return;
|
|
59
71
|
}
|
|
60
72
|
const fileExists = controllerList.some(f => f.controllerName === controllerName);
|
|
73
|
+
const pendingChangeExists = checkForExistingChange(this.rta, 'codeExt', 'content.codeRef', `${controllerName}.js`);
|
|
61
74
|
if (fileExists) {
|
|
62
75
|
updateDialogState(ValueState.Error, 'Enter a different name. The controller name that you entered already exists in your project.');
|
|
63
76
|
return;
|
|
64
77
|
}
|
|
78
|
+
if (pendingChangeExists) {
|
|
79
|
+
updateDialogState(ValueState.Error, 'Enter a different name. The controller name that you entered already exists as a pending change.');
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
65
82
|
const isValidName = /^[a-zA-Z_][a-zA-Z0-9_-]*$/.test(controllerName);
|
|
66
83
|
if (!isValidName) {
|
|
67
84
|
updateDialogState(ValueState.Error, 'The controller name cannot contain white spaces or special characters.');
|
|
@@ -87,7 +104,15 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/model/json/J
|
|
|
87
104
|
source.setEnabled(false);
|
|
88
105
|
const controllerName = this.model.getProperty('/newControllerName');
|
|
89
106
|
const viewId = this.model.getProperty('/viewId');
|
|
90
|
-
|
|
107
|
+
const controllerRef = {
|
|
108
|
+
codeRef: `coding/${controllerName}.js`,
|
|
109
|
+
viewId
|
|
110
|
+
};
|
|
111
|
+
if (this.data) {
|
|
112
|
+
this.data.deferred.resolve(controllerRef);
|
|
113
|
+
} else {
|
|
114
|
+
await this.createNewController(controllerName, controllerRef);
|
|
115
|
+
}
|
|
91
116
|
} else {
|
|
92
117
|
const controllerPath = this.model.getProperty('/controllerPath');
|
|
93
118
|
window.open(`vscode://file${controllerPath}`);
|
|
@@ -105,8 +130,11 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/model/json/J
|
|
|
105
130
|
viewId
|
|
106
131
|
} = getControllerInfo(overlayControl);
|
|
107
132
|
const data = await this.getExistingController(controllerName);
|
|
133
|
+
const hasPendingChangeForView = checkForExistingChange(this.rta, 'codeExt', 'selector.controllerName', controllerName);
|
|
108
134
|
if (data) {
|
|
109
|
-
if (
|
|
135
|
+
if (hasPendingChangeForView) {
|
|
136
|
+
this.updateModelForExistingPendingChange();
|
|
137
|
+
} else if (data?.controllerExists) {
|
|
110
138
|
this.updateModelForExistingController(data);
|
|
111
139
|
} else {
|
|
112
140
|
this.updateModelForNewController(viewId, data.isTsSupported);
|
|
@@ -129,11 +157,9 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/model/json/J
|
|
|
129
157
|
this.model.setProperty('/controllerExists', controllerExists);
|
|
130
158
|
this.model.setProperty('/controllerPath', controllerPath);
|
|
131
159
|
this.model.setProperty('/controllerPathFromRoot', controllerPathFromRoot);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const messageForm = content[1];
|
|
136
|
-
messageForm.setVisible(true);
|
|
160
|
+
this.model.setProperty('/inputFormVisibility', false);
|
|
161
|
+
this.model.setProperty('/pendingChangeFormVisibility', false);
|
|
162
|
+
this.model.setProperty('/existingControllerFormVisibility', true);
|
|
137
163
|
if (isRunningInBAS) {
|
|
138
164
|
this.dialog.getBeginButton().setVisible(false);
|
|
139
165
|
} else {
|
|
@@ -141,6 +167,16 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/model/json/J
|
|
|
141
167
|
}
|
|
142
168
|
this.dialog.getEndButton().setText('Close');
|
|
143
169
|
},
|
|
170
|
+
/**
|
|
171
|
+
* Updates the model properties for an existing controller in a pending change.
|
|
172
|
+
*/
|
|
173
|
+
updateModelForExistingPendingChange: function _updateModelForExistingPendingChange() {
|
|
174
|
+
this.model.setProperty('/inputFormVisibility', false);
|
|
175
|
+
this.model.setProperty('/existingControllerFormVisibility', false);
|
|
176
|
+
this.model.setProperty('/pendingChangeFormVisibility', true);
|
|
177
|
+
this.dialog.getBeginButton().setVisible(false);
|
|
178
|
+
this.dialog.getEndButton().setText('Close');
|
|
179
|
+
},
|
|
144
180
|
/**
|
|
145
181
|
* Updates the model property for a new controller.
|
|
146
182
|
*
|
|
@@ -150,6 +186,9 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/model/json/J
|
|
|
150
186
|
updateModelForNewController: function _updateModelForNewController(viewId, isTsSupported) {
|
|
151
187
|
this.model.setProperty('/viewId', viewId);
|
|
152
188
|
this.model.setProperty('/controllerExtension', isTsSupported ? '.ts' : '.js');
|
|
189
|
+
this.model.setProperty('/existingControllerFormVisibility', false);
|
|
190
|
+
this.model.setProperty('/pendingChangeFormVisibility', false);
|
|
191
|
+
this.model.setProperty('/inputFormVisibility', true);
|
|
153
192
|
},
|
|
154
193
|
/**
|
|
155
194
|
* Retrieves existing controller data if found in the project's workspace.
|
|
@@ -183,17 +222,21 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/model/json/J
|
|
|
183
222
|
* Creates a new fragment for the specified control
|
|
184
223
|
*
|
|
185
224
|
* @param controllerName Controller Name
|
|
186
|
-
* @param
|
|
225
|
+
* @param controllerRef Controller reference
|
|
187
226
|
*/
|
|
188
|
-
createNewController: async function _createNewController(controllerName,
|
|
227
|
+
createNewController: async function _createNewController(controllerName, controllerRef) {
|
|
228
|
+
const ui5Version = await getUi5Version();
|
|
229
|
+
if (!isLowerThanMinimalUi5Version(ui5Version, {
|
|
230
|
+
major: 1,
|
|
231
|
+
minor: 135
|
|
232
|
+
})) {
|
|
233
|
+
await this.createControllerCommand(controllerName, controllerRef);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
189
236
|
try {
|
|
190
237
|
await writeController({
|
|
191
238
|
controllerName
|
|
192
239
|
});
|
|
193
|
-
const controllerRef = {
|
|
194
|
-
codeRef: `coding/${controllerName}.js`,
|
|
195
|
-
viewId
|
|
196
|
-
};
|
|
197
240
|
const service = await this.rta.getService('controllerExtension');
|
|
198
241
|
const change = await service.add(controllerRef.codeRef, controllerRef.viewId);
|
|
199
242
|
change.creation = new Date().toISOString();
|
|
@@ -205,6 +248,21 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/model/json/J
|
|
|
205
248
|
await this.getControllers();
|
|
206
249
|
this.handleError(e);
|
|
207
250
|
}
|
|
251
|
+
},
|
|
252
|
+
/**
|
|
253
|
+
* Creates a controller command and executes it.
|
|
254
|
+
*
|
|
255
|
+
* @param controllerName Controller name
|
|
256
|
+
* @param controllerRef Controller reference
|
|
257
|
+
*/
|
|
258
|
+
createControllerCommand: async function _createControllerCommand(controllerName, controllerRef) {
|
|
259
|
+
const flexSettings = this.rta.getFlexSettings();
|
|
260
|
+
const commandExecutor = new CommandExecutor(this.rta);
|
|
261
|
+
const view = getControlById(controllerRef.viewId);
|
|
262
|
+
const command = await commandExecutor.getCommand(view, 'codeExt', controllerRef, flexSettings);
|
|
263
|
+
await commandExecutor.pushAndExecuteCommand(command);
|
|
264
|
+
const bundle = await getTextBundle();
|
|
265
|
+
notifyUser(bundle.getText('ADP_CREATE_CONTROLLER_EXTENSION', [controllerName]), 8000);
|
|
208
266
|
}
|
|
209
267
|
});
|
|
210
268
|
return ControllerExtension;
|
|
@@ -17,17 +17,19 @@ import JSONModel from 'sap/ui/model/json/JSONModel';
|
|
|
17
17
|
/** sap.ui.rta */
|
|
18
18
|
import type RuntimeAuthoring from 'sap/ui/rta/RuntimeAuthoring';
|
|
19
19
|
|
|
20
|
-
/** sap.ui.layout */
|
|
21
|
-
import type SimpleForm from 'sap/ui/layout/form/SimpleForm';
|
|
22
|
-
|
|
23
20
|
/** sap.ui.dt */
|
|
24
21
|
import type ElementOverlay from 'sap/ui/dt/ElementOverlay';
|
|
25
22
|
|
|
26
23
|
import type { CodeExtResponse, ControllersResponse } from '../api-handler';
|
|
27
24
|
import { getExistingController, readControllers, writeChange, writeController } from '../api-handler';
|
|
28
25
|
import BaseDialog from './BaseDialog.controller';
|
|
29
|
-
import {
|
|
26
|
+
import type { ExtendControllerData, DeferredExtendControllerData } from '../extend-controller';
|
|
30
27
|
import { QuickActionTelemetryData } from '../../cpe/quick-actions/quick-action-definition';
|
|
28
|
+
import { getResourceModel, getTextBundle, TextBundle } from '../../i18n';
|
|
29
|
+
import { notifyUser, checkForExistingChange, getControllerInfo } from '../utils';
|
|
30
|
+
import { getUi5Version, isLowerThanMinimalUi5Version } from '../../utils/version';
|
|
31
|
+
import CommandExecutor from '../command-executor';
|
|
32
|
+
import { getControlById } from '../../utils/core';
|
|
31
33
|
|
|
32
34
|
interface ControllerExtensionService {
|
|
33
35
|
add: (codeRef: string, viewId: string) => Promise<{ creation: string }>;
|
|
@@ -53,11 +55,21 @@ type ControllerModel = JSONModel & {
|
|
|
53
55
|
* @namespace open.ux.preview.client.adp.controllers
|
|
54
56
|
*/
|
|
55
57
|
export default class ControllerExtension extends BaseDialog<ControllerModel> {
|
|
56
|
-
|
|
58
|
+
public readonly data?: ExtendControllerData;
|
|
59
|
+
private bundle: TextBundle;
|
|
60
|
+
|
|
61
|
+
constructor(
|
|
62
|
+
name: string,
|
|
63
|
+
overlays: UI5Element,
|
|
64
|
+
rta: RuntimeAuthoring,
|
|
65
|
+
data?: ExtendControllerData,
|
|
66
|
+
telemetryData?: QuickActionTelemetryData
|
|
67
|
+
) {
|
|
57
68
|
super(name, telemetryData);
|
|
58
69
|
this.rta = rta;
|
|
59
70
|
this.overlays = overlays;
|
|
60
71
|
this.model = new JSONModel();
|
|
72
|
+
this.data = data;
|
|
61
73
|
}
|
|
62
74
|
|
|
63
75
|
/**
|
|
@@ -70,8 +82,12 @@ export default class ControllerExtension extends BaseDialog<ControllerModel> {
|
|
|
70
82
|
|
|
71
83
|
this.setEscapeHandler();
|
|
72
84
|
|
|
85
|
+
const resourceModel = await getResourceModel('open.ux.preview.client');
|
|
86
|
+
this.bundle = await getTextBundle();
|
|
87
|
+
|
|
73
88
|
await this.buildDialogData();
|
|
74
89
|
|
|
90
|
+
this.dialog.setModel(resourceModel, 'i18n');
|
|
75
91
|
this.dialog.setModel(this.model);
|
|
76
92
|
|
|
77
93
|
this.dialog.open();
|
|
@@ -102,6 +118,13 @@ export default class ControllerExtension extends BaseDialog<ControllerModel> {
|
|
|
102
118
|
|
|
103
119
|
const fileExists = controllerList.some((f) => f.controllerName === controllerName);
|
|
104
120
|
|
|
121
|
+
const pendingChangeExists = checkForExistingChange(
|
|
122
|
+
this.rta,
|
|
123
|
+
'codeExt',
|
|
124
|
+
'content.codeRef',
|
|
125
|
+
`${controllerName}.js`
|
|
126
|
+
);
|
|
127
|
+
|
|
105
128
|
if (fileExists) {
|
|
106
129
|
updateDialogState(
|
|
107
130
|
ValueState.Error,
|
|
@@ -110,6 +133,14 @@ export default class ControllerExtension extends BaseDialog<ControllerModel> {
|
|
|
110
133
|
return;
|
|
111
134
|
}
|
|
112
135
|
|
|
136
|
+
if (pendingChangeExists) {
|
|
137
|
+
updateDialogState(
|
|
138
|
+
ValueState.Error,
|
|
139
|
+
'Enter a different name. The controller name that you entered already exists as a pending change.'
|
|
140
|
+
);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
113
144
|
const isValidName = /^[a-zA-Z_][a-zA-Z0-9_-]*$/.test(controllerName);
|
|
114
145
|
|
|
115
146
|
if (!isValidName) {
|
|
@@ -147,7 +178,16 @@ export default class ControllerExtension extends BaseDialog<ControllerModel> {
|
|
|
147
178
|
const controllerName = this.model.getProperty('/newControllerName');
|
|
148
179
|
const viewId = this.model.getProperty('/viewId');
|
|
149
180
|
|
|
150
|
-
|
|
181
|
+
const controllerRef = {
|
|
182
|
+
codeRef: `coding/${controllerName}.js`,
|
|
183
|
+
viewId
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
if (this.data) {
|
|
187
|
+
this.data.deferred.resolve(controllerRef);
|
|
188
|
+
} else {
|
|
189
|
+
await this.createNewController(controllerName, controllerRef);
|
|
190
|
+
}
|
|
151
191
|
} else {
|
|
152
192
|
const controllerPath = this.model.getProperty('/controllerPath');
|
|
153
193
|
window.open(`vscode://file${controllerPath}`);
|
|
@@ -166,8 +206,17 @@ export default class ControllerExtension extends BaseDialog<ControllerModel> {
|
|
|
166
206
|
const { controllerName, viewId } = getControllerInfo(overlayControl);
|
|
167
207
|
const data = await this.getExistingController(controllerName);
|
|
168
208
|
|
|
209
|
+
const hasPendingChangeForView = checkForExistingChange(
|
|
210
|
+
this.rta,
|
|
211
|
+
'codeExt',
|
|
212
|
+
'selector.controllerName',
|
|
213
|
+
controllerName
|
|
214
|
+
);
|
|
215
|
+
|
|
169
216
|
if (data) {
|
|
170
|
-
if (
|
|
217
|
+
if (hasPendingChangeForView) {
|
|
218
|
+
this.updateModelForExistingPendingChange();
|
|
219
|
+
} else if (data?.controllerExists) {
|
|
171
220
|
this.updateModelForExistingController(data);
|
|
172
221
|
} else {
|
|
173
222
|
this.updateModelForNewController(viewId, data.isTsSupported);
|
|
@@ -187,14 +236,9 @@ export default class ControllerExtension extends BaseDialog<ControllerModel> {
|
|
|
187
236
|
this.model.setProperty('/controllerExists', controllerExists);
|
|
188
237
|
this.model.setProperty('/controllerPath', controllerPath);
|
|
189
238
|
this.model.setProperty('/controllerPathFromRoot', controllerPathFromRoot);
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
const form = content[0] as SimpleForm;
|
|
194
|
-
form.setVisible(false);
|
|
195
|
-
|
|
196
|
-
const messageForm = content[1] as SimpleForm;
|
|
197
|
-
messageForm.setVisible(true);
|
|
239
|
+
this.model.setProperty('/inputFormVisibility', false);
|
|
240
|
+
this.model.setProperty('/pendingChangeFormVisibility', false);
|
|
241
|
+
this.model.setProperty('/existingControllerFormVisibility', true);
|
|
198
242
|
|
|
199
243
|
if (isRunningInBAS) {
|
|
200
244
|
this.dialog.getBeginButton().setVisible(false);
|
|
@@ -204,6 +248,18 @@ export default class ControllerExtension extends BaseDialog<ControllerModel> {
|
|
|
204
248
|
this.dialog.getEndButton().setText('Close');
|
|
205
249
|
}
|
|
206
250
|
|
|
251
|
+
/**
|
|
252
|
+
* Updates the model properties for an existing controller in a pending change.
|
|
253
|
+
*/
|
|
254
|
+
private updateModelForExistingPendingChange(): void {
|
|
255
|
+
this.model.setProperty('/inputFormVisibility', false);
|
|
256
|
+
this.model.setProperty('/existingControllerFormVisibility', false);
|
|
257
|
+
this.model.setProperty('/pendingChangeFormVisibility', true);
|
|
258
|
+
|
|
259
|
+
this.dialog.getBeginButton().setVisible(false);
|
|
260
|
+
this.dialog.getEndButton().setText('Close');
|
|
261
|
+
}
|
|
262
|
+
|
|
207
263
|
/**
|
|
208
264
|
* Updates the model property for a new controller.
|
|
209
265
|
*
|
|
@@ -213,6 +269,9 @@ export default class ControllerExtension extends BaseDialog<ControllerModel> {
|
|
|
213
269
|
private updateModelForNewController(viewId: string, isTsSupported: boolean): void {
|
|
214
270
|
this.model.setProperty('/viewId', viewId);
|
|
215
271
|
this.model.setProperty('/controllerExtension', isTsSupported ? '.ts' : '.js');
|
|
272
|
+
this.model.setProperty('/existingControllerFormVisibility', false);
|
|
273
|
+
this.model.setProperty('/pendingChangeFormVisibility', false);
|
|
274
|
+
this.model.setProperty('/inputFormVisibility', true);
|
|
216
275
|
}
|
|
217
276
|
|
|
218
277
|
/**
|
|
@@ -248,17 +307,20 @@ export default class ControllerExtension extends BaseDialog<ControllerModel> {
|
|
|
248
307
|
* Creates a new fragment for the specified control
|
|
249
308
|
*
|
|
250
309
|
* @param controllerName Controller Name
|
|
251
|
-
* @param
|
|
310
|
+
* @param controllerRef Controller reference
|
|
252
311
|
*/
|
|
253
|
-
private async createNewController(
|
|
312
|
+
private async createNewController(
|
|
313
|
+
controllerName: string,
|
|
314
|
+
controllerRef: DeferredExtendControllerData
|
|
315
|
+
): Promise<void> {
|
|
316
|
+
const ui5Version = await getUi5Version();
|
|
317
|
+
if (!isLowerThanMinimalUi5Version(ui5Version, { major: 1, minor: 135 })) {
|
|
318
|
+
await this.createControllerCommand(controllerName, controllerRef);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
254
321
|
try {
|
|
255
322
|
await writeController({ controllerName });
|
|
256
323
|
|
|
257
|
-
const controllerRef = {
|
|
258
|
-
codeRef: `coding/${controllerName}.js`,
|
|
259
|
-
viewId
|
|
260
|
-
};
|
|
261
|
-
|
|
262
324
|
const service = await this.rta.getService<ControllerExtensionService>('controllerExtension');
|
|
263
325
|
|
|
264
326
|
const change = await service.add(controllerRef.codeRef, controllerRef.viewId);
|
|
@@ -273,4 +335,30 @@ export default class ControllerExtension extends BaseDialog<ControllerModel> {
|
|
|
273
335
|
this.handleError(e);
|
|
274
336
|
}
|
|
275
337
|
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Creates a controller command and executes it.
|
|
341
|
+
*
|
|
342
|
+
* @param controllerName Controller name
|
|
343
|
+
* @param controllerRef Controller reference
|
|
344
|
+
*/
|
|
345
|
+
private async createControllerCommand(
|
|
346
|
+
controllerName: string,
|
|
347
|
+
controllerRef: DeferredExtendControllerData
|
|
348
|
+
): Promise<void> {
|
|
349
|
+
const flexSettings = this.rta.getFlexSettings();
|
|
350
|
+
const commandExecutor = new CommandExecutor(this.rta);
|
|
351
|
+
const view = getControlById(controllerRef.viewId) as UI5Element;
|
|
352
|
+
const command = await commandExecutor.getCommand<DeferredExtendControllerData>(
|
|
353
|
+
view,
|
|
354
|
+
'codeExt',
|
|
355
|
+
controllerRef,
|
|
356
|
+
flexSettings
|
|
357
|
+
);
|
|
358
|
+
|
|
359
|
+
await commandExecutor.pushAndExecuteCommand(command);
|
|
360
|
+
|
|
361
|
+
const bundle = await getTextBundle();
|
|
362
|
+
notifyUser(bundle.getText('ADP_CREATE_CONTROLLER_EXTENSION', [controllerName]), 8000);
|
|
363
|
+
}
|
|
276
364
|
}
|
|
@@ -73,7 +73,7 @@ sap.ui.define(["sap/ui/core/Fragment", "../i18n", "./controllers/AddFragment.con
|
|
|
73
73
|
}, telemetryData);
|
|
74
74
|
break;
|
|
75
75
|
case DialogNames.CONTROLLER_EXTENSION:
|
|
76
|
-
controller = new ControllerExtension(`open.ux.preview.client.adp.controllers.${dialogName}`, overlay, rta, telemetryData);
|
|
76
|
+
controller = new ControllerExtension(`open.ux.preview.client.adp.controllers.${dialogName}`, overlay, rta, data, telemetryData);
|
|
77
77
|
break;
|
|
78
78
|
case DialogNames.ADD_FRAGMENT_AT_EXTENSION_POINT:
|
|
79
79
|
controller = new ExtensionPoint(`open.ux.preview.client.adp.controllers.${dialogName}`, overlay, rta, data);
|
|
@@ -12,6 +12,7 @@ import ExtensionPoint from './controllers/ExtensionPoint.controller';
|
|
|
12
12
|
|
|
13
13
|
import type { ExtensionPointData } from './extension-point';
|
|
14
14
|
import { AddFragmentData } from './add-fragment';
|
|
15
|
+
import { ExtendControllerData } from './extend-controller';
|
|
15
16
|
import FileExistsDialog, { FileExistsDialogOptions } from './controllers/FileExistsDialog.controller';
|
|
16
17
|
import AddSubpage, { AddSubpageOptions } from './controllers/AddSubpage.controller';
|
|
17
18
|
import { QuickActionTelemetryData } from '../cpe/quick-actions/quick-action-definition';
|
|
@@ -33,7 +34,7 @@ type Controller =
|
|
|
33
34
|
| FileExistsDialog
|
|
34
35
|
| AddSubpage;
|
|
35
36
|
|
|
36
|
-
type DialogData = ExtensionPointData | AddFragmentData;
|
|
37
|
+
type DialogData = ExtensionPointData | AddFragmentData | ExtendControllerData;
|
|
37
38
|
|
|
38
39
|
export const OPEN_DIALOG_STATUS_CHANGED = 'OPEN_DIALOG_STATUS_CHANGED';
|
|
39
40
|
|
|
@@ -106,6 +107,7 @@ export class DialogFactory {
|
|
|
106
107
|
`open.ux.preview.client.adp.controllers.${dialogName}`,
|
|
107
108
|
overlay,
|
|
108
109
|
rta,
|
|
110
|
+
(data as ExtendControllerData),
|
|
109
111
|
telemetryData
|
|
110
112
|
);
|
|
111
113
|
break;
|