@sapui5/sap.fe.test 1.100.0 → 1.102.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -3
- package/src/sap/fe/test/.library +1 -1
- package/src/sap/fe/test/BaseArrangements.js +65 -18
- package/src/sap/fe/test/CollaborationClient.js +77 -0
- package/src/sap/fe/test/CollaborationClient.ts +105 -0
- package/src/sap/fe/test/FeMocks.js +3 -3
- package/src/sap/fe/test/FeMocks.ts +10 -6
- package/src/sap/fe/test/FlexibleColumnLayout.js +148 -141
- package/src/sap/fe/test/JestTemplatingHelper.js +31 -10
- package/src/sap/fe/test/JestTemplatingHelper.ts +62 -48
- package/src/sap/fe/test/ListReport.js +72 -77
- package/src/sap/fe/test/LocationUtil.js +12 -16
- package/src/sap/fe/test/ObjectPage.js +116 -124
- package/src/sap/fe/test/Shell.js +94 -34
- package/src/sap/fe/test/TemplatePage.js +49 -27
- package/src/sap/fe/test/UI5MockHelper.js +100 -20
- package/src/sap/fe/test/UI5MockHelper.ts +79 -14
- package/src/sap/fe/test/api/APIHelper.js +26 -15
- package/src/sap/fe/test/api/CollaborationAPI.js +215 -0
- package/src/sap/fe/test/api/CollaborationAPI.ts +240 -0
- package/src/sap/fe/test/api/DialogActions.js +3 -1
- package/src/sap/fe/test/api/DialogMessageActions.js +78 -64
- package/src/sap/fe/test/api/HeaderActions.js +229 -226
- package/src/sap/fe/test/api/HeaderAssertions.js +76 -41
- package/src/sap/fe/test/api/TableAPI.js +30 -34
- package/src/sap/fe/test/api/TableActions.js +58 -70
- package/src/sap/fe/test/api/TableAssertions.js +51 -46
- package/src/sap/fe/test/builder/MacroFieldBuilder.js +161 -153
- package/src/sap/fe/test/builder/MdcTableBuilder.js +247 -191
- package/src/sap/fe/test/library.js +26 -35
- package/src/sap/fe/test/library.ts +28 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* SAP UI development toolkit for HTML5 (SAPUI5)
|
|
3
|
+
* (c) Copyright 2009-2021 SAP SE. All rights reserved
|
|
4
|
+
*/
|
|
5
|
+
sap.ui.define(["sap/base/Log", "sap/fe/core/controllerextensions/collaboration/ActivityBase", "sap/fe/core/controllerextensions/collaboration/CollaborationCommon", "sap/fe/core/controllerextensions/editFlow/draft", "sap/ui/model/json/JSONModel"], function (Log, ActivityBase, CollaborationCommon, draft, JSONModel) {
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
var Activity = CollaborationCommon.Activity;
|
|
9
|
+
var initializeCollaboration = ActivityBase.initializeCollaboration;
|
|
10
|
+
var endCollaboration = ActivityBase.endCollaboration;
|
|
11
|
+
var broadcastCollaborationMessage = ActivityBase.broadcastCollaborationMessage;
|
|
12
|
+
|
|
13
|
+
var CollaborationAPI = {
|
|
14
|
+
_lastReceivedMessage: undefined,
|
|
15
|
+
_rootPath: "",
|
|
16
|
+
_oModel: undefined,
|
|
17
|
+
_lockedPropertyPath: "",
|
|
18
|
+
_internalModel: undefined,
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Open an existing collaborative draft with a new user, and creates a 'ghost client' for this user.
|
|
22
|
+
*
|
|
23
|
+
* @param oContext The context of the collaborative draft
|
|
24
|
+
* @param userID The ID of the user
|
|
25
|
+
* @param userName The name of the user
|
|
26
|
+
*/
|
|
27
|
+
enterDraft: function (oContext, userID, userName) {
|
|
28
|
+
var webSocketBaseURL = oContext.getModel().getMetaModel().getObject("/@com.sap.vocabularies.Common.v1.WebSocketBaseURL");
|
|
29
|
+
|
|
30
|
+
if (!webSocketBaseURL) {
|
|
31
|
+
Log.error("Cannot find WebSocketBaseURL annotation");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
var sDraftUUID = oContext.getProperty("DraftAdministrativeData/DraftUUID");
|
|
36
|
+
this._internalModel = new JSONModel({});
|
|
37
|
+
initializeCollaboration({
|
|
38
|
+
id: userID,
|
|
39
|
+
name: userName,
|
|
40
|
+
initialName: userName
|
|
41
|
+
}, webSocketBaseURL, sDraftUUID, this._internalModel, this._onMessageReceived.bind(this), true);
|
|
42
|
+
this._rootPath = oContext.getPath();
|
|
43
|
+
this._oModel = oContext.getModel();
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Checks if the ghost client has revieved a given message.
|
|
48
|
+
*
|
|
49
|
+
* @param message The message content to be looked for
|
|
50
|
+
* @returns True if the last recieved message matches the content
|
|
51
|
+
*/
|
|
52
|
+
checkReceived: function (message) {
|
|
53
|
+
if (!this._lastReceivedMessage) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
var found = (!message.userID || message.userID === this._lastReceivedMessage.userID) && (!message.userAction || message.userAction === this._lastReceivedMessage.userAction) && (!message.clientContent || message.clientContent === this._lastReceivedMessage.clientContent);
|
|
58
|
+
this._lastReceivedMessage = undefined; // reset history to avoid finding the same message twice
|
|
59
|
+
|
|
60
|
+
return found;
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Closes the ghost client and removes the user from the collaborative draft.
|
|
65
|
+
*/
|
|
66
|
+
leaveDraft: function () {
|
|
67
|
+
if (this._internalModel) {
|
|
68
|
+
endCollaboration(this._internalModel);
|
|
69
|
+
|
|
70
|
+
this._internalModel.destroy();
|
|
71
|
+
|
|
72
|
+
this._internalModel = undefined;
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Simulates that the user starts typing in an input (live change).
|
|
78
|
+
*
|
|
79
|
+
* @param sPropertyPath The path of the property being modified
|
|
80
|
+
*/
|
|
81
|
+
startLiveChange: function (sPropertyPath) {
|
|
82
|
+
if (this._internalModel) {
|
|
83
|
+
if (this._lockedPropertyPath) {
|
|
84
|
+
// Unlock previous property path
|
|
85
|
+
this.undoChange();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
this._lockedPropertyPath = sPropertyPath;
|
|
89
|
+
broadcastCollaborationMessage(Activity.LiveChange, this._rootPath + "/" + sPropertyPath, this._internalModel);
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Simulates that the user has modified a property.
|
|
95
|
+
*
|
|
96
|
+
* @param sPropertyPath The path of the property being modified
|
|
97
|
+
* @param value The new value of the property being modified
|
|
98
|
+
*/
|
|
99
|
+
updatePropertyValue: function (sPropertyPath, value) {
|
|
100
|
+
var _this = this;
|
|
101
|
+
|
|
102
|
+
if (this._internalModel) {
|
|
103
|
+
if (this._lockedPropertyPath !== sPropertyPath) {
|
|
104
|
+
this.startLiveChange(sPropertyPath);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
var oContextBinding = this._oModel.bindContext(this._rootPath, undefined, {
|
|
108
|
+
$$patchWithoutSideEffects: true,
|
|
109
|
+
$$groupId: "$auto",
|
|
110
|
+
$$updateGroupId: "$auto"
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
var oPropertyBinding = this._oModel.bindProperty(sPropertyPath, oContextBinding.getBoundContext());
|
|
114
|
+
|
|
115
|
+
oPropertyBinding.requestValue().then(function () {
|
|
116
|
+
oPropertyBinding.setValue(value);
|
|
117
|
+
oContextBinding.attachEventOnce("patchCompleted", function () {
|
|
118
|
+
broadcastCollaborationMessage(Activity.Change, _this._rootPath + "/" + sPropertyPath, _this._internalModel);
|
|
119
|
+
_this._lockedPropertyPath = "";
|
|
120
|
+
});
|
|
121
|
+
}).catch(function (err) {
|
|
122
|
+
Log.error(err);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Simulates that the user did an 'undo' (to be called after startLiveChange).
|
|
129
|
+
*/
|
|
130
|
+
undoChange: function () {
|
|
131
|
+
if (this._lockedPropertyPath) {
|
|
132
|
+
broadcastCollaborationMessage(Activity.Undo, this._rootPath + "/" + this._lockedPropertyPath, this._internalModel);
|
|
133
|
+
this._lockedPropertyPath = "";
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Simulates that the user has discarded the draft.
|
|
139
|
+
*/
|
|
140
|
+
discardDraft: function () {
|
|
141
|
+
var _this2 = this;
|
|
142
|
+
|
|
143
|
+
if (this._internalModel) {
|
|
144
|
+
var draftContext = this._getDraftContext();
|
|
145
|
+
|
|
146
|
+
draftContext.requestProperty("IsActiveEntity").then(function () {
|
|
147
|
+
draft.deleteDraft(draftContext);
|
|
148
|
+
}).then(function () {
|
|
149
|
+
broadcastCollaborationMessage(Activity.Discard, _this2._rootPath.replace("IsActiveEntity=false", "IsActiveEntity=true"), _this2._internalModel);
|
|
150
|
+
|
|
151
|
+
_this2._internalModel.destroy();
|
|
152
|
+
|
|
153
|
+
_this2._internalModel = undefined;
|
|
154
|
+
}).catch(function (err) {
|
|
155
|
+
Log.error(err);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Simulates that the user has deleted the draft.
|
|
162
|
+
*/
|
|
163
|
+
deleteDraft: function () {
|
|
164
|
+
var _this3 = this;
|
|
165
|
+
|
|
166
|
+
if (this._internalModel) {
|
|
167
|
+
var draftContext = this._getDraftContext();
|
|
168
|
+
|
|
169
|
+
var activeContext;
|
|
170
|
+
draftContext.requestProperty("IsActiveEntity").then(function () {
|
|
171
|
+
return draftContext.getModel().bindContext(_this3._rootPath + "/SiblingEntity").getBoundContext();
|
|
172
|
+
}).then(function (context) {
|
|
173
|
+
activeContext = context;
|
|
174
|
+
return context.requestCanonicalPath();
|
|
175
|
+
}).then(function () {
|
|
176
|
+
return draft.deleteDraft(draftContext);
|
|
177
|
+
}).then(function () {
|
|
178
|
+
activeContext.delete();
|
|
179
|
+
broadcastCollaborationMessage(Activity.Delete, _this3._rootPath, _this3._internalModel);
|
|
180
|
+
|
|
181
|
+
_this3._internalModel.destroy();
|
|
182
|
+
|
|
183
|
+
_this3._internalModel = undefined;
|
|
184
|
+
}).catch(function (err) {
|
|
185
|
+
Log.error(err);
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
// /////////////////////////////
|
|
190
|
+
// Private methods
|
|
191
|
+
_getDraftContext: function () {
|
|
192
|
+
return this._oModel.bindContext(this._rootPath, undefined, {
|
|
193
|
+
$$patchWithoutSideEffects: true,
|
|
194
|
+
$$groupId: "$auto",
|
|
195
|
+
$$updateGroupId: "$auto"
|
|
196
|
+
}).getBoundContext();
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Callback of the ghost client when receiving a message on the web socket.
|
|
201
|
+
*
|
|
202
|
+
* @param oMessage The message
|
|
203
|
+
*/
|
|
204
|
+
_onMessageReceived: function (oMessage) {
|
|
205
|
+
oMessage.userAction = oMessage.userAction || oMessage.clientAction;
|
|
206
|
+
this._lastReceivedMessage = oMessage;
|
|
207
|
+
|
|
208
|
+
if (oMessage.userAction === Activity.Join) {
|
|
209
|
+
broadcastCollaborationMessage(Activity.JoinEcho, this._lockedPropertyPath ? this._rootPath + "/" + this._lockedPropertyPath : undefined, this._internalModel);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
return CollaborationAPI;
|
|
214
|
+
}, false);
|
|
215
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkNvbGxhYm9yYXRpb25BUEkudHMiXSwibmFtZXMiOlsiQ29sbGFib3JhdGlvbkFQSSIsIl9sYXN0UmVjZWl2ZWRNZXNzYWdlIiwidW5kZWZpbmVkIiwiX3Jvb3RQYXRoIiwiX29Nb2RlbCIsIl9sb2NrZWRQcm9wZXJ0eVBhdGgiLCJfaW50ZXJuYWxNb2RlbCIsImVudGVyRHJhZnQiLCJvQ29udGV4dCIsInVzZXJJRCIsInVzZXJOYW1lIiwid2ViU29ja2V0QmFzZVVSTCIsImdldE1vZGVsIiwiZ2V0TWV0YU1vZGVsIiwiZ2V0T2JqZWN0IiwiTG9nIiwiZXJyb3IiLCJzRHJhZnRVVUlEIiwiZ2V0UHJvcGVydHkiLCJKU09OTW9kZWwiLCJpbml0aWFsaXplQ29sbGFib3JhdGlvbiIsImlkIiwibmFtZSIsImluaXRpYWxOYW1lIiwiX29uTWVzc2FnZVJlY2VpdmVkIiwiYmluZCIsImdldFBhdGgiLCJjaGVja1JlY2VpdmVkIiwibWVzc2FnZSIsImZvdW5kIiwidXNlckFjdGlvbiIsImNsaWVudENvbnRlbnQiLCJsZWF2ZURyYWZ0IiwiZW5kQ29sbGFib3JhdGlvbiIsImRlc3Ryb3kiLCJzdGFydExpdmVDaGFuZ2UiLCJzUHJvcGVydHlQYXRoIiwidW5kb0NoYW5nZSIsImJyb2FkY2FzdENvbGxhYm9yYXRpb25NZXNzYWdlIiwiQWN0aXZpdHkiLCJMaXZlQ2hhbmdlIiwidXBkYXRlUHJvcGVydHlWYWx1ZSIsInZhbHVlIiwib0NvbnRleHRCaW5kaW5nIiwiYmluZENvbnRleHQiLCIkJHBhdGNoV2l0aG91dFNpZGVFZmZlY3RzIiwiJCRncm91cElkIiwiJCR1cGRhdGVHcm91cElkIiwib1Byb3BlcnR5QmluZGluZyIsImJpbmRQcm9wZXJ0eSIsImdldEJvdW5kQ29udGV4dCIsInJlcXVlc3RWYWx1ZSIsInRoZW4iLCJzZXRWYWx1ZSIsImF0dGFjaEV2ZW50T25jZSIsIkNoYW5nZSIsImNhdGNoIiwiZXJyIiwiVW5kbyIsImRpc2NhcmREcmFmdCIsImRyYWZ0Q29udGV4dCIsIl9nZXREcmFmdENvbnRleHQiLCJyZXF1ZXN0UHJvcGVydHkiLCJkcmFmdCIsImRlbGV0ZURyYWZ0IiwiRGlzY2FyZCIsInJlcGxhY2UiLCJhY3RpdmVDb250ZXh0IiwiY29udGV4dCIsInJlcXVlc3RDYW5vbmljYWxQYXRoIiwiZGVsZXRlIiwiRGVsZXRlIiwib01lc3NhZ2UiLCJjbGllbnRBY3Rpb24iLCJKb2luIiwiSm9pbkVjaG8iXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7Ozs7Ozs7OztBQVVBLE1BQU1BLGdCQUFnQixHQUFHO0FBQ3hCQyxJQUFBQSxvQkFBb0IsRUFBRUMsU0FERTtBQUV4QkMsSUFBQUEsU0FBUyxFQUFFLEVBRmE7QUFHeEJDLElBQUFBLE9BQU8sRUFBRUYsU0FIZTtBQUl4QkcsSUFBQUEsbUJBQW1CLEVBQUUsRUFKRztBQUt4QkMsSUFBQUEsY0FBYyxFQUFFSixTQUxROztBQU94QjtBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNDSyxJQUFBQSxVQUFVLEVBQUUsVUFBVUMsUUFBVixFQUE2QkMsTUFBN0IsRUFBNkNDLFFBQTdDLEVBQStEO0FBQzFFLFVBQU1DLGdCQUF3QixHQUFHSCxRQUFRLENBQUNJLFFBQVQsR0FBb0JDLFlBQXBCLEdBQW1DQyxTQUFuQyxDQUE2QyxtREFBN0MsQ0FBakM7O0FBRUEsVUFBSSxDQUFDSCxnQkFBTCxFQUF1QjtBQUN0QkksUUFBQUEsR0FBRyxDQUFDQyxLQUFKLENBQVUseUNBQVY7QUFDQTtBQUNBOztBQUVELFVBQU1DLFVBQWtCLEdBQUdULFFBQVEsQ0FBQ1UsV0FBVCxDQUFxQixtQ0FBckIsQ0FBM0I7QUFDQSxXQUFLWixjQUFMLEdBQXNCLElBQUlhLFNBQUosQ0FBYyxFQUFkLENBQXRCO0FBRUFDLE1BQUFBLHVCQUF1QixDQUN0QjtBQUNDQyxRQUFBQSxFQUFFLEVBQUVaLE1BREw7QUFFQ2EsUUFBQUEsSUFBSSxFQUFFWixRQUZQO0FBR0NhLFFBQUFBLFdBQVcsRUFBRWI7QUFIZCxPQURzQixFQU10QkMs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b2cgZnJvbSBcInNhcC9iYXNlL0xvZ1wiO1xuaW1wb3J0IHtcblx0YnJvYWRjYXN0Q29sbGFib3JhdGlvbk1lc3NhZ2UsXG5cdGVuZENvbGxhYm9yYXRpb24sXG5cdGluaXRpYWxpemVDb2xsYWJvcmF0aW9uXG59IGZyb20gXCJzYXAvZmUvY29yZS9jb250cm9sbGVyZXh0ZW5zaW9ucy9jb2xsYWJvcmF0aW9uL0FjdGl2aXR5QmFzZVwiO1xuaW1wb3J0IHsgQWN0aXZpdHksIE1lc3NhZ2UgfSBmcm9tIFwic2FwL2ZlL2NvcmUvY29udHJvbGxlcmV4dGVuc2lvbnMvY29sbGFib3JhdGlvbi9Db2xsYWJvcmF0aW9uQ29tbW9uXCI7XG5pbXBvcnQgZHJhZnQgZnJvbSBcInNhcC9mZS9jb3JlL2NvbnRyb2xsZXJleHRlbnNpb25zL2VkaXRGbG93L2RyYWZ0XCI7XG5pbXBvcnQgQ29udGV4dCBmcm9tIFwic2FwL3VpL21vZGVsL0NvbnRleHRcIjtcbmltcG9ydCBKU09OTW9kZWwgZnJvbSBcInNhcC91aS9tb2RlbC9qc29uL0pTT05Nb2RlbFwiO1xuaW1wb3J0IE9EYXRhTW9kZWwgZnJvbSBcInNhcC91aS9tb2RlbC9vZGF0YS92NC9PRGF0YU1vZGVsXCI7XG5cbmNvbnN0IENvbGxhYm9yYXRpb25BUEkgPSB7XG5cdF9sYXN0UmVjZWl2ZWRNZXNzYWdlOiB1bmRlZmluZWQgYXMgTWVzc2FnZSB8IHVuZGVmaW5lZCxcblx0X3Jvb3RQYXRoOiBcIlwiLFxuXHRfb01vZGVsOiB1bmRlZmluZWQgYXMgT0RhdGFNb2RlbCB8IHVuZGVmaW5lZCxcblx0X2xvY2tlZFByb3BlcnR5UGF0aDogXCJcIixcblx0X2ludGVybmFsTW9kZWw6IHVuZGVmaW5lZCBhcyBKU09OTW9kZWwgfCB1bmRlZmluZWQsXG5cblx0LyoqXG5cdCAqIE9wZW4gYW4gZXhpc3RpbmcgY29sbGFib3JhdGl2ZSBkcmFmdCB3aXRoIGEgbmV3IHVzZXIsIGFuZCBjcmVhdGVzIGEgJ2dob3N0IGNsaWVudCcgZm9yIHRoaXMgdXNlci5cblx0ICpcblx0ICogQHBhcmFtIG9Db250ZXh0IFRoZSBjb250ZXh0IG9mIHRoZSBjb2xsYWJvcmF0aXZlIGRyYWZ0XG5cdCAqIEBwYXJhbSB1c2VySUQgVGhlIElEIG9mIHRoZSB1c2VyXG5cdCAqIEBwYXJhbSB1c2VyTmFtZSBUaGUgbmFtZSBvZiB0aGUgdXNlclxuXHQgKi9cblx0ZW50ZXJEcmFmdDogZnVuY3Rpb24gKG9Db250ZXh0OiBDb250ZXh0LCB1c2VySUQ6IHN0cmluZywgdXNlck5hbWU6IHN0cmluZykge1xuXHRcdGNvbnN0IHdlYlNvY2tldEJhc2VVUkw6IHN0cmluZyA9IG9Db250ZXh0LmdldE1vZGVsKCkuZ2V0TWV0YU1vZGVsKCkuZ2V0T2JqZWN0KFwiL0Bjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuV2ViU29ja2V0QmFzZVVSTFwiKTtcblxuXHRcdGlmICghd2ViU29ja2V0QmFzZVVSTCkge1xuXHRcdFx0TG9nLmVycm9yKFwiQ2Fubm90IGZpbmQgV2ViU29ja2V0QmFzZVVSTCBhbm5vdGF0aW9uXCIpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IHNEcmFmdFVVSUQ6IHN0cmluZyA9IG9Db250ZXh0LmdldFByb3BlcnR5KFwiRHJhZnRBZG1pbmlzdHJhdGl2ZURhdGEvRHJhZnRVVUlEXCIpO1xuXHRcdHRoaXMuX2ludGVybmFsTW9kZWwgPSBuZXcgSlNPTk1vZGVsKHt9KTtcblxuXHRcdGluaXRpYWxpemVDb2xsYWJvcmF0aW9uKFxuXHRcdFx0e1xuXHRcdFx0XHRpZDogdXNlcklELFxuXHRcdFx0XHRuYW1lOiB1c2VyTmFtZSxcblx0XHRcdFx0aW5pdGlhbE5hbWU6IHVzZXJOYW1lXG5cdFx0XHR9LFxuXHRcdFx0d2ViU29ja2V0QmFzZVVSTCxcblx0XHRcdHNEcmFmdFVVSUQsXG5cdFx0XHR0aGlzLl9pbnRlcm5hbE1vZGVsLFxuXHRcdFx0dGhpcy5fb25NZXNzYWdlUmVjZWl2ZWQuYmluZCh0aGlzKSxcblx0XHRcdHRydWVcblx0XHQpO1xuXG5cdFx0dGhpcy5fcm9vdFBhdGggPSBvQ29udGV4dC5nZXRQYXRoKCk7XG5cdFx0dGhpcy5fb01vZGVsID0gb0NvbnRleHQuZ2V0TW9kZWwoKSBhcyBPRGF0YU1vZGVsO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgdGhlIGdob3N0IGNsaWVudCBoYXMgcmV2aWV2ZWQgYSBnaXZlbiBtZXNzYWdlLlxuXHQgKlxuXHQgKiBAcGFyYW0gbWVzc2FnZSBUaGUgbWVzc2FnZSBjb250ZW50IHRvIGJlIGxvb2tlZCBmb3Jcblx0ICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgbGFzdCByZWNpZXZlZCBtZXNzYWdlIG1hdGNoZXMgdGhlIGNvbnRlbnRcblx0ICovXG5cdGNoZWNrUmVjZWl2ZWQ6IGZ1bmN0aW9uIChtZXNzYWdlOiBQYXJ0aWFsPE1lc3NhZ2U+KTogYm9vbGVhbiB7XG5cdFx0aWYgKCF0aGlzLl9sYXN0UmVjZWl2ZWRNZXNzYWdlKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Y29uc3QgZm91bmQgPVxuXHRcdFx0KCFtZXNzYWdlLnVzZXJJRCB8fCBtZXNzYWdlLnVzZXJJRCA9PT0gdGhpcy5fbGFzdFJlY2VpdmVkTWVzc2FnZS51c2VySUQpICYmXG5cdFx0XHQoIW1lc3NhZ2UudXNlckFjdGlvbiB8fCBtZXNzYWdlLnVzZXJBY3Rpb24gPT09IHRoaXMuX2xhc3RSZWNlaXZlZE1lc3NhZ2UudXNlckFjdGlvbikgJiZcblx0XHRcdCghbWVzc2FnZS5jbGllbnRDb250ZW50IHx8IG1lc3NhZ2UuY2xpZW50Q29udGVudCA9PT0gdGhpcy5fbGFzdFJlY2VpdmVkTWVzc2FnZS5jbGllbnRDb250ZW50KTtcblxuXHRcdHRoaXMuX2xhc3RSZWNlaXZlZE1lc3NhZ2UgPSB1bmRlZmluZWQ7IC8vIHJlc2V0IGhpc3RvcnkgdG8gYXZvaWQgZmluZGluZyB0aGUgc2FtZSBtZXNzYWdlIHR3aWNlXG5cblx0XHRyZXR1cm4gZm91bmQ7XG5cdH0sXG5cblx0LyoqXG5cdCAqIENsb3NlcyB0aGUgZ2hvc3QgY2xpZW50IGFuZCByZW1vdmVzIHRoZSB1c2VyIGZyb20gdGhlIGNvbGxhYm9yYXRpdmUgZHJhZnQuXG5cdCAqL1xuXHRsZWF2ZURyYWZ0OiBmdW5jdGlvbiAoKSB7XG5cdFx0aWYgKHRoaXMuX2ludGVybmFsTW9kZWwpIHtcblx0XHRcdGVuZENvbGxhYm9yYXRpb24odGhpcy5faW50ZXJuYWxNb2RlbCk7XG5cdFx0XHR0aGlzLl9pbnRlcm5hbE1vZGVsLmRlc3Ryb3koKTtcblx0XHRcdHRoaXMuX2ludGVybmFsTW9kZWwgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBTaW11bGF0ZXMgdGhhdCB0aGUgdXNlciBzdGFydHMgdHlwaW5nIGluIGFuIGlucHV0IChsaXZlIGNoYW5nZSkuXG5cdCAqXG5cdCAqIEBwYXJhbSBzUHJvcGVydHlQYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSBiZWluZyBtb2RpZmllZFxuXHQgKi9cblx0c3RhcnRMaXZlQ2hhbmdlOiBmdW5jdGlvbiAoc1Byb3BlcnR5UGF0aDogc3RyaW5nKSB7XG5cdFx0aWYgKHRoaXMuX2ludGVybmFsTW9kZWwpIHtcblx0XHRcdGlmICh0aGlzLl9sb2NrZWRQcm9wZXJ0eVBhdGgpIHtcblx0XHRcdFx0Ly8gVW5sb2NrIHByZXZpb3VzIHByb3BlcnR5IHBhdGhcblx0XHRcdFx0dGhpcy51bmRvQ2hhbmdlKCk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLl9sb2NrZWRQcm9wZXJ0eVBhdGggPSBzUHJvcGVydHlQYXRoO1xuXHRcdFx0YnJvYWRjYXN0Q29sbGFib3JhdGlvbk1lc3NhZ2UoQWN0aXZpdHkuTGl2ZUNoYW5nZSwgdGhpcy5fcm9vdFBhdGggKyBcIi9cIiArIHNQcm9wZXJ0eVBhdGgsIHRoaXMuX2ludGVybmFsTW9kZWwpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogU2ltdWxhdGVzIHRoYXQgdGhlIHVzZXIgaGFzIG1vZGlmaWVkIGEgcHJvcGVydHkuXG5cdCAqXG5cdCAqIEBwYXJhbSBzUHJvcGVydHlQYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSBiZWluZyBtb2RpZmllZFxuXHQgKiBAcGFyYW0gdmFsdWUgVGhlIG5ldyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgYmVpbmcgbW9kaWZpZWRcblx0ICovXG5cdHVwZGF0ZVByb3BlcnR5VmFsdWU6IGZ1bmN0aW9uIChzUHJvcGVydHlQYXRoOiBzdHJpbmcsIHZhbHVlOiBhbnkpIHtcblx0XHRpZiAodGhpcy5faW50ZXJuYWxNb2RlbCkge1xuXHRcdFx0aWYgKHRoaXMuX2xvY2tlZFByb3BlcnR5UGF0aCAhPT0gc1Byb3BlcnR5UGF0aCkge1xuXHRcdFx0XHR0aGlzLnN0YXJ0TGl2ZUNoYW5nZShzUHJvcGVydHlQYXRoKTtcblx0XHRcdH1cblxuXHRcdFx0Y29uc3Qgb0NvbnRleHRCaW5kaW5nID0gdGhpcy5fb01vZGVsIS5iaW5kQ29udGV4dCh0aGlzLl9yb290UGF0aCwgdW5kZWZpbmVkLCB7XG5cdFx0XHRcdCQkcGF0Y2hXaXRob3V0U2lkZUVmZmVjdHM6IHRydWUsXG5cdFx0XHRcdCQkZ3JvdXBJZDogXCIkYXV0b1wiLFxuXHRcdFx0XHQkJHVwZGF0ZUdyb3VwSWQ6IFwiJGF1dG9cIlxuXHRcdFx0fSk7XG5cblx0XHRcdGNvbnN0IG9Qcm9wZXJ0eUJpbmRpbmcgPSB0aGlzLl9vTW9kZWwhLmJpbmRQcm9wZXJ0eShzUHJvcGVydHlQYXRoLCBvQ29udGV4dEJpbmRpbmcuZ2V0Qm91bmRDb250ZXh0KCkpO1xuXG5cdFx0XHRvUHJvcGVydHlCaW5kaW5nXG5cdFx0XHRcdC5yZXF1ZXN0VmFsdWUoKVxuXHRcdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdFx0b1Byb3BlcnR5QmluZGluZy5zZXRWYWx1ZSh2YWx1ZSk7XG5cdFx0XHRcdFx0b0NvbnRleHRCaW5kaW5nLmF0dGFjaEV2ZW50T25jZShcInBhdGNoQ29tcGxldGVkXCIsICgpID0+IHtcblx0XHRcdFx0XHRcdGJyb2FkY2FzdENvbGxhYm9yYXRpb25NZXNzYWdlKEFjdGl2aXR5LkNoYW5nZSwgdGhpcy5fcm9vdFBhdGggKyBcIi9cIiArIHNQcm9wZXJ0eVBhdGgsIHRoaXMuX2ludGVybmFsTW9kZWwhKTtcblx0XHRcdFx0XHRcdHRoaXMuX2xvY2tlZFByb3BlcnR5UGF0aCA9IFwiXCI7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5jYXRjaChmdW5jdGlvbiAoZXJyKSB7XG5cdFx0XHRcdFx0TG9nLmVycm9yKGVycik7XG5cdFx0XHRcdH0pO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogU2ltdWxhdGVzIHRoYXQgdGhlIHVzZXIgZGlkIGFuICd1bmRvJyAodG8gYmUgY2FsbGVkIGFmdGVyIHN0YXJ0TGl2ZUNoYW5nZSkuXG5cdCAqL1xuXHR1bmRvQ2hhbmdlOiBmdW5jdGlvbiAoKSB7XG5cdFx0aWYgKHRoaXMuX2xvY2tlZFByb3BlcnR5UGF0aCkge1xuXHRcdFx0YnJvYWRjYXN0Q29sbGFib3JhdGlvbk1lc3NhZ2UoQWN0aXZpdHkuVW5kbywgdGhpcy5fcm9vdFBhdGggKyBcIi9cIiArIHRoaXMuX2xvY2tlZFByb3BlcnR5UGF0aCwgdGhpcy5faW50ZXJuYWxNb2RlbCEpO1xuXHRcdFx0dGhpcy5fbG9ja2VkUHJvcGVydHlQYXRoID0gXCJcIjtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFNpbXVsYXRlcyB0aGF0IHRoZSB1c2VyIGhhcyBkaXNjYXJkZWQgdGhlIGRyYWZ0LlxuXHQgKi9cblx0ZGlzY2FyZERyYWZ0OiBmdW5jdGlvbiAoKSB7XG5cdFx0aWYgKHRoaXMuX2ludGVybmFsTW9kZWwpIHtcblx0XHRcdGNvbnN0IGRyYWZ0Q29udGV4dCA9IHRoaXMuX2dldERyYWZ0Q29udGV4dCgpO1xuXG5cdFx0XHRkcmFmdENvbnRleHRcblx0XHRcdFx0LnJlcXVlc3RQcm9wZXJ0eShcIklzQWN0aXZlRW50aXR5XCIpXG5cdFx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0XHRkcmFmdC5kZWxldGVEcmFmdChkcmFmdENvbnRleHQpO1xuXHRcdFx0XHR9KVxuXHRcdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdFx0YnJvYWRjYXN0Q29sbGFib3JhdGlvbk1lc3NhZ2UoXG5cdFx0XHRcdFx0XHRBY3Rpdml0eS5EaXNjYXJkLFxuXHRcdFx0XHRcdFx0dGhpcy5fcm9vdFBhdGgucmVwbGFjZShcIklzQWN0aXZlRW50aXR5PWZhbHNlXCIsIFwiSXNBY3RpdmVFbnRpdHk9dHJ1ZVwiKSxcblx0XHRcdFx0XHRcdHRoaXMuX2ludGVybmFsTW9kZWwhXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHR0aGlzLl9pbnRlcm5hbE1vZGVsIS5kZXN0cm95KCk7XG5cdFx0XHRcdFx0dGhpcy5faW50ZXJuYWxNb2RlbCA9IHVuZGVmaW5lZDtcblx0XHRcdFx0fSlcblx0XHRcdFx0LmNhdGNoKGZ1bmN0aW9uIChlcnI6IGFueSkge1xuXHRcdFx0XHRcdExvZy5lcnJvcihlcnIpO1xuXHRcdFx0XHR9KTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFNpbXVsYXRlcyB0aGF0IHRoZSB1c2VyIGhhcyBkZWxldGVkIHRoZSBkcmFmdC5cblx0ICovXG5cdGRlbGV0ZURyYWZ0OiBmdW5jdGlvbiAoKSB7XG5cdFx0aWYgKHRoaXMuX2ludGVybmFsTW9kZWwpIHtcblx0XHRcdGNvbnN0IGRyYWZ0Q29udGV4dCA9IHRoaXMuX2dldERyYWZ0Q29udGV4dCgpO1xuXHRcdFx0bGV0IGFjdGl2ZUNvbnRleHQ6IENvbnRleHQ7XG5cblx0XHRcdGRyYWZ0Q29udGV4dFxuXHRcdFx0XHQucmVxdWVzdFByb3BlcnR5KFwiSXNBY3RpdmVFbnRpdHlcIilcblx0XHRcdFx0LnRoZW4oKCkgPT4ge1xuXHRcdFx0XHRcdHJldHVybiBkcmFmdENvbnRleHRcblx0XHRcdFx0XHRcdC5nZXRNb2RlbCgpXG5cdFx0XHRcdFx0XHQuYmluZENvbnRleHQodGhpcy5fcm9vdFBhdGggKyBcIi9TaWJsaW5nRW50aXR5XCIpXG5cdFx0XHRcdFx0XHQuZ2V0Qm91bmRDb250ZXh0KCk7XG5cdFx0XHRcdH0pXG5cdFx0XHRcdC50aGVuKChjb250ZXh0OiBhbnkpID0+IHtcblx0XHRcdFx0XHRhY3RpdmVDb250ZXh0ID0gY29udGV4dDtcblx0XHRcdFx0XHRyZXR1cm4gY29udGV4dC5yZXF1ZXN0Q2Fub25pY2FsUGF0aCgpO1xuXHRcdFx0XHR9KVxuXHRcdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdFx0cmV0dXJuIGRyYWZ0LmRlbGV0ZURyYWZ0KGRyYWZ0Q29udGV4dCk7XG5cdFx0XHRcdH0pXG5cdFx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0XHQoYWN0aXZlQ29udGV4dCBhcyBhbnkpLmRlbGV0ZSgpO1xuXHRcdFx0XHRcdGJyb2FkY2FzdENvbGxhYm9yYXRpb25NZXNzYWdlKEFjdGl2aXR5LkRlbGV0ZSwgdGhpcy5fcm9vdFBhdGgsIHRoaXMuX2ludGVybmFsTW9kZWwhKTtcblx0XHRcdFx0XHR0aGlzLl9pbnRlcm5hbE1vZGVsIS5kZXN0cm95KCk7XG5cdFx0XHRcdFx0dGhpcy5faW50ZXJuYWxNb2RlbCA9IHVuZGVmaW5lZDtcblx0XHRcdFx0fSlcblx0XHRcdFx0LmNhdGNoKGZ1bmN0aW9uIChlcnI6IGFueSkge1xuXHRcdFx0XHRcdExvZy5lcnJvcihlcnIpO1xuXHRcdFx0XHR9KTtcblx0XHR9XG5cdH0sXG5cblx0Ly8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0Ly8gUHJpdmF0ZSBtZXRob2RzXG5cblx0X2dldERyYWZ0Q29udGV4dDogZnVuY3Rpb24gKCk6IGFueSB7XG5cdFx0cmV0dXJuIHRoaXMuX29Nb2RlbCEuYmluZENvbnRleHQodGhpcy5fcm9vdFBhdGgsIHVuZGVmaW5lZCwge1xuXHRcdFx0JCRwYXRjaFdpdGhvdXRTaWRlRWZmZWN0czogdHJ1ZSxcblx0XHRcdCQkZ3JvdXBJZDogXCIkYXV0b1wiLFxuXHRcdFx0JCR1cGRhdGVHcm91cElkOiBcIiRhdXRvXCJcblx0XHR9KS5nZXRCb3VuZENvbnRleHQoKTtcblx0fSxcblxuXHQvKipcblx0ICogQ2FsbGJhY2sgb2YgdGhlIGdob3N0IGNsaWVudCB3aGVuIHJlY2VpdmluZyBhIG1lc3NhZ2Ugb24gdGhlIHdlYiBzb2NrZXQuXG5cdCAqXG5cdCAqIEBwYXJhbSBvTWVzc2FnZSBUaGUgbWVzc2FnZVxuXHQgKi9cblx0X29uTWVzc2FnZVJlY2VpdmVkOiBmdW5jdGlvbiAob01lc3NhZ2U6IE1lc3NhZ2UpIHtcblx0XHRvTWVzc2FnZS51c2VyQWN0aW9uID0gb01lc3NhZ2UudXNlckFjdGlvbiB8fCBvTWVzc2FnZS5jbGllbnRBY3Rpb247XG5cdFx0dGhpcy5fbGFzdFJlY2VpdmVkTWVzc2FnZSA9IG9NZXNzYWdlO1xuXG5cdFx0aWYgKG9NZXNzYWdlLnVzZXJBY3Rpb24gPT09IEFjdGl2aXR5LkpvaW4pIHtcblx0XHRcdGJyb2FkY2FzdENvbGxhYm9yYXRpb25NZXNzYWdlKFxuXHRcdFx0XHRBY3Rpdml0eS5Kb2luRWNobyxcblx0XHRcdFx0dGhpcy5fbG9ja2VkUHJvcGVydHlQYXRoID8gdGhpcy5fcm9vdFBhdGggKyBcIi9cIiArIHRoaXMuX2xvY2tlZFByb3BlcnR5UGF0aCA6IHVuZGVmaW5lZCxcblx0XHRcdFx0dGhpcy5faW50ZXJuYWxNb2RlbCFcblx0XHRcdCk7XG5cdFx0fVxuXHR9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBDb2xsYWJvcmF0aW9uQVBJO1xuIl19
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import Log from "sap/base/Log";
|
|
2
|
+
import {
|
|
3
|
+
broadcastCollaborationMessage,
|
|
4
|
+
endCollaboration,
|
|
5
|
+
initializeCollaboration
|
|
6
|
+
} from "sap/fe/core/controllerextensions/collaboration/ActivityBase";
|
|
7
|
+
import { Activity, Message } from "sap/fe/core/controllerextensions/collaboration/CollaborationCommon";
|
|
8
|
+
import draft from "sap/fe/core/controllerextensions/editFlow/draft";
|
|
9
|
+
import Context from "sap/ui/model/Context";
|
|
10
|
+
import JSONModel from "sap/ui/model/json/JSONModel";
|
|
11
|
+
import ODataModel from "sap/ui/model/odata/v4/ODataModel";
|
|
12
|
+
|
|
13
|
+
const CollaborationAPI = {
|
|
14
|
+
_lastReceivedMessage: undefined as Message | undefined,
|
|
15
|
+
_rootPath: "",
|
|
16
|
+
_oModel: undefined as ODataModel | undefined,
|
|
17
|
+
_lockedPropertyPath: "",
|
|
18
|
+
_internalModel: undefined as JSONModel | undefined,
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Open an existing collaborative draft with a new user, and creates a 'ghost client' for this user.
|
|
22
|
+
*
|
|
23
|
+
* @param oContext The context of the collaborative draft
|
|
24
|
+
* @param userID The ID of the user
|
|
25
|
+
* @param userName The name of the user
|
|
26
|
+
*/
|
|
27
|
+
enterDraft: function (oContext: Context, userID: string, userName: string) {
|
|
28
|
+
const webSocketBaseURL: string = oContext.getModel().getMetaModel().getObject("/@com.sap.vocabularies.Common.v1.WebSocketBaseURL");
|
|
29
|
+
|
|
30
|
+
if (!webSocketBaseURL) {
|
|
31
|
+
Log.error("Cannot find WebSocketBaseURL annotation");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const sDraftUUID: string = oContext.getProperty("DraftAdministrativeData/DraftUUID");
|
|
36
|
+
this._internalModel = new JSONModel({});
|
|
37
|
+
|
|
38
|
+
initializeCollaboration(
|
|
39
|
+
{
|
|
40
|
+
id: userID,
|
|
41
|
+
name: userName,
|
|
42
|
+
initialName: userName
|
|
43
|
+
},
|
|
44
|
+
webSocketBaseURL,
|
|
45
|
+
sDraftUUID,
|
|
46
|
+
this._internalModel,
|
|
47
|
+
this._onMessageReceived.bind(this),
|
|
48
|
+
true
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
this._rootPath = oContext.getPath();
|
|
52
|
+
this._oModel = oContext.getModel() as ODataModel;
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Checks if the ghost client has revieved a given message.
|
|
57
|
+
*
|
|
58
|
+
* @param message The message content to be looked for
|
|
59
|
+
* @returns True if the last recieved message matches the content
|
|
60
|
+
*/
|
|
61
|
+
checkReceived: function (message: Partial<Message>): boolean {
|
|
62
|
+
if (!this._lastReceivedMessage) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const found =
|
|
67
|
+
(!message.userID || message.userID === this._lastReceivedMessage.userID) &&
|
|
68
|
+
(!message.userAction || message.userAction === this._lastReceivedMessage.userAction) &&
|
|
69
|
+
(!message.clientContent || message.clientContent === this._lastReceivedMessage.clientContent);
|
|
70
|
+
|
|
71
|
+
this._lastReceivedMessage = undefined; // reset history to avoid finding the same message twice
|
|
72
|
+
|
|
73
|
+
return found;
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Closes the ghost client and removes the user from the collaborative draft.
|
|
78
|
+
*/
|
|
79
|
+
leaveDraft: function () {
|
|
80
|
+
if (this._internalModel) {
|
|
81
|
+
endCollaboration(this._internalModel);
|
|
82
|
+
this._internalModel.destroy();
|
|
83
|
+
this._internalModel = undefined;
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Simulates that the user starts typing in an input (live change).
|
|
89
|
+
*
|
|
90
|
+
* @param sPropertyPath The path of the property being modified
|
|
91
|
+
*/
|
|
92
|
+
startLiveChange: function (sPropertyPath: string) {
|
|
93
|
+
if (this._internalModel) {
|
|
94
|
+
if (this._lockedPropertyPath) {
|
|
95
|
+
// Unlock previous property path
|
|
96
|
+
this.undoChange();
|
|
97
|
+
}
|
|
98
|
+
this._lockedPropertyPath = sPropertyPath;
|
|
99
|
+
broadcastCollaborationMessage(Activity.LiveChange, this._rootPath + "/" + sPropertyPath, this._internalModel);
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Simulates that the user has modified a property.
|
|
105
|
+
*
|
|
106
|
+
* @param sPropertyPath The path of the property being modified
|
|
107
|
+
* @param value The new value of the property being modified
|
|
108
|
+
*/
|
|
109
|
+
updatePropertyValue: function (sPropertyPath: string, value: any) {
|
|
110
|
+
if (this._internalModel) {
|
|
111
|
+
if (this._lockedPropertyPath !== sPropertyPath) {
|
|
112
|
+
this.startLiveChange(sPropertyPath);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const oContextBinding = this._oModel!.bindContext(this._rootPath, undefined, {
|
|
116
|
+
$$patchWithoutSideEffects: true,
|
|
117
|
+
$$groupId: "$auto",
|
|
118
|
+
$$updateGroupId: "$auto"
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const oPropertyBinding = this._oModel!.bindProperty(sPropertyPath, oContextBinding.getBoundContext());
|
|
122
|
+
|
|
123
|
+
oPropertyBinding
|
|
124
|
+
.requestValue()
|
|
125
|
+
.then(() => {
|
|
126
|
+
oPropertyBinding.setValue(value);
|
|
127
|
+
oContextBinding.attachEventOnce("patchCompleted", () => {
|
|
128
|
+
broadcastCollaborationMessage(Activity.Change, this._rootPath + "/" + sPropertyPath, this._internalModel!);
|
|
129
|
+
this._lockedPropertyPath = "";
|
|
130
|
+
});
|
|
131
|
+
})
|
|
132
|
+
.catch(function (err) {
|
|
133
|
+
Log.error(err);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Simulates that the user did an 'undo' (to be called after startLiveChange).
|
|
140
|
+
*/
|
|
141
|
+
undoChange: function () {
|
|
142
|
+
if (this._lockedPropertyPath) {
|
|
143
|
+
broadcastCollaborationMessage(Activity.Undo, this._rootPath + "/" + this._lockedPropertyPath, this._internalModel!);
|
|
144
|
+
this._lockedPropertyPath = "";
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Simulates that the user has discarded the draft.
|
|
150
|
+
*/
|
|
151
|
+
discardDraft: function () {
|
|
152
|
+
if (this._internalModel) {
|
|
153
|
+
const draftContext = this._getDraftContext();
|
|
154
|
+
|
|
155
|
+
draftContext
|
|
156
|
+
.requestProperty("IsActiveEntity")
|
|
157
|
+
.then(() => {
|
|
158
|
+
draft.deleteDraft(draftContext);
|
|
159
|
+
})
|
|
160
|
+
.then(() => {
|
|
161
|
+
broadcastCollaborationMessage(
|
|
162
|
+
Activity.Discard,
|
|
163
|
+
this._rootPath.replace("IsActiveEntity=false", "IsActiveEntity=true"),
|
|
164
|
+
this._internalModel!
|
|
165
|
+
);
|
|
166
|
+
this._internalModel!.destroy();
|
|
167
|
+
this._internalModel = undefined;
|
|
168
|
+
})
|
|
169
|
+
.catch(function (err: any) {
|
|
170
|
+
Log.error(err);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Simulates that the user has deleted the draft.
|
|
177
|
+
*/
|
|
178
|
+
deleteDraft: function () {
|
|
179
|
+
if (this._internalModel) {
|
|
180
|
+
const draftContext = this._getDraftContext();
|
|
181
|
+
let activeContext: Context;
|
|
182
|
+
|
|
183
|
+
draftContext
|
|
184
|
+
.requestProperty("IsActiveEntity")
|
|
185
|
+
.then(() => {
|
|
186
|
+
return draftContext
|
|
187
|
+
.getModel()
|
|
188
|
+
.bindContext(this._rootPath + "/SiblingEntity")
|
|
189
|
+
.getBoundContext();
|
|
190
|
+
})
|
|
191
|
+
.then((context: any) => {
|
|
192
|
+
activeContext = context;
|
|
193
|
+
return context.requestCanonicalPath();
|
|
194
|
+
})
|
|
195
|
+
.then(() => {
|
|
196
|
+
return draft.deleteDraft(draftContext);
|
|
197
|
+
})
|
|
198
|
+
.then(() => {
|
|
199
|
+
(activeContext as any).delete();
|
|
200
|
+
broadcastCollaborationMessage(Activity.Delete, this._rootPath, this._internalModel!);
|
|
201
|
+
this._internalModel!.destroy();
|
|
202
|
+
this._internalModel = undefined;
|
|
203
|
+
})
|
|
204
|
+
.catch(function (err: any) {
|
|
205
|
+
Log.error(err);
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
|
|
210
|
+
// /////////////////////////////
|
|
211
|
+
// Private methods
|
|
212
|
+
|
|
213
|
+
_getDraftContext: function (): any {
|
|
214
|
+
return this._oModel!.bindContext(this._rootPath, undefined, {
|
|
215
|
+
$$patchWithoutSideEffects: true,
|
|
216
|
+
$$groupId: "$auto",
|
|
217
|
+
$$updateGroupId: "$auto"
|
|
218
|
+
}).getBoundContext();
|
|
219
|
+
},
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Callback of the ghost client when receiving a message on the web socket.
|
|
223
|
+
*
|
|
224
|
+
* @param oMessage The message
|
|
225
|
+
*/
|
|
226
|
+
_onMessageReceived: function (oMessage: Message) {
|
|
227
|
+
oMessage.userAction = oMessage.userAction || oMessage.clientAction;
|
|
228
|
+
this._lastReceivedMessage = oMessage;
|
|
229
|
+
|
|
230
|
+
if (oMessage.userAction === Activity.Join) {
|
|
231
|
+
broadcastCollaborationMessage(
|
|
232
|
+
Activity.JoinEcho,
|
|
233
|
+
this._lockedPropertyPath ? this._rootPath + "/" + this._lockedPropertyPath : undefined,
|
|
234
|
+
this._internalModel!
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
export default CollaborationAPI;
|
|
@@ -100,11 +100,13 @@ sap.ui.define(["./DialogAPI", "sap/fe/test/Utils", "sap/ui/test/OpaBuilder"], fu
|
|
|
100
100
|
/**
|
|
101
101
|
* Changes the content of a field in an action parameter dialog.
|
|
102
102
|
*
|
|
103
|
+
* Deprecated: Please use dialog action iChangeDialogField.
|
|
104
|
+
*
|
|
103
105
|
* @param {sap.fe.test.api.ActionDialogFieldIdentifier} vFieldIdentifier The identifier of the field
|
|
104
106
|
* @param {string} [vValue] The new target value.
|
|
105
107
|
* @param {boolean} [bClearFirst] Set to <code>true</code> to clear previously set filters, otherwise all previously set values will be kept
|
|
106
108
|
* @returns {object} The result of the {@link sap.ui.test.Opa5#waitFor} function, that can be used for chaining statements
|
|
107
|
-
* @
|
|
109
|
+
* @ui5-restricted
|
|
108
110
|
*/
|
|
109
111
|
DialogActions.prototype.iChangeActionParameterDialogField = function(vFieldIdentifier, vValue, bClearFirst) {
|
|
110
112
|
return this.iChangeDialogField(vFieldIdentifier, vValue, bClearFirst);
|
|
@@ -3,72 +3,86 @@
|
|
|
3
3
|
(c) Copyright 2009-2021 SAP SE. All rights reserved
|
|
4
4
|
|
|
5
5
|
*/
|
|
6
|
-
sap.ui.define(
|
|
7
|
-
"
|
|
6
|
+
sap.ui.define(
|
|
7
|
+
["./DialogActions", "sap/fe/test/Utils", "sap/ui/test/OpaBuilder", "sap/fe/test/builder/FEBuilder"],
|
|
8
|
+
function (DialogActions, Utils, OpaBuilder, FEBuilder) {
|
|
9
|
+
"use strict";
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Constructs a new DialogMessageActions instance.
|
|
13
|
+
*
|
|
14
|
+
* @param {sap.fe.test.builder.DialogBuilder} oDialogBuilder The {@link sap.fe.test.builder.DialogBuilder} instance used to interact with the UI
|
|
15
|
+
* @param {string} [vDialogDescription] Description (optional) of the dialog to be used for logging messages
|
|
16
|
+
* @returns {sap.fe.test.api.DialogMessageActions} The new instance
|
|
17
|
+
* @extends sap.fe.test.api.DialogActions
|
|
18
|
+
* @alias sap.fe.test.api.DialogMessageActions
|
|
19
|
+
* @class
|
|
20
|
+
* @hideconstructor
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
var DialogMessageActions = function (oDialogBuilder, vDialogDescription) {
|
|
24
|
+
return DialogActions.call(this, oDialogBuilder, vDialogDescription, 0);
|
|
25
|
+
};
|
|
26
|
+
DialogMessageActions.prototype = Object.create(DialogActions.prototype);
|
|
27
|
+
DialogMessageActions.prototype.constructor = DialogMessageActions;
|
|
28
|
+
DialogMessageActions.prototype.isAction = true;
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Executes the <code>Back</code> action on the message dialog.
|
|
32
|
+
*
|
|
33
|
+
* @returns {object} The result of the {@link sap.ui.test.Opa5#waitFor} function, to be used for chained statements
|
|
34
|
+
* @public
|
|
35
|
+
*/
|
|
36
|
+
DialogMessageActions.prototype.iExecuteBack = function () {
|
|
37
|
+
return this.prepareResult(
|
|
38
|
+
this.getBuilder()
|
|
39
|
+
.doPressHeaderButton(OpaBuilder.Matchers.properties({ icon: "sap-icon://nav-back" }))
|
|
40
|
+
.description(Utils.formatMessage("Pressing back button on dialog '{0}'", this.getIdentifier()))
|
|
41
|
+
.execute()
|
|
42
|
+
);
|
|
43
|
+
};
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Executes the <code>Refresh</code> action on the message dialog.
|
|
47
|
+
*
|
|
48
|
+
* @returns {object} The result of the {@link sap.ui.test.Opa5#waitFor} function, to be used for chained statements
|
|
49
|
+
* @public
|
|
50
|
+
*/
|
|
51
|
+
DialogMessageActions.prototype.iExecuteRefresh = function () {
|
|
52
|
+
return this.prepareResult(
|
|
53
|
+
this.getBuilder()
|
|
54
|
+
.doPressFooterButton(OpaBuilder.Matchers.resourceBundle("text", "sap.fe.core", "C_COMMON_SAPFE_REFRESH"))
|
|
55
|
+
.description(Utils.formatMessage("Pressing refresh button on dialog '{0}'", this.getIdentifier()))
|
|
56
|
+
.execute()
|
|
57
|
+
);
|
|
58
|
+
};
|
|
57
59
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
.
|
|
70
|
-
|
|
71
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Selects the specified entry in the draft data loss popup
|
|
62
|
+
*
|
|
63
|
+
* @returns {object} The result of the {@link sap.ui.test.Opa5#waitFor} function, to be used for chained statements
|
|
64
|
+
* @public
|
|
65
|
+
*/
|
|
66
|
+
DialogMessageActions.prototype.iSelectDraftDataLossOption = function (optionKey) {
|
|
67
|
+
// The logic below uses customData for identifying the entry in list in the dialog
|
|
68
|
+
// which needs to be pressed
|
|
69
|
+
// The dialog's XML fragment for the custom data and the used keys
|
|
70
|
+
return this.prepareResult(
|
|
71
|
+
FEBuilder.create()
|
|
72
|
+
.hasType("sap.m.List")
|
|
73
|
+
.isDialogElement(true)
|
|
74
|
+
.has(OpaBuilder.Matchers.aggregation("items"))
|
|
75
|
+
.has(function (oItem) {
|
|
76
|
+
return oItem.find(function (element) {
|
|
77
|
+
return element.data("itemKey") === optionKey;
|
|
78
|
+
});
|
|
79
|
+
})
|
|
80
|
+
.doPress()
|
|
81
|
+
.description("Selecting option with key {0} in draft data loss popup")
|
|
82
|
+
.execute()
|
|
83
|
+
);
|
|
84
|
+
};
|
|
72
85
|
|
|
73
|
-
|
|
74
|
-
}
|
|
86
|
+
return DialogMessageActions;
|
|
87
|
+
}
|
|
88
|
+
);
|