@sapui5/sap.fe.core 1.102.3 → 1.102.5
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 +1 -1
- package/src/sap/fe/core/.library +1 -1
- package/src/sap/fe/core/CommonUtils.js +18 -2
- package/src/sap/fe/core/CommonUtils.ts +15 -1
- package/src/sap/fe/core/ExtensionAPI.js +34 -1
- package/src/sap/fe/core/ExtensionAPI.ts +30 -0
- package/src/sap/fe/core/PageController.js +9 -7
- package/src/sap/fe/core/PageController.ts +10 -1
- package/src/sap/fe/core/controllerextensions/PageReady.js +85 -176
- package/src/sap/fe/core/controllerextensions/PageReady.ts +86 -168
- package/src/sap/fe/core/controllerextensions/editFlow/operations.js +3 -4
- package/src/sap/fe/core/controllerextensions/editFlow/operations.ts +3 -3
- package/src/sap/fe/core/controllerextensions/pageReady/DataQueryWatcher.js +397 -0
- package/src/sap/fe/core/controllerextensions/pageReady/DataQueryWatcher.ts +295 -0
- package/src/sap/fe/core/converters/annotations/DataField.js +9 -7
- package/src/sap/fe/core/converters/annotations/DataField.ts +10 -7
- package/src/sap/fe/core/converters/controls/Common/Table.js +1 -2
- package/src/sap/fe/core/converters/controls/Common/Table.ts +0 -2
- package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +12 -2
- package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +14 -1
- package/src/sap/fe/core/library.js +1 -1
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import Log from "sap/base/Log";
|
|
2
|
-
import AppComponent from "sap/fe/core/AppComponent";
|
|
2
|
+
import type AppComponent from "sap/fe/core/AppComponent";
|
|
3
|
+
import DataQueryWatcher from "sap/fe/core/controllerextensions/pageReady/DataQueryWatcher";
|
|
3
4
|
import TemplatedViewServiceFactory from "sap/fe/core/services/TemplatedViewServiceFactory";
|
|
4
|
-
import Event from "sap/ui/base/Event";
|
|
5
|
+
import type Event from "sap/ui/base/Event";
|
|
5
6
|
import EventProvider from "sap/ui/base/EventProvider";
|
|
6
|
-
import ManagedObject from "sap/ui/base/ManagedObject";
|
|
7
|
+
import type ManagedObject from "sap/ui/base/ManagedObject";
|
|
7
8
|
import Component from "sap/ui/core/Component";
|
|
8
9
|
import Core from "sap/ui/core/Core";
|
|
9
10
|
import ControllerExtension from "sap/ui/core/mvc/ControllerExtension";
|
|
10
11
|
import OverrideExecution from "sap/ui/core/mvc/OverrideExecution";
|
|
11
|
-
import View from "sap/ui/core/mvc/View";
|
|
12
|
-
import Context from "sap/ui/model/Context";
|
|
13
|
-
import { CoreEx } from "types/extension_types";
|
|
12
|
+
import type View from "sap/ui/core/mvc/View";
|
|
13
|
+
import type Context from "sap/ui/model/odata/v4/Context";
|
|
14
|
+
import type { CoreEx } from "types/extension_types";
|
|
14
15
|
import CommonUtils from "../CommonUtils";
|
|
15
16
|
import { defineUI5Class, extensible, finalExtension, methodOverride, privateExtension, publicExtension } from "../helpers/ClassSupport";
|
|
16
|
-
|
|
17
17
|
@defineUI5Class("sap.fe.core.controllerextensions.PageReady")
|
|
18
18
|
class PageReadyControllerExtension extends ControllerExtension {
|
|
19
19
|
private _oEventProvider!: EventProvider;
|
|
@@ -24,19 +24,17 @@ class PageReadyControllerExtension extends ControllerExtension {
|
|
|
24
24
|
private _bAfterBindingAlreadyApplied!: boolean;
|
|
25
25
|
private _fnContainerDelegate: any;
|
|
26
26
|
private _nbWaits!: number;
|
|
27
|
-
private _bSeachTriggered!: boolean;
|
|
28
27
|
private _bIsPageReady!: boolean;
|
|
29
28
|
private _bWaitingForRefresh!: boolean;
|
|
30
29
|
private bShown!: boolean;
|
|
31
30
|
private bHasContext!: boolean;
|
|
32
|
-
private
|
|
33
|
-
private bTablesLoaded: boolean | undefined;
|
|
31
|
+
private bTablesChartsLoaded?: boolean;
|
|
34
32
|
private pageReadyTimer: NodeJS.Timeout | undefined;
|
|
33
|
+
private queryWatcher!: DataQueryWatcher;
|
|
35
34
|
|
|
36
35
|
@methodOverride()
|
|
37
36
|
public onInit() {
|
|
38
37
|
this._nbWaits = 0;
|
|
39
|
-
this._bSeachTriggered = false;
|
|
40
38
|
this._oEventProvider = this._oEventProvider ? this._oEventProvider : new EventProvider();
|
|
41
39
|
this._oView = (this as any).base.getView();
|
|
42
40
|
this._oAppComponent = CommonUtils.getAppComponent(this._oView);
|
|
@@ -68,6 +66,8 @@ class PageReadyControllerExtension extends ControllerExtension {
|
|
|
68
66
|
this
|
|
69
67
|
);
|
|
70
68
|
}
|
|
69
|
+
|
|
70
|
+
this.queryWatcher = new DataQueryWatcher(this._oEventProvider, this.checkPageReadyDebounced.bind(this));
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
@methodOverride()
|
|
@@ -75,7 +75,9 @@ class PageReadyControllerExtension extends ControllerExtension {
|
|
|
75
75
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
76
76
|
// @ts-ignore
|
|
77
77
|
delete this._oAppComponent;
|
|
78
|
-
|
|
78
|
+
if (this._oContainer) {
|
|
79
|
+
this._oContainer.removeEventDelegate(this._fnContainerDelegate);
|
|
80
|
+
}
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
@publicExtension()
|
|
@@ -99,162 +101,78 @@ class PageReadyControllerExtension extends ControllerExtension {
|
|
|
99
101
|
this.checkPageReadyDebounced();
|
|
100
102
|
}
|
|
101
103
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
this.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
default:
|
|
124
|
-
}
|
|
125
|
-
(oEvent.getSource() as any).detachDataReceived(fnReceived);
|
|
126
|
-
iReceived++;
|
|
127
|
-
if (iReceived >= iRequested && iRequested !== 0) {
|
|
128
|
-
iRequested = 0;
|
|
129
|
-
iReceived = 0;
|
|
130
|
-
this.bDataReceived = true;
|
|
131
|
-
this.checkPageReadyDebounced();
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
const fnSearch = (oEvent: Event) => {
|
|
135
|
-
const aMDCTables = aNotBoundMDCTables.filter((oElem) => {
|
|
136
|
-
if ((oEvent.getSource() as any).sId === oElem.getFilter() && oElem.getVisible()) {
|
|
137
|
-
return true;
|
|
138
|
-
}
|
|
139
|
-
return false;
|
|
140
|
-
});
|
|
141
|
-
if (aMDCTables.length > 0) {
|
|
142
|
-
this._bSeachTriggered = true;
|
|
143
|
-
}
|
|
144
|
-
aMDCTables.forEach((oMDCTable: any) => {
|
|
145
|
-
let oRowBinding = oMDCTable.getRowBinding();
|
|
146
|
-
const fnAttachDataEvents = () => {
|
|
147
|
-
oRowBinding.attachDataRequested(fnRequested);
|
|
148
|
-
oRowBinding.attachDataReceived((oEvent: any) => {
|
|
149
|
-
fnReceived(oEvent);
|
|
150
|
-
this._bSeachTriggered = false;
|
|
151
|
-
});
|
|
152
|
-
aBoundElements.push(oRowBinding);
|
|
153
|
-
};
|
|
154
|
-
if (oRowBinding) {
|
|
155
|
-
fnAttachDataEvents();
|
|
156
|
-
} else {
|
|
157
|
-
oMDCTable.attachEventOnce(
|
|
158
|
-
"bindingUpdated",
|
|
159
|
-
null,
|
|
160
|
-
() => {
|
|
161
|
-
oRowBinding = oMDCTable.getRowBinding();
|
|
162
|
-
fnAttachDataEvents();
|
|
163
|
-
},
|
|
164
|
-
null
|
|
165
|
-
);
|
|
104
|
+
public registerAggregatedControls(mainBindingContext?: Context): Promise<void>[] {
|
|
105
|
+
if (mainBindingContext) {
|
|
106
|
+
const mainObjectBinding = mainBindingContext.getBinding();
|
|
107
|
+
this.queryWatcher.registerBinding(mainObjectBinding);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const aPromises: Promise<void>[] = [];
|
|
111
|
+
const aControls = this.getView().findAggregatedObjects(true);
|
|
112
|
+
|
|
113
|
+
aControls.forEach((oElement: any) => {
|
|
114
|
+
const oObjectBinding = oElement.getObjectBinding();
|
|
115
|
+
if (oObjectBinding) {
|
|
116
|
+
// Register on all object binding (mostly used on object pages)
|
|
117
|
+
this.queryWatcher.registerBinding(oObjectBinding);
|
|
118
|
+
} else {
|
|
119
|
+
const aBindingKeys = Object.keys(oElement.mBindingInfos);
|
|
120
|
+
aBindingKeys.forEach((sPropertyName) => {
|
|
121
|
+
const oListBinding = oElement.mBindingInfos[sPropertyName].binding;
|
|
122
|
+
|
|
123
|
+
if (oListBinding && oListBinding.isA("sap.ui.model.odata.v4.ODataListBinding")) {
|
|
124
|
+
this.queryWatcher.registerBinding(oListBinding);
|
|
166
125
|
}
|
|
167
126
|
});
|
|
168
|
-
};
|
|
169
|
-
if (this.isContextExpected() && oBindingContext === undefined) {
|
|
170
|
-
// Force to mention we are expecting data
|
|
171
|
-
this.bHasContext = false;
|
|
172
|
-
return;
|
|
173
|
-
} else {
|
|
174
|
-
this.bHasContext = true;
|
|
175
127
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
oElement.detachEvent("dataRequested", fnRequested);
|
|
183
|
-
oElement.detachEvent("dataReceived", fnReceived);
|
|
184
|
-
oElement.detachEvent("search", fnSearch);
|
|
185
|
-
});
|
|
186
|
-
this._bAfterBindingAlreadyApplied = false;
|
|
187
|
-
aBoundElements = [];
|
|
188
|
-
},
|
|
189
|
-
null
|
|
190
|
-
);
|
|
191
|
-
if (oBindingContext) {
|
|
192
|
-
const mainObjectBinding = (oBindingContext as any).getBinding();
|
|
193
|
-
mainObjectBinding.attachDataRequested(fnRequested);
|
|
194
|
-
mainObjectBinding.attachDataReceived(fnReceived);
|
|
195
|
-
aBoundElements.push(mainObjectBinding);
|
|
128
|
+
// This is dirty but MDCTables and MDCCharts have a weird loading lifecycle
|
|
129
|
+
if (oElement.isA("sap.ui.mdc.Table") || oElement.isA("sap.ui.mdc.Chart")) {
|
|
130
|
+
this.bTablesChartsLoaded = false;
|
|
131
|
+
aPromises.push(this.queryWatcher.registerTableOrChart(oElement));
|
|
132
|
+
} else if (oElement.isA("sap.fe.core.controls.FilterBar")) {
|
|
133
|
+
this.queryWatcher.registerFilterBar(oElement);
|
|
196
134
|
}
|
|
135
|
+
});
|
|
197
136
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
.catch(function (oError: Error) {
|
|
238
|
-
Log.error("Cannot find a bound table", oError as any);
|
|
239
|
-
})
|
|
240
|
-
);
|
|
241
|
-
} else if (oElement.isA("sap.fe.core.controls.FilterBar")) {
|
|
242
|
-
oElement.attachEvent("search", fnSearch);
|
|
243
|
-
aBoundElements.push(oElement);
|
|
244
|
-
}
|
|
245
|
-
});
|
|
246
|
-
if (aTableInitializedPromises.length > 0) {
|
|
247
|
-
Promise.all(aTableInitializedPromises)
|
|
248
|
-
.then(() => {
|
|
249
|
-
this.bTablesLoaded = true;
|
|
250
|
-
this.checkPageReadyDebounced();
|
|
251
|
-
})
|
|
252
|
-
.catch((oError) => {
|
|
253
|
-
Log.info("There was an error with one or multiple table", oError);
|
|
254
|
-
this.bTablesLoaded = true;
|
|
255
|
-
this.checkPageReadyDebounced();
|
|
256
|
-
});
|
|
257
|
-
}
|
|
137
|
+
return aPromises;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@methodOverride("_routing")
|
|
141
|
+
onAfterBinding(oBindingContext: Context) {
|
|
142
|
+
if (this._bAfterBindingAlreadyApplied) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
this._bAfterBindingAlreadyApplied = true;
|
|
146
|
+
|
|
147
|
+
if (this.isContextExpected() && oBindingContext === undefined) {
|
|
148
|
+
// Force to mention we are expecting data
|
|
149
|
+
this.bHasContext = false;
|
|
150
|
+
return;
|
|
151
|
+
} else {
|
|
152
|
+
this.bHasContext = true;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
this.attachEventOnce(
|
|
156
|
+
"pageReady",
|
|
157
|
+
null,
|
|
158
|
+
() => {
|
|
159
|
+
this._bAfterBindingAlreadyApplied = false;
|
|
160
|
+
this.queryWatcher.reset();
|
|
161
|
+
},
|
|
162
|
+
null
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
const aTableChartInitializedPromises = this.registerAggregatedControls(oBindingContext);
|
|
166
|
+
|
|
167
|
+
if (aTableChartInitializedPromises.length > 0) {
|
|
168
|
+
Promise.all(aTableChartInitializedPromises)
|
|
169
|
+
.finally(() => {
|
|
170
|
+
this.bTablesChartsLoaded = true;
|
|
171
|
+
this.checkPageReadyDebounced();
|
|
172
|
+
})
|
|
173
|
+
.catch((oError) => {
|
|
174
|
+
Log.info("There was an error with one or multiple tables or charts", oError);
|
|
175
|
+
});
|
|
258
176
|
}
|
|
259
177
|
}
|
|
260
178
|
|
|
@@ -361,13 +279,13 @@ class PageReadyControllerExtension extends ControllerExtension {
|
|
|
361
279
|
|
|
362
280
|
if (
|
|
363
281
|
this.bShown &&
|
|
364
|
-
this.
|
|
365
|
-
this.
|
|
282
|
+
this.queryWatcher.isDataReceived() !== false &&
|
|
283
|
+
this.bTablesChartsLoaded !== false &&
|
|
366
284
|
(!this.isContextExpected() || this.bHasContext) // Either no context is expected or there is one
|
|
367
285
|
) {
|
|
368
|
-
if (this.
|
|
286
|
+
if (this.queryWatcher.isDataReceived() === true && !bFromNav && !this._bWaitingForRefresh && Core.getUIDirty()) {
|
|
369
287
|
// If we requested data we get notified as soon as the data arrived, so before the next rendering tick
|
|
370
|
-
this.
|
|
288
|
+
this.queryWatcher.resetDataReceived();
|
|
371
289
|
this._bWaitingForRefresh = true;
|
|
372
290
|
(Core as CoreEx).attachEvent("UIUpdated", fnUIUpdated);
|
|
373
291
|
setTimeout(checkUIUpdated, 500);
|
|
@@ -375,7 +293,7 @@ class PageReadyControllerExtension extends ControllerExtension {
|
|
|
375
293
|
(!this._bWaitingForRefresh && Core.getUIDirty()) ||
|
|
376
294
|
this._nbWaits !== 0 ||
|
|
377
295
|
TemplatedViewServiceFactory.getNumberOfViewsInCreationState() > 0 ||
|
|
378
|
-
this.
|
|
296
|
+
this.queryWatcher.isSearchPending()
|
|
379
297
|
) {
|
|
380
298
|
this._bWaitingForRefresh = true;
|
|
381
299
|
(Core as CoreEx).attachEvent("UIUpdated", fnUIUpdated);
|