@sapui5/sap.suite.ui.generic.template 1.120.44 → 1.120.45

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sapui5/sap.suite.ui.generic.template",
3
- "version": "1.120.44",
3
+ "version": "1.120.45",
4
4
  "description": "SAPUI5 Library sap.suite.ui.generic.template",
5
5
  "keywords": [
6
6
  "sapui5",
@@ -7,7 +7,7 @@
7
7
 
8
8
  (c) Copyright 2009-2015 SAP SE. All rights reserved
9
9
  </copyright>
10
- <version>1.120.44</version>
10
+ <version>1.120.45</version>
11
11
 
12
12
  <documentation>Library with generic Suite UI templates.</documentation>
13
13
 
@@ -8,7 +8,7 @@
8
8
  "i18n": "i18n/i18n.properties",
9
9
  "applicationVersion": {
10
10
  "__comment": "applicationVersion oder componentversion??",
11
- "version": "1.120.44"
11
+ "version": "1.120.45"
12
12
  },
13
13
  "title": "{{TITLE}}",
14
14
  "description": "{{DESCRIPTION}}",
@@ -8,7 +8,7 @@
8
8
  "i18n": "i18n/i18n.properties",
9
9
  "applicationVersion": {
10
10
  "__comment": "applicationVersion oder componentversion??",
11
- "version": "1.120.44"
11
+ "version": "1.120.45"
12
12
  },
13
13
  "title": "Canvas",
14
14
  "description": "Canvas Page",
@@ -16,23 +16,23 @@ sap.ui.define([
16
16
  "sap/suite/ui/generic/template/genericUtilities/testableHelper",
17
17
  "sap/suite/ui/generic/template/js/StableIdHelper",
18
18
  "sap/suite/ui/generic/template/genericUtilities/utils"
19
- ], function(BaseObject, ControllerExtension, NavError, listUtils, SelectionVariant, UIState, FeLogger, deepEqual, extend,
20
- isEmptyObject, FeError, Device, semanticDateRangeTypeHelper, LegacyStateHandler, testableHelper, StableIdHelper, Utils) {
19
+ ], function (BaseObject, ControllerExtension, NavError, listUtils, SelectionVariant, UIState, FeLogger, deepEqual, extend,
20
+ isEmptyObject, FeError, Device, semanticDateRangeTypeHelper, LegacyStateHandler, testableHelper, StableIdHelper, Utils) {
21
21
  "use strict";
22
22
 
23
- var sClassName = "ListReport.controller.IappStateHandler";
23
+ var sClassName = "ListReport.controller.IappStateHandler";
24
24
  var oFeLogger = new FeLogger(sClassName);
25
25
  var oLogger = oFeLogger.getLogger();
26
26
  var oLevel = oFeLogger.Level;
27
27
  // Constants which are used as property names for storing custom filter data and generic filter data
28
28
  var dataPropertyNameCustom = "sap.suite.ui.generic.template.customData",
29
- dataPropertyNameExtension = "sap.suite.ui.generic.template.extensionData",
30
- dataPropertyNameGeneric = "sap.suite.ui.generic.template.genericData";
29
+ dataPropertyNameExtension = "sap.suite.ui.generic.template.extensionData",
30
+ dataPropertyNameGeneric = "sap.suite.ui.generic.template.genericData";
31
31
  // Array contains URL parameters that should be ignored and trigger app initialization as only
32
32
  // default parameters were passed
33
33
  var aIgnoreURLParameters = ["save-appvar-id"];
34
34
 
35
- function fnLogInfo(sMessage, vDetails){
35
+ function fnLogInfo(sMessage, vDetails) {
36
36
  if (sap.ui.support) { //only if support assistant is loaded
37
37
  var iLevel = oLogger.getLevel();
38
38
  if (iLevel < oLevel.INFO) {
@@ -40,12 +40,12 @@ sap.ui.define([
40
40
  }
41
41
  }
42
42
  var sDetails;
43
- if (typeof vDetails === "string"){
43
+ if (typeof vDetails === "string") {
44
44
  sDetails = vDetails;
45
45
  } else {
46
46
  sDetails = "";
47
47
  var sDelim = "";
48
- for (var sKey in vDetails){
48
+ for (var sKey in vDetails) {
49
49
  sDetails = sDetails + sDelim + sKey + ": " + vDetails[sKey];
50
50
  sDelim = "; ";
51
51
  }
@@ -60,10 +60,15 @@ sap.ui.define([
60
60
  // don't apply any results from appstate analysis to SFB before this event
61
61
  // -> should actually be handled by (wrapper for) SFB
62
62
  var onSmartFilterBarInitialized;
63
- var oSmartFilterBarInitializedPromise = new Promise(function(fnResolve){
63
+ var oSmartFilterBarInitializedPromise = new Promise(function (fnResolve) {
64
64
  onSmartFilterBarInitialized = fnResolve;
65
65
  });
66
66
 
67
+ // Resolve this only after the FE initializes all the filter values from different sources
68
+ var onFEStartupInitializedResolver;
69
+ var onFEStartupInitializedPromise = new Promise(function (fnResolve) {
70
+ onFEStartupInitializedResolver = fnResolve;
71
+ });
67
72
  // *** setup wrappers for control states (start)
68
73
 
69
74
 
@@ -83,21 +88,27 @@ sap.ui.define([
83
88
  // storing/restoring their states (in its part of the appState stored in genericData.tableTabData)
84
89
  // In this case, mutliViewsHandler exchanges oState.oPresentationControlHandler (setting it always to the current visible one), so don't rely on that to get the wrapper.
85
90
  // Using the id (without providing optional parameter sQuickVariantKey) returns the smartTable only in single table case.
86
- var oSmartTable = oController.byId(StableIdHelper.getStableId({type: "ListReportTable", subType: "SmartTable"}));
87
- if (oSmartTable){ // in multipleViews case (with multiple tables) currently multipleViews handler handles complete state information
91
+ var oSmartTable = oController.byId(StableIdHelper.getStableId({
92
+ type: "ListReportTable",
93
+ subType: "SmartTable"
94
+ }));
95
+ if (oSmartTable) { // in multipleViews case (with multiple tables) currently multipleViews handler handles complete state information
88
96
  aControlStateWrappers.push(oTemplateUtils.oCommonUtils.getControlStateWrapper(oSmartTable));
89
97
  }
90
98
 
91
99
  // SearchField state: Value of searchfield
92
100
  // Exists only in case of worklist. In case of worklist with multiple views with multiple tables, same is true as for SmartTable
93
- var oSearchField = oController.byId(StableIdHelper.getStableId({type: "ListReportAction", subType: "SearchField"}));
94
- if (oSearchField){
101
+ var oSearchField = oController.byId(StableIdHelper.getStableId({
102
+ type: "ListReportAction",
103
+ subType: "SearchField"
104
+ }));
105
+ if (oSearchField) {
95
106
  aControlStateWrappers.push(oTemplateUtils.oCommonUtils.getControlStateWrapper(oSearchField));
96
107
  }
97
108
 
98
109
  var oMultipleViewsGeneralContentStateWrapper = oState.oMultipleViewsHandler.getGeneralContentStateWrapper();
99
- if (oMultipleViewsGeneralContentStateWrapper){
100
- oMultipleViewsGeneralContentStateWrapper.getLocalId = function(){
110
+ if (oMultipleViewsGeneralContentStateWrapper) {
111
+ oMultipleViewsGeneralContentStateWrapper.getLocalId = function () {
101
112
  return "$multipleViewsGeneralContent";
102
113
  };
103
114
  aControlStateWrappers.push(oMultipleViewsGeneralContentStateWrapper);
@@ -106,7 +117,7 @@ sap.ui.define([
106
117
  // state information not belonging to the SFB needs to be added to the variant management, if page variant management is used (setting smartVariantManagment) and not
107
118
  // hidden (setting variantManagementHidden) - otherwise, it needs to be stored directly in the appState
108
119
 
109
- if (oController.getOwnerComponent().getSmartVariantManagement() && !oController.getOwnerComponent().getVariantManagementHidden()){
120
+ if (oController.getOwnerComponent().getSmartVariantManagement() && !oController.getOwnerComponent().getVariantManagementHidden()) {
110
121
  // if no page variant management or page variant hidden, everything up to here is stored directly in the iAppState (only). In that case, only SFBs state is relevant for
111
122
  // variant managment
112
123
  aPageVariantControlStateWrappers = aControlStateWrappers;
@@ -114,8 +125,8 @@ sap.ui.define([
114
125
  }
115
126
 
116
127
  var oMultipleViewsSFBVariantContentStateWrapper = oState.oMultipleViewsHandler.getSFBVariantContentStateWrapper();
117
- if (oMultipleViewsSFBVariantContentStateWrapper){
118
- oMultipleViewsSFBVariantContentStateWrapper.getLocalId = function(){
128
+ if (oMultipleViewsSFBVariantContentStateWrapper) {
129
+ oMultipleViewsSFBVariantContentStateWrapper.getLocalId = function () {
119
130
  return "$multipleViewsSFBVariantContent";
120
131
  };
121
132
  aPageVariantControlStateWrappers.push(oMultipleViewsSFBVariantContentStateWrapper);
@@ -124,83 +135,86 @@ sap.ui.define([
124
135
  // List of handlers to react on (app or adaptation) extension state changes. Only one entry expected (handler in SFB wrapper). Currently, extensions are only possible in
125
136
  // SFB - if extensions at other places are needed, the similar handler might differ depending on whether page variant management is used.
126
137
  var aExtensionStateChangeHandlers = [];
138
+
127
139
  function customAppStateChange() {
128
- aExtensionStateChangeHandlers.forEach(function(fnHandler) {
140
+ aExtensionStateChangeHandlers.forEach(function (fnHandler) {
129
141
  fnHandler();
130
142
  });
131
143
  }
132
144
 
133
145
  var oCustomFiltersWrapper = {
134
- getLocalId: function(){
135
- return "$customFilters";
136
- },
137
- getState: function(){
138
- var oState = {
139
- appExtension: Object.create(null),
140
- adaptationExtensions: Object.create(null) // collects all extension state information (as map extension-namespace -> state). Initialized on demand
141
- };
142
-
143
- if (oTemplateUtils.oComponentUtils.isDraftEnabled()){
144
- var oTemplatePrivateModel = oTemplateUtils.oComponentUtils.getTemplatePrivateModel();
145
- oState.editState = oTemplatePrivateModel.getProperty("/listReport/vDraftState");
146
- }
147
-
148
- oController.getCustomAppStateDataExtension(oState.appExtension);
146
+ getLocalId: function () {
147
+ return "$customFilters";
148
+ },
149
+ getState: function () {
150
+ var oState = {
151
+ appExtension: Object.create(null),
152
+ adaptationExtensions: Object.create(null) // collects all extension state information (as map extension-namespace -> state). Initialized on demand
153
+ };
154
+
155
+ if (oTemplateUtils.oComponentUtils.isDraftEnabled()) {
156
+ var oTemplatePrivateModel = oTemplateUtils.oComponentUtils.getTemplatePrivateModel();
157
+ oState.editState = oTemplatePrivateModel.getProperty("/listReport/vDraftState");
158
+ }
149
159
 
150
- var bIsAllowed = true; // check for synchronous calls
151
- // the following function will be passed to all extensions. It gives them the possibility to provide their state as oAppState
152
- // Therefore, they must identify themselves via their instance of ControllerExtension.
153
- var fnSetSingleAdaptationExtensionState = function(oControllerExtension, oSingleAdaptationExtensionState){
154
- if (!(oControllerExtension instanceof ControllerExtension)){
155
- throw new FeError(sClassName, "State must always be set with respect to a ControllerExtension");
156
- }
157
- if (!bIsAllowed){
158
- throw new FeError(sClassName, "State must always be provided synchronously");
159
- }
160
- oState.adaptationExtensions[oControllerExtension.getMetadata().getNamespace()] = oSingleAdaptationExtensionState;
161
- };
162
- oController.templateBaseExtension.provideExtensionAppStateData(fnSetSingleAdaptationExtensionState);
163
- bIsAllowed = false;
160
+ oController.getCustomAppStateDataExtension(oState.appExtension);
164
161
 
165
- return oState;
166
- },
167
- setState: function(oState){
168
- if (oTemplateUtils.oComponentUtils.isDraftEnabled()){
169
- var oTemplatePrivateModel = oTemplateUtils.oComponentUtils.getTemplatePrivateModel();
170
- oTemplatePrivateModel.setProperty("/listReport/vDraftState", oState.editState);
162
+ var bIsAllowed = true; // check for synchronous calls
163
+ // the following function will be passed to all extensions. It gives them the possibility to provide their state as oAppState
164
+ // Therefore, they must identify themselves via their instance of ControllerExtension.
165
+ var fnSetSingleAdaptationExtensionState = function (oControllerExtension, oSingleAdaptationExtensionState) {
166
+ if (!(oControllerExtension instanceof ControllerExtension)) {
167
+ throw new FeError(sClassName, "State must always be set with respect to a ControllerExtension");
171
168
  }
169
+ if (!bIsAllowed) {
170
+ throw new FeError(sClassName, "State must always be provided synchronously");
171
+ }
172
+ oState.adaptationExtensions[oControllerExtension.getMetadata().getNamespace()] = oSingleAdaptationExtensionState;
173
+ };
174
+ oController.templateBaseExtension.provideExtensionAppStateData(fnSetSingleAdaptationExtensionState);
175
+ bIsAllowed = false;
176
+
177
+ return oState;
178
+ },
179
+ setState: function (oState) {
180
+ if (oTemplateUtils.oComponentUtils.isDraftEnabled()) {
181
+ var oTemplatePrivateModel = oTemplateUtils.oComponentUtils.getTemplatePrivateModel();
182
+ oTemplatePrivateModel.setProperty("/listReport/vDraftState", oState.editState);
183
+ }
172
184
 
173
- oController.restoreCustomAppStateDataExtension(oState.appExtension);
185
+ oController.restoreCustomAppStateDataExtension(oState.appExtension);
174
186
 
175
- var bIsAllowed = true; // check for synchronous calls
176
- // the following function will be passed to all extensions. It gives them the possibility to retrieve their state.
177
- // Therefore, they must identify themselves via their instance of ControllerExtension.
178
- var fnGetSingleAdaptationExtensionState = function(oControllerExtension){
179
- if (!(oControllerExtension instanceof ControllerExtension)){
180
- throw new FeError(sClassName, "State must always be retrieved with respect to a ControllerExtension");
181
- }
182
- if (!bIsAllowed){
183
- throw new FeError(sClassName, "State must always be restored synchronously");
184
- }
185
- return oState.adaptationExtensions[oControllerExtension.getMetadata().getNamespace()];
186
- };
187
- oController.templateBaseExtension.restoreExtensionAppStateData(fnGetSingleAdaptationExtensionState);
188
- bIsAllowed = false;
189
- },
190
- attachStateChanged: function(fnHandler){
191
- if (oController.byId("editStateFilter")){
192
- // Remark:
193
- // - checking for isDraftEnabled is not enough - if filtering on draft is not supported, editStateFilter would also not be created
194
- // - Cleaner from architectural point of view, but not strictly needed, as SFB registers for the same event and fires filterChanged
195
- oController.byId("editStateFilter").attachChange(fnHandler);
187
+ var bIsAllowed = true; // check for synchronous calls
188
+ // the following function will be passed to all extensions. It gives them the possibility to retrieve their state.
189
+ // Therefore, they must identify themselves via their instance of ControllerExtension.
190
+ var fnGetSingleAdaptationExtensionState = function (oControllerExtension) {
191
+ if (!(oControllerExtension instanceof ControllerExtension)) {
192
+ throw new FeError(sClassName, "State must always be retrieved with respect to a ControllerExtension");
196
193
  }
197
- // For extensionFilters, registration is needed for extension using controls not known to the SFB implementation (which is a fundamental purpose of extension!)
198
- // Same is valid for appExtensions and adaptationExtensions.
199
- aExtensionStateChangeHandlers.push(fnHandler);
194
+ if (!bIsAllowed) {
195
+ throw new FeError(sClassName, "State must always be restored synchronously");
196
+ }
197
+ return oState.adaptationExtensions[oControllerExtension.getMetadata().getNamespace()];
198
+ };
199
+ oController.templateBaseExtension.restoreExtensionAppStateData(fnGetSingleAdaptationExtensionState);
200
+ bIsAllowed = false;
201
+ },
202
+ attachStateChanged: function (fnHandler) {
203
+ if (oController.byId("editStateFilter")) {
204
+ // Remark:
205
+ // - checking for isDraftEnabled is not enough - if filtering on draft is not supported, editStateFilter would also not be created
206
+ // - Cleaner from architectural point of view, but not strictly needed, as SFB registers for the same event and fires filterChanged
207
+ oController.byId("editStateFilter").attachChange(fnHandler);
200
208
  }
209
+ // For extensionFilters, registration is needed for extension using controls not known to the SFB implementation (which is a fundamental purpose of extension!)
210
+ // Same is valid for appExtensions and adaptationExtensions.
211
+ aExtensionStateChangeHandlers.push(fnHandler);
212
+ }
201
213
  };
202
214
 
203
- var oSmartFilterBarWrapper = oTemplateUtils.oCommonUtils.getControlStateWrapper(oState.oSmartFilterbar, {oCustomFiltersWrapper: oCustomFiltersWrapper});
215
+ var oSmartFilterBarWrapper = oTemplateUtils.oCommonUtils.getControlStateWrapper(oState.oSmartFilterbar, {
216
+ oCustomFiltersWrapper: oCustomFiltersWrapper
217
+ });
204
218
 
205
219
  // theoretically, SFB's state is part of VM. But due to the direct connection between SFB and SVM, applying a variant would lead to an endless loop (selection variant as
206
220
  // part of UiState object applied to SFB also contains a variant id, which is then applied to SVM). The same connection ensures that the part of SFB's state known to the SFB
@@ -216,7 +230,7 @@ sap.ui.define([
216
230
  // SVM side (which is cleaner architecture, as the SVM rather manages the SFB)
217
231
  // - Here, only the connection is established. All workarounds needed due to the broken connection should be build into the wrappers
218
232
  var oSmartVariantManagement = oState.oSmartFilterbar.getSmartVariant();
219
- if (oSmartVariantManagement){
233
+ if (oSmartVariantManagement) {
220
234
  var oSmartVariantManagementWrapper = oTemplateUtils.oCommonUtils.getControlStateWrapper(oSmartVariantManagement, {
221
235
  managedControlWrappers: aPageVariantControlStateWrappers.concat([oSmartFilterBarWrapper]),
222
236
  smartFilterBarWrapper: oSmartFilterBarWrapper
@@ -227,7 +241,10 @@ sap.ui.define([
227
241
  }
228
242
 
229
243
  // DynamicPage state: header pinned
230
- var oDynamicPage = oController.byId(StableIdHelper.getStableId({type: "ListReportPage", subType: "DynamicPage"}));
244
+ var oDynamicPage = oController.byId(StableIdHelper.getStableId({
245
+ type: "ListReportPage",
246
+ subType: "DynamicPage"
247
+ }));
231
248
  // The DynamicPage state (header pinned) is intentionally stored only in iAppState and not included in any variant (neither page variant nor SFB variant).
232
249
  var oDynamicPageWrapper = oTemplateUtils.oCommonUtils.getControlStateWrapper(oDynamicPage);
233
250
  aControlStateWrappers.push(oDynamicPageWrapper);
@@ -235,7 +252,7 @@ sap.ui.define([
235
252
 
236
253
  // Wrapper to control whether data is loaded
237
254
 
238
- function fnGetDataLoadedWrapper(){
255
+ function fnGetDataLoadedWrapper() {
239
256
  // Wrapper to control whether data is expected to be loaded - controls the state, but does not trigger loading data on restore!
240
257
  var oTemplatePrivateModel = oTemplateUtils.oComponentUtils.getTemplatePrivateModel();
241
258
  // initial state:
@@ -243,16 +260,16 @@ sap.ui.define([
243
260
  // - other startup cases: applyInitialLoadBehavior calls setState explicitly
244
261
  // - navigation
245
262
 
246
- function fnSetState(bState){
263
+ function fnSetState(bState) {
247
264
  oTemplatePrivateModel.setProperty("/generic/bDataAreShownInTable", bState);
248
265
  }
249
266
 
250
- function fnGetState(){
267
+ function fnGetState() {
251
268
  return oTemplatePrivateModel.getProperty("/generic/bDataAreShownInTable");
252
269
  }
253
270
 
254
- function fnSetDataShown(bDataShown, fnHandler){
255
- if (bDataShown === fnGetState()){
271
+ function fnSetDataShown(bDataShown, fnHandler) {
272
+ if (bDataShown === fnGetState()) {
256
273
  return;
257
274
  }
258
275
  fnSetState(bDataShown);
@@ -260,12 +277,12 @@ sap.ui.define([
260
277
  }
261
278
 
262
279
  return {
263
- getLocalId: function(){
280
+ getLocalId: function () {
264
281
  return "$dataLoaded";
265
282
  },
266
283
  setState: fnSetState,
267
284
  getState: fnGetState,
268
- attachStateChanged: function(fnHandler){
285
+ attachStateChanged: function (fnHandler) {
269
286
  // changing from data not loaded to data loaded:
270
287
  // - when SFB triggers search
271
288
  oState.oSmartFilterbar.attachSearch(fnSetDataShown.bind(null, true, fnHandler));
@@ -277,6 +294,10 @@ sap.ui.define([
277
294
  // pro: - also for custom filters (the SFB does not know about)
278
295
  // - not when applying state to SFB
279
296
  // contra: could there be other changes from SFB?
297
+ // Note: this event also fires during iAppState restore when SVM applies a variant
298
+ // asynchronously via setCurrentVariantId, unintentionally resetting $dataLoaded
299
+ // to false. Therefore fnAdaptToAppStateIappState explicitly re-applies the saved
300
+ // $dataLoaded value after all wrappers have settled via Promise.all.
280
301
  oState.oSmartFilterbar.attachFilterChange(fnSetDataShown.bind(null, false, fnHandler));
281
302
  }
282
303
  };
@@ -284,10 +305,10 @@ sap.ui.define([
284
305
 
285
306
  var oDataLoadedWrapper = fnGetDataLoadedWrapper();
286
307
  aControlStateWrappers.push(oDataLoadedWrapper);
287
- // oDataLoadedWrapper.attachStateChanged(changeIappState);
308
+ // oDataLoadedWrapper.attachStateChanged(changeIappState);
288
309
 
289
310
  // attach to change event of all wrappers handled directly - others should be propagated through the managing control wrapper (currently a SmartVariantManagementWrapper)
290
- aControlStateWrappers.forEach(function(oWrapper){
311
+ aControlStateWrappers.forEach(function (oWrapper) {
291
312
  oWrapper.attachStateChanged(changeIappState);
292
313
  });
293
314
 
@@ -307,22 +328,22 @@ sap.ui.define([
307
328
  oDataLoadedWrapper.setState(bDataShown);
308
329
  }
309
330
 
310
- function areDataShownInTable(){
331
+ function areDataShownInTable() {
311
332
  var oTemplatePrivateModel = oTemplateUtils.oComponentUtils.getTemplatePrivateModel();
312
333
  return oTemplatePrivateModel.getProperty("/generic/bDataAreShownInTable");
313
334
  }
314
335
 
315
336
  // trigger loading data
316
337
  // This method is NOT intended to do any checks to analyze, whether loading data is actually needed - that should be done before
317
- function loadData(){
338
+ function loadData() {
318
339
  oState.oSmartFilterbar.search();
319
340
  }
320
341
 
321
342
  function getCurrentAppState() {
322
343
 
323
344
  var mControlStates = {};
324
- aControlStateWrappers.forEach(function(oWrapper){
325
- if (oWrapper.getLocalId()){
345
+ aControlStateWrappers.forEach(function (oWrapper) {
346
+ if (oWrapper.getLocalId()) {
326
347
  mControlStates[oWrapper.getLocalId()] = oWrapper.getState();
327
348
  }
328
349
  });
@@ -352,13 +373,14 @@ sap.ui.define([
352
373
  }
353
374
  } else {
354
375
  var aPageVariantId = oNewUrlParameters['sap-ui-fe-variant-id'],
355
- aFilterBarVariantId = oNewUrlParameters['sap-ui-fe-filterbar-variant-id'],
356
- aChartVariantId = oNewUrlParameters['sap-ui-fe-chart-variant-id'],
357
- aTableVariantId = oNewUrlParameters['sap-ui-fe-table-variant-id'];
376
+ aFilterBarVariantId = oNewUrlParameters['sap-ui-fe-filterbar-variant-id'],
377
+ aChartVariantId = oNewUrlParameters['sap-ui-fe-chart-variant-id'],
378
+ aTableVariantId = oNewUrlParameters['sap-ui-fe-table-variant-id'];
358
379
 
359
380
  applyControlVariantId(aFilterBarVariantId && aFilterBarVariantId[0], aChartVariantId && aChartVariantId[0], aTableVariantId && aTableVariantId[0], aPageVariantId && aPageVariantId[0]);
360
381
  }
361
382
  }
383
+
362
384
  function applyControlVariantId(sFilterBarVariantId, sChartVariantId, sTableVariantId, sPageVariantId) {
363
385
  if (sFilterBarVariantId || sPageVariantId) {
364
386
  oSmartVariantManagement.setCurrentVariantId(sFilterBarVariantId || sPageVariantId);
@@ -382,7 +404,7 @@ sap.ui.define([
382
404
  // - Collapse of filter bar once user press Go (only for phone device)
383
405
  function onSearchPressed() {
384
406
  // if SFB does not allow search, no need to adapt anything
385
- if (!oState.oSmartFilterbar.checkSearchAllowed()){
407
+ if (!oState.oSmartFilterbar.checkSearchAllowed()) {
386
408
  return;
387
409
  }
388
410
  oState.refreshModel();
@@ -402,7 +424,7 @@ sap.ui.define([
402
424
 
403
425
  // It is responsible for:
404
426
  // - triggering the creation of a new appState
405
- function changeIappState(){
427
+ function changeIappState() {
406
428
  fnLogInfo("changeIappState called", {
407
429
  bDataAreShownInTable: areDataShownInTable()
408
430
  });
@@ -415,16 +437,16 @@ sap.ui.define([
415
437
 
416
438
  /*
417
439
  The function is to add default values in Display Currency parameter if it is not there in the Selection Variant
418
- @param {object} Selection Variant
440
+ @param {object} Selection Variant
419
441
  ` @param {object} App data
420
442
  */
421
443
  function addDisplayCurrency(oAppData) {
422
444
  var aMandatoryFilterItems = oState.oSmartFilterbar.determineMandatoryFilterItems(),
423
- sDisplayCurrency;
445
+ sDisplayCurrency;
424
446
  for (var item = 0; item < aMandatoryFilterItems.length; item++) {
425
447
  if (aMandatoryFilterItems[item].getName().indexOf("P_DisplayCurrency") !== -1) {
426
- if (oAppData.oDefaultedSelectionVariant.getSelectOption("DisplayCurrency") && oAppData.oDefaultedSelectionVariant.getSelectOption("DisplayCurrency")[0]
427
- && oAppData.oDefaultedSelectionVariant.getSelectOption("DisplayCurrency")[0].Low) {
448
+ if (oAppData.oDefaultedSelectionVariant.getSelectOption("DisplayCurrency") && oAppData.oDefaultedSelectionVariant.getSelectOption("DisplayCurrency")[0] &&
449
+ oAppData.oDefaultedSelectionVariant.getSelectOption("DisplayCurrency")[0].Low) {
428
450
  sDisplayCurrency = oAppData.oDefaultedSelectionVariant.getSelectOption("DisplayCurrency")[0].Low;
429
451
  if (sDisplayCurrency) {
430
452
  oAppData.oSelectionVariant.addParameter("P_DisplayCurrency", sDisplayCurrency);
@@ -449,28 +471,39 @@ sap.ui.define([
449
471
  oState.oPresentationControlHandler.applyNavigationSortOrder(aNavigationSortOrder);
450
472
  }
451
473
 
452
- function fnAdaptToAppStateIappState(oAppData){
453
-
474
+ function fnAdaptToAppStateIappState(oAppData) {
475
+ // Save $dataLoaded value upfront before any wrappers run.
476
+ // This is needed because the SVM wrapper applies its variant asynchronously
477
+ // (via oAllControlsInitializedPromise). When it resolves, fnSetVariant calls
478
+ // setCurrentVariantId which triggers SFB's filterChange event. oDataLoadedWrapper
479
+ // is attached to filterChange and resets bDataAreShownInTable to false — overwriting
480
+ // the value that was correctly restored from iAppState. Re-applying it explicitly
481
+ // after the microtask ensures the saved value wins after all synchronous activity
482
+ // settles, without depending on the full SVM async promise chain which may not
483
+ // resolve in test environments (OPA).
484
+ var bDataLoaded = oAppData.controlStates && oAppData.controlStates["$dataLoaded"];
454
485
  fnAdaptOtherControlsToAppState(oAppData.controlStates);
455
- if (areDataShownInTable() && Object.keys(oState.oSmartFilterbar.verifySearchAllowed()).length === 0){
486
+ Promise.resolve().then(function() {
487
+ oDataLoadedWrapper.setState(bDataLoaded);
488
+ if (areDataShownInTable() && Object.keys(oState.oSmartFilterbar.verifySearchAllowed()).length === 0) {
456
489
  // fnAdaptOtherControlsToAppState only (synchronously) sets the state including the information whether data should be loaded and search is allowed,- if this is the case, the actual loading
457
490
  // (which happens asynchronous of course) still needs to be triggered
458
491
  loadData();
459
- } else {
460
- // hide placeholder already here, if no data is to be loaded - in case data is loaded, it will be hidden in data received event
461
- oTemplateUtils.oComponentUtils.hidePlaceholder();
462
- }
463
-
464
- // special case: when restoring an old app state with data loaded, but in the meantime a filter not set in that state has been changed to mandatory, SFB.search would not
465
- // trigger a request (but instead only mark that filter) - thus hiding placeholder now to avoid it to stay forever
466
- // TODO: refactor: Still in that case our internal data shows data are loaded - ideally, that should not be the case
467
- if (!oState.oSmartFilterbar.checkSearchAllowed()){
468
- oTemplateUtils.oComponentUtils.hidePlaceholder();
469
- }
492
+ } else {
493
+ // hide placeholder already here, if no data is to be loaded - in case data is loaded, it will be hidden in data received event
494
+ oTemplateUtils.oComponentUtils.hidePlaceholder();
495
+ }
470
496
 
497
+ // special case: when restoring an old app state with data loaded, but in the meantime a filter not set in that state has been changed to mandatory, SFB.search would not
498
+ // trigger a request (but instead only mark that filter) - thus hiding placeholder now to avoid it to stay forever
499
+ // TODO: refactor: Still in that case our internal data shows data are loaded - ideally, that should not be the case
500
+ if (!oState.oSmartFilterbar.checkSearchAllowed()) {
501
+ oTemplateUtils.oComponentUtils.hidePlaceholder();
502
+ }
503
+ });
471
504
  }
472
505
 
473
- function fnAdaptToAppStateNavigation(oAppData, oURLParameters, sPreferredQuickVariantSelectionKey){
506
+ function fnAdaptToAppStateNavigation(oAppData, oURLParameters, sPreferredQuickVariantSelectionKey) {
474
507
  handleVariantIdPassedViaURLParams(oURLParameters);
475
508
  handleEditingStatusFilterPassedViaURLParams(oURLParameters);
476
509
  //Apply sort order coming from the XAppState to the smart table.
@@ -481,12 +514,12 @@ sap.ui.define([
481
514
  addDisplayCurrency(oAppData);
482
515
  }
483
516
  var oStartupObject = {
484
- viaExternalNavigation: true,
485
- selectionVariant: oAppData.oSelectionVariant,
486
- urlParameters: oURLParameters,
487
- selectedQuickVariantSelectionKey: sPreferredQuickVariantSelectionKey,
488
- // incase semantic date field is present, parseNavigation returns semanticDates in stringified format and otherwise an empty object
489
- semanticDates: (typeof oAppData.semanticDates === "string" ? JSON.parse(oAppData.semanticDates) : oAppData.semanticDates) || {}
517
+ viaExternalNavigation: true,
518
+ selectionVariant: oAppData.oSelectionVariant,
519
+ urlParameters: oURLParameters,
520
+ selectedQuickVariantSelectionKey: sPreferredQuickVariantSelectionKey,
521
+ // incase semantic date field is present, parseNavigation returns semanticDates in stringified format and otherwise an empty object
522
+ semanticDates: (typeof oAppData.semanticDates === "string" ? JSON.parse(oAppData.semanticDates) : oAppData.semanticDates) || {}
490
523
  };
491
524
  // if there is a navigation from external application to worklist,
492
525
  // the filters from external application should not be applied since the worklist does not show smartfilterbar
@@ -500,7 +533,7 @@ sap.ui.define([
500
533
  oStartupObject.semanticDates = semanticDateRangeTypeHelper.addSemanticDateRangeDefaultValue(oSettings, oState.oSmartFilterbar, oStartupObject.semanticDates, oStartupObject.urlParameters || {}, oStartupObject.selectionVariant, true);
501
534
  // Smart filter bar all the filters will be replaced by the one which are coming from oUiState build base of oSelectionVariant where the Semantic Date Default Values
502
535
  // is missing and because of that the values are replaced. Hence adding the semantic Dates to oSelectionVariant as mentioned by the Smart Control Colleague in the mentioned BCP
503
- oStartupObject.semanticDates.Dates.forEach(function(oSelectDateOption){
536
+ oStartupObject.semanticDates.Dates.forEach(function (oSelectDateOption) {
504
537
  oStartupObject.selectionVariant.addSelectOption(oSelectDateOption.PropertyName, "I", "EQ", "");
505
538
  });
506
539
  }
@@ -514,21 +547,21 @@ sap.ui.define([
514
547
 
515
548
  // In navigation case, data should be loaded in general unless variant is provided in navigation parameters - in that case, setting of that variant should win.
516
549
  // Remark: Implemented logic does not fully reflect this: If navigation parameter exists but points to the standard variant, still the initial startup logic applies.
517
- applyInitialLoadBehavior(/* bDataLoadCausedByNavigation = */ oState.oSmartFilterbar.isCurrentVariantStandard());
550
+ applyInitialLoadBehavior( /* bDataLoadCausedByNavigation = */ oState.oSmartFilterbar.isCurrentVariantStandard());
518
551
  }
519
552
 
520
553
 
521
- function fnAdaptToAppStateStartUpInitial(oURLParameters, sPreferredQuickVariantSelectionKey){
554
+ function fnAdaptToAppStateStartUpInitial(oURLParameters, sPreferredQuickVariantSelectionKey) {
522
555
  handleVariantIdPassedViaURLParams(oURLParameters);
523
556
 
524
557
  //oStartupObject to be passed to the extension where urlParameters and selectedQuickVariantSelectionKey are optional
525
558
  var oStartupObject = {
526
- viaExternalNavigation: false,
527
- selectionVariant: "",
528
- urlParameters: oURLParameters, // can only contain "technical" parameters (starting with "sap-")
529
- selectedQuickVariantSelectionKey: sPreferredQuickVariantSelectionKey,
530
- // in case semantic date field is present, parseNavigation returns semanticDates in stringified format and otherwise an empty object
531
- semanticDates: {}
559
+ viaExternalNavigation: false,
560
+ selectionVariant: "",
561
+ urlParameters: oURLParameters, // can only contain "technical" parameters (starting with "sap-")
562
+ selectedQuickVariantSelectionKey: sPreferredQuickVariantSelectionKey,
563
+ // in case semantic date field is present, parseNavigation returns semanticDates in stringified format and otherwise an empty object
564
+ semanticDates: {}
532
565
  };
533
566
  var oSFBUiState = oState.oSmartFilterbar.getUiState();
534
567
  var oSFBSelectionVariant = new SelectionVariant(JSON.stringify(oSFBUiState.getSelectionVariant()));
@@ -568,7 +601,7 @@ sap.ui.define([
568
601
 
569
602
  // Smart filter bar all the filters will be replaced by the one which are coming from oUiState build base of oSelectionVariant where the Semantic Date Default Values
570
603
  // is missing and because of that the values are replaced. Hence adding the semantic Dates to oSelectionVariant as mentioned by the Smart Control Colleague in the mentioned BCP
571
- oStartupObject.semanticDates.Dates.forEach(function(oSelectDateOption){
604
+ oStartupObject.semanticDates.Dates.forEach(function (oSelectDateOption) {
572
605
  oStartupObject.selectionVariant.addSelectOption(oSelectDateOption.PropertyName, "I", "EQ", "");
573
606
  });
574
607
  }
@@ -584,32 +617,32 @@ sap.ui.define([
584
617
  }
585
618
 
586
619
  //Startup semantic date will be priortised in case of collision
587
- function fnMergeSemanticDates(aSFBSemanticDate, aStartupSemanticDate){
620
+ function fnMergeSemanticDates(aSFBSemanticDate, aStartupSemanticDate) {
588
621
  var oSemanticDateMap = {};
589
- aSFBSemanticDate.forEach(function(oVal) {
622
+ aSFBSemanticDate.forEach(function (oVal) {
590
623
  oSemanticDateMap[oVal.PropertyName] = oVal;
591
624
  });
592
- aStartupSemanticDate.forEach(function(oVal) {
625
+ aStartupSemanticDate.forEach(function (oVal) {
593
626
  oSemanticDateMap[oVal.PropertyName] = oVal;
594
627
  });
595
628
  return Object.values(oSemanticDateMap);
596
629
  }
597
630
 
598
- function fnAdaptToAppStateStartUpWithParameters(oAppData, oURLParameters, sPreferredQuickVariantSelectionKey){
631
+ function fnAdaptToAppStateStartUpWithParameters(oAppData, oURLParameters, sPreferredQuickVariantSelectionKey) {
599
632
  handleVariantIdPassedViaURLParams(oURLParameters);
600
633
 
601
634
  var oSFBUiState = oState.oSmartFilterbar.getUiState();
602
635
  var oSFBSemanticDates = oSFBUiState.getSemanticDates();
603
636
  //oStartupObject to be passed to the extension where urlParameters and selectedQuickVariantSelectionKey are optional
604
637
  var oStartupObject = {
605
- viaExternalNavigation: false,
606
- selectionVariant: oAppData.oSelectionVariant,
607
- urlParameters: oURLParameters,
608
- selectedQuickVariantSelectionKey: sPreferredQuickVariantSelectionKey,
609
- // In case semantic date field is present, parseNavigation returns semanticDates in stringified format and otherwise an empty object.
610
- // Moreover, if there is no semanticDates retrieved from NavigationHandler, then the existing values of semantic
611
- // dates properties considered by smartfilterbar (from annotation, change handler etc) should be taken into consideration.
612
- semanticDates: (typeof oAppData.semanticDates === "string" ? JSON.parse(oAppData.semanticDates) : oAppData.semanticDates) || {}
638
+ viaExternalNavigation: false,
639
+ selectionVariant: oAppData.oSelectionVariant,
640
+ urlParameters: oURLParameters,
641
+ selectedQuickVariantSelectionKey: sPreferredQuickVariantSelectionKey,
642
+ // In case semantic date field is present, parseNavigation returns semanticDates in stringified format and otherwise an empty object.
643
+ // Moreover, if there is no semanticDates retrieved from NavigationHandler, then the existing values of semantic
644
+ // dates properties considered by smartfilterbar (from annotation, change handler etc) should be taken into consideration.
645
+ semanticDates: (typeof oAppData.semanticDates === "string" ? JSON.parse(oAppData.semanticDates) : oAppData.semanticDates) || {}
613
646
  };
614
647
  //Apply sort order coming from the XAppState to the smart table.
615
648
  if (oAppData.presentationVariant !== undefined) {
@@ -642,16 +675,16 @@ sap.ui.define([
642
675
  }
643
676
  // Smart filter bar all the filters will be replaced by the one which are coming from oUiState build base of oSelectionVariant where the Semantic Date Default Values
644
677
  // is missing and because of that the values are replaced. Hence adding the semantic Dates to oSelectionVariant as mentioned by the Smart Control Colleague in the mentioned BCP
645
- oStartupObject.semanticDates.Dates.forEach(function(oSelectDateOption) {
678
+ oStartupObject.semanticDates.Dates.forEach(function (oSelectDateOption) {
646
679
  var oSelectionDateOption = oStartupObject.selectionVariant.getSelectOption(oSelectDateOption.PropertyName);
647
- var oSFBSelectionOption = oSFBSelectionVariant.getSelectOption(oSelectDateOption.PropertyName);
680
+ var oSFBSelectionOption = oSFBSelectionVariant.getSelectOption(oSelectDateOption.PropertyName);
648
681
  //If startup object contains date range with the oSelectionDateOption PropertyName no need to override
649
682
  if (oSelectionDateOption && oSelectionDateOption.length != 0) {
650
683
  return;
651
684
  }
652
685
  //If SmartFilterBar has the property for that in that case add it to selectOption
653
686
  if (oSFBSelectionOption && oSFBSelectionOption.length != 0) {
654
- oStartupObject.selectionVariant.massAddSelectOption(oSelectDateOption.PropertyName,oSFBSelectionOption);
687
+ oStartupObject.selectionVariant.massAddSelectOption(oSelectDateOption.PropertyName, oSFBSelectionOption);
655
688
  return;
656
689
  }
657
690
  //If none has in that case we will add the selectOption with empty value
@@ -681,9 +714,9 @@ sap.ui.define([
681
714
 
682
715
  var oSFBSelectionVariantJSON = oSFBSelectionVariant.toJSONObject();
683
716
  if (
684
- !fnArrayContainsSameEnteries(oSFBSelectionVariantJSON.SelectOptions.filter(fnFilterItemExists), aTargetSelectionVariantJSON.SelectOptions.filter(fnFilterItemExists)) ||
685
- !fnArrayContainsSameEnteries(oSFBSelectionVariantJSON.Parameters.filter(fnParameterExists), aTargetSelectionVariantJSON.Parameters.filter(fnParameterExists)) ||
686
- !bSemanticDateEqual
717
+ !fnArrayContainsSameEnteries(oSFBSelectionVariantJSON.SelectOptions.filter(fnFilterItemExists), aTargetSelectionVariantJSON.SelectOptions.filter(fnFilterItemExists)) ||
718
+ !fnArrayContainsSameEnteries(oSFBSelectionVariantJSON.Parameters.filter(fnParameterExists), aTargetSelectionVariantJSON.Parameters.filter(fnParameterExists)) ||
719
+ !bSemanticDateEqual
687
720
  ) {
688
721
  fnApplySelectionVariantToSFB(oTargetSelectionVariant, oAppData.selectionVariant, true, oStartupObject.semanticDates, false);
689
722
  oSmartVariantManagement.currentVariantSetModified(true);
@@ -713,7 +746,7 @@ sap.ui.define([
713
746
  // In case of restoring from iAppState, it's called by applyState, which is in turn called from statePreserver, that
714
747
  // already takes care of not trying to apply an appstate that is not valid anymore.
715
748
  // task of this method is (now always when it's called!) only to adapt the state of all relevant controls to the provided one
716
- function fnAdaptToAppState(oAppData, oURLParameters, sNavType){
749
+ function fnAdaptToAppState(oAppData, oURLParameters, sNavType) {
717
750
  fnLogInfo("fnAdaptToAppState called", {
718
751
  sNavType: sNavType
719
752
  });
@@ -721,7 +754,7 @@ sap.ui.define([
721
754
  // Remark: within SVM Wrapper, setSuppressSelection is also used - be aware, that this must not be overlapping (as in both cases we set back to fixed-value false)
722
755
  oState.oSmartFilterbar.setSuppressSelection(false);
723
756
  bInitialisation = false;
724
- if (sNavType === sap.fe.navigation.NavType.hybrid){ // incase of hybrid -> take everything from IappState
757
+ if (sNavType === sap.fe.navigation.NavType.hybrid) { // incase of hybrid -> take everything from IappState
725
758
  oAppData = oAppData.iAppState;
726
759
  oAppData.controlStates = oAppData.data.permanentEntries.permanentState.data.controlStates;
727
760
  fnAdaptToAppStateIappState(oAppData);
@@ -731,7 +764,7 @@ sap.ui.define([
731
764
  // - restore from iAppState
732
765
  // - adapt to navigation parameters
733
766
  // - initial startup from scratch (including parameters provided from FLP!)
734
- if (sNavType === sap.fe.navigation.NavType.iAppState){ // first case is the simplest -> take everything from IappState
767
+ if (sNavType === sap.fe.navigation.NavType.iAppState) { // first case is the simplest -> take everything from IappState
735
768
  fnAdaptToAppStateIappState(oAppData);
736
769
  return;
737
770
  }
@@ -741,28 +774,28 @@ sap.ui.define([
741
774
  var sPreferredEntitySet = oSelectionInfo && oSelectionInfo.pageEntitySet;
742
775
  var sPreferredQuickVariantSelectionKey = oState.oMultipleViewsHandler.getPreferredKey(sPreferredEntitySet);
743
776
 
744
- switch (sNavType){
745
- case sap.fe.navigation.NavType.initial:
746
- // "technical" URL parameters are possible even in that case. NavigationHandler treats everything starting with "sap-" as technical.
747
- // some of them (at least 'sap-ui-fe*variant-id') are relevant
748
- fnAdaptToAppStateStartUpInitial(oURLParameters, sPreferredQuickVariantSelectionKey);
749
- break;
750
- case sap.fe.navigation.NavType.xAppState:
751
- case sap.fe.navigation.NavType.URLParams:
752
- if (oAppData.bNavSelVarHasDefaultsOnly
753
- || oAppData.oSelectionVariant.getSelectOptionsPropertyNames().length && Utils.isASubsetOfB(oAppData.oSelectionVariant.getSelectOptionsPropertyNames(), aIgnoreURLParameters)
754
- ){
755
- fnAdaptToAppStateStartUpWithParameters(oAppData, oURLParameters, sPreferredQuickVariantSelectionKey);
756
- } else {
757
- fnAdaptToAppStateNavigation(oAppData, oURLParameters, sPreferredQuickVariantSelectionKey);
758
- }
759
- break;
760
- default:
761
- throw new FeError(sClassName, "Invalid navigation type: " + sNavType);
777
+ switch (sNavType) {
778
+ case sap.fe.navigation.NavType.initial:
779
+ // "technical" URL parameters are possible even in that case. NavigationHandler treats everything starting with "sap-" as technical.
780
+ // some of them (at least 'sap-ui-fe*variant-id') are relevant
781
+ fnAdaptToAppStateStartUpInitial(oURLParameters, sPreferredQuickVariantSelectionKey);
782
+ break;
783
+ case sap.fe.navigation.NavType.xAppState:
784
+ case sap.fe.navigation.NavType.URLParams:
785
+ if (oAppData.bNavSelVarHasDefaultsOnly ||
786
+ oAppData.oSelectionVariant.getSelectOptionsPropertyNames().length && Utils.isASubsetOfB(oAppData.oSelectionVariant.getSelectOptionsPropertyNames(), aIgnoreURLParameters)
787
+ ) {
788
+ fnAdaptToAppStateStartUpWithParameters(oAppData, oURLParameters, sPreferredQuickVariantSelectionKey);
789
+ } else {
790
+ fnAdaptToAppStateNavigation(oAppData, oURLParameters, sPreferredQuickVariantSelectionKey);
791
+ }
792
+ break;
793
+ default:
794
+ throw new FeError(sClassName, "Invalid navigation type: " + sNavType);
762
795
  }
763
796
 
764
797
  // common to all startup cases (except iAppState)
765
- if (areDataShownInTable()){
798
+ if (areDataShownInTable()) {
766
799
  // trigger search if needed
767
800
  oState.oSmartFilterbar.search();
768
801
  // For desktop devices, expand the header for Standard and Custom variants and for tablet and mobile devices,
@@ -787,7 +820,7 @@ sap.ui.define([
787
820
  // adapt controls according to current implementation
788
821
  // Information in state could actually differ (if state originates from old release, change in FE or app layer). Additional information in state should be ignored,
789
822
  // missing information should lead to set initial state (which wrappers should do if called with undefined)
790
- aControlStateWrappers.forEach(function(oWrapper){
823
+ aControlStateWrappers.forEach(function (oWrapper) {
791
824
  oWrapper.setState(mControlsStates[oWrapper.getLocalId()]);
792
825
  });
793
826
  }
@@ -798,7 +831,7 @@ sap.ui.define([
798
831
  * 2) State is an empty object: No state should be applied. It offers a flexibility to set the page to an initial state i.e. without any state.
799
832
  * 3) State is an object: Passed state should be applied and it should be transferred to the most current version, assuming overriding here will not harm.
800
833
  */
801
- function applyState(oState){
834
+ function applyState(oState) {
802
835
  if (!oState) {
803
836
  // no iAppState key in Url, that means
804
837
  // - we are definitely in startUp case (while navigating inside the app, there's always an appState - even if it cannot be stored)
@@ -806,7 +839,11 @@ sap.ui.define([
806
839
  // Remark: in case of an appState key in the URL, that could not be analyzed, we should NOT call navigationHandler to parse. In this case, we get an empty object
807
840
  // (in contrast to undefined when there's no appstate key)
808
841
 
809
- return oSmartFilterBarInitializedPromise.then(fnParseUrlAndApplyAppState); // return promise to inform controller, when startup is finished
842
+ return oSmartFilterBarInitializedPromise.then(function () {
843
+ var oStartupFinishedPromise = fnParseUrlAndApplyAppState();
844
+ oStartupFinishedPromise.then(onFEStartupInitializedResolver);
845
+ return oStartupFinishedPromise; // return promise to inform controller, when startup is finished
846
+ });
810
847
  }
811
848
 
812
849
  var sNavType;
@@ -820,20 +857,22 @@ sap.ui.define([
820
857
  // enhance appData to the format needed by fnAdaptToAppState
821
858
  var oAppData = extend({
822
859
  oDefaultedSelectionVariant: new SelectionVariant(), // only accessed to check for P_DisplayCurrency - can this be relevant?
823
- oSelectionVariant: new SelectionVariant(oState && oState.selectionVariant) // -> oSelectionVariant
860
+ oSelectionVariant: new SelectionVariant(oState && oState.selectionVariant) // -> oSelectionVariant
824
861
  }, oState);
825
- oSmartFilterBarInitializedPromise.then(function(){
862
+ oSmartFilterBarInitializedPromise.then(function () {
826
863
  // fallback to navType initial, if appState is given in URL, but could not be analyzed => oState is an empty Object
827
- fnAdaptToAppState(oAppData, {} /* URLparameter are irrelevant if restoring from iAppState */, sNavType);
864
+ fnAdaptToAppState(oAppData, {} /* URLparameter are irrelevant if restoring from iAppState */ , sNavType);
865
+ // Once the FE is initialized, the promise is resolved so that the SFB contains the updated list of filters
866
+ onFEStartupInitializedResolver();
828
867
  });
829
868
  return oSmartFilterBarInitializedPromise; // to inform controller, when startup is finished
830
869
  }
831
870
 
832
- function fnParseUrlAndApplyAppState(){
833
- var oRet = new Promise(function(fnResolve){
871
+ function fnParseUrlAndApplyAppState() {
872
+ var oRet = new Promise(function (fnResolve) {
834
873
  try {
835
874
  var oParseNavigationPromise = oNavigationHandler.parseNavigation();
836
- oParseNavigationPromise.done(function(oAppData, oURLParameters, sNavType){
875
+ oParseNavigationPromise.done(function (oAppData, oURLParameters, sNavType) {
837
876
  if (sNavType !== sap.fe.navigation.NavType.iAppState) { // handled via state preserver
838
877
  // navType initial has also to be handled here, as in that case the call from state preserver happens to early (we don't even know
839
878
  // at that time, whether navtype is initial, URLparams or xAppState when started from FLP with user default values set)
@@ -841,16 +880,16 @@ sap.ui.define([
841
880
  }
842
881
  fnResolve();
843
882
  });
844
- oParseNavigationPromise.fail(function(oNavError, oURLParameters, sNavType){
883
+ oParseNavigationPromise.fail(function (oNavError, oURLParameters, sNavType) {
845
884
  /* Parsing app state has failed, so we cannot set the correct state
846
885
  * But at least we should get into a consistent state again, so the user can continue using the app
847
886
  */
848
887
  oLogger.warning(oNavError.getErrorCode() + "app state could not be parsed - continuing with empty state");
849
- // Use NavType initial, as this will enforce selection in case auto-binding is true.
888
+ // Use NavType initial, as this will enforce selection in case auto-binding is true.
850
889
  fnAdaptToAppState({}, oURLParameters, sap.fe.navigation.NavType.initial);
851
890
  fnResolve();
852
891
  });
853
- } catch (oError){
892
+ } catch (oError) {
854
893
  // method is called only, if no iAppState key in URL
855
894
  // possible error case could be a URL with xAppState key, but no iAppState key (navigation from non FE-app, or very old bookmark), and no ushell-Service available
856
895
  // TODO: verify, whether this can happen and how to deal with it
@@ -861,7 +900,7 @@ sap.ui.define([
861
900
  return oRet;
862
901
  }
863
902
 
864
- function fnRestoreExtendedFilterDataOnAfterSFBVariantLoad(oEvent){
903
+ function fnRestoreExtendedFilterDataOnAfterSFBVariantLoad(oEvent) {
865
904
  // Only difference in worklist: any change, i.e. also loading a variant, has to directly trigger a new request.
866
905
  // If we apply variant (as per appState), don't trigger search here, but later from appState restoring itself
867
906
  if (oState.oWorklistData.bWorkListEnabled && oEvent.getParameter("context") !== "SET_VM_ID") {
@@ -888,6 +927,17 @@ sap.ui.define([
888
927
  // regarding a), while SFB takes care to set the data for standard filters (created via annotation), for others (extension filters, edit state filter, anything else that
889
928
  // should be controlled by VM (currently anything else we add to iAppState, but maybe that's only correct in case of page variant management)) we have to set it
890
929
  // (independent of the context).
930
+ if (sap.ui.getCore().getMessageManager().getMessageModel().oData.length) {
931
+ var removedMessages = [];
932
+ for (var i in sap.ui.getCore().getMessageManager().getMessageModel().oData) {
933
+ var msg = sap.ui.getCore().getMessageManager().getMessageModel().oData[i];
934
+ if (msg.persistent && oEvent.getParameters().context === undefined) {
935
+ removedMessages.push(msg);
936
+ }
937
+ }
938
+ sap.ui.getCore().getMessageManager().removeMessages(removedMessages);
939
+ }
940
+
891
941
  // Restore header collapse logic (originally removed in change 5641712)
892
942
  // Collapse header when user manually selects a variant (context === undefined) that has executeOnSelect set to true
893
943
  var oContext = oEvent.getParameter("context");
@@ -901,7 +951,7 @@ sap.ui.define([
901
951
  }
902
952
 
903
953
  // collapse dynamic header - conditions are checked at calling places
904
- function collapseHeader(){
954
+ function collapseHeader() {
905
955
  var oTemplatePrivateModel = oController.getOwnerComponent().getModel("_templPriv");
906
956
  // Remark: this property is never set to true programmatically - only if user expands the header explicitly via 2-way-binding
907
957
  oTemplatePrivateModel.setProperty("/listReport/isHeaderExpanded", false);
@@ -914,7 +964,7 @@ sap.ui.define([
914
964
  */
915
965
  function fnSetFiltersUsingUIState(oSelectionVariant, bReplace, bStrictMode, oSemanticDates) {
916
966
  var oUiState = new UIState({
917
- selectionVariant : oSelectionVariant,
967
+ selectionVariant: oSelectionVariant,
918
968
  semanticDates: oSemanticDates
919
969
  });
920
970
  oState.oSmartFilterbar.setUiState(oUiState, {
@@ -939,9 +989,9 @@ sap.ui.define([
939
989
  */
940
990
  function applySelectionProperties(oSelectionVariant, sSelectionVariant, bNavTypeInitial) {
941
991
  // even when the nav type is initial, due to modifystartup extension,new fields can be added to smartfilterbar
942
- if (oSelectionVariant && (sSelectionVariant !== "" || bNavTypeInitial)){
992
+ if (oSelectionVariant && (sSelectionVariant !== "" || bNavTypeInitial)) {
943
993
  var aSelectionVariantProperties = oSelectionVariant.getParameterNames().concat(
944
- oSelectionVariant.getSelectOptionsPropertyNames());
994
+ oSelectionVariant.getSelectOptionsPropertyNames());
945
995
  for (var i = 0; i < aSelectionVariantProperties.length; i++) {
946
996
  oState.oSmartFilterbar.addFieldToAdvancedArea(aSelectionVariantProperties[i]);
947
997
  }
@@ -949,24 +999,24 @@ sap.ui.define([
949
999
  }
950
1000
 
951
1001
  // map property values for property with name sFirstProperty to values for property with name sSecondProperty in oSelectionVariant
952
- function fnAlignSelectOptions(oSelectionVariant, sFirstProperty, sSecondProperty){
953
- if (oSelectionVariant.getParameter(sFirstProperty) && !oSelectionVariant.getParameter(sSecondProperty)){
1002
+ function fnAlignSelectOptions(oSelectionVariant, sFirstProperty, sSecondProperty) {
1003
+ if (oSelectionVariant.getParameter(sFirstProperty) && !oSelectionVariant.getParameter(sSecondProperty)) {
954
1004
  oSelectionVariant.addParameter(sSecondProperty, oSelectionVariant.getParameter(sFirstProperty));
955
1005
  }
956
- if (oSelectionVariant.getSelectOption(sFirstProperty) && !oSelectionVariant.getSelectOption(sSecondProperty)){
1006
+ if (oSelectionVariant.getSelectOption(sFirstProperty) && !oSelectionVariant.getSelectOption(sSecondProperty)) {
957
1007
  var aSelectOption = oSelectionVariant.getSelectOption(sFirstProperty);
958
- aSelectOption.forEach(function(oSelectOption){
1008
+ aSelectOption.forEach(function (oSelectOption) {
959
1009
  oSelectionVariant.addSelectOption(sSecondProperty, oSelectOption.Sign, oSelectOption.Option, oSelectOption.Low, oSelectOption.High);
960
1010
  });
961
1011
  }
962
1012
  }
963
1013
 
964
- function fnMapEditableFieldFor(oSelectionVariant){
1014
+ function fnMapEditableFieldFor(oSelectionVariant) {
965
1015
  var oMetaModel = oController.getOwnerComponent().getModel().getMetaModel();
966
1016
  var sEntitySet = oController.getOwnerComponent().getEntitySet();
967
1017
  var oEntityType = oMetaModel.getODataEntityType(oMetaModel.getODataEntitySet(sEntitySet).entityType);
968
- oEntityType.property.forEach(function(oProperty){
969
- if (oProperty["com.sap.vocabularies.Common.v1.EditableFieldFor"]){
1018
+ oEntityType.property.forEach(function (oProperty) {
1019
+ if (oProperty["com.sap.vocabularies.Common.v1.EditableFieldFor"]) {
970
1020
  // annotation property names follow their type, so PropertyPath is the right property to look at - String has to be supported for compatibility reasons
971
1021
  var sKeyProperty = oProperty["com.sap.vocabularies.Common.v1.EditableFieldFor"].PropertyPath || oProperty["com.sap.vocabularies.Common.v1.EditableFieldFor"].String;
972
1022
  var sForEditProperty = oProperty.name;
@@ -978,7 +1028,7 @@ sap.ui.define([
978
1028
  });
979
1029
  }
980
1030
 
981
- function fnApplySelectionVariantToSFB(oSelectionVariant, sSelectionVariant, bReplace, oSemanticDates, bNavTypeInitial){
1031
+ function fnApplySelectionVariantToSFB(oSelectionVariant, sSelectionVariant, bReplace, oSemanticDates, bNavTypeInitial) {
982
1032
  fnMapEditableFieldFor(oSelectionVariant);
983
1033
  if (bReplace) {
984
1034
  oState.oSmartFilterbar.clearVariantSelection();
@@ -990,15 +1040,17 @@ sap.ui.define([
990
1040
  // provide data load settings including defaulting
991
1041
  // ideally, this should be implemented in a generic way in template assembler, so that generated getters also return default values for objects if not explicitely set in
992
1042
  // manifest (i.e. it should be sufficient to define the default in component - no need to individually implement defaulting!)
993
- function getDataLoadSettings(){
1043
+ function getDataLoadSettings() {
994
1044
  // general default
995
- var oDefaultDataLoadSettings = {loadDataOnAppLaunch: "ifAnyFilterExist"};
1045
+ var oDefaultDataLoadSettings = {
1046
+ loadDataOnAppLaunch: "ifAnyFilterExist"
1047
+ };
996
1048
 
997
1049
  // intension is boolean, but unfortunately faulty values are (historically) not treated consistently
998
1050
  var bEnableAutoBindingMultiViews = oState.oMultipleViewsHandler.getOriginalEnableAutoBinding();
999
1051
 
1000
1052
  // if multiple views settings is not defined (also the case in single views case), general default is taken. Unlike other faulty values, null is treated like undefined
1001
- if (bEnableAutoBindingMultiViews !== undefined && bEnableAutoBindingMultiViews !== null){
1053
+ if (bEnableAutoBindingMultiViews !== undefined && bEnableAutoBindingMultiViews !== null) {
1002
1054
  // multiple views setting overrules general default
1003
1055
  oDefaultDataLoadSettings.loadDataOnAppLaunch = bEnableAutoBindingMultiViews ? "always" : "never";
1004
1056
  }
@@ -1008,7 +1060,7 @@ sap.ui.define([
1008
1060
  // settings. Other not allowed values (any other sting) were ignored, i.e. returning undefined from getInitialLoadBehaviourSettings, thus setting undefined to
1009
1061
  // oSmartVariantManagement.setExecuteOnStandard (which actually only sets the default) and finally using the value returned from
1010
1062
  // oSmartVariantManagement.getExecuteOnStandard (only different from overall default (false), if user has explicitly set it)
1011
- if (oManifestDataLoadSettings && oManifestDataLoadSettings.loadDataOnAppLaunch === ""){
1063
+ if (oManifestDataLoadSettings && oManifestDataLoadSettings.loadDataOnAppLaunch === "") {
1012
1064
  oManifestDataLoadSettings.loadDataOnAppLaunch = undefined;
1013
1065
  }
1014
1066
 
@@ -1019,16 +1071,16 @@ sap.ui.define([
1019
1071
  // analyze all input determining whether data should be loaded initially and accordingly
1020
1072
  // - sets default value for flag whether standard variant should be execute on select
1021
1073
  // - determines whether we actually should load data
1022
- function applyInitialLoadBehavior(bDataLoadCausedByNavigation){
1074
+ function applyInitialLoadBehavior(bDataLoadCausedByNavigation) {
1023
1075
  // cases definitely determining to load data initially
1024
1076
  // - worklist
1025
1077
  // - livemode
1026
1078
  // - master detail (i.e. bLoadListAndFirstEntryOnStartup is set)
1027
1079
  var oSmartFilterbar = oState.oSmartFilterbar;
1028
- var bShouldDataBeLoaded = oState.oWorklistData.bWorkListEnabled || oSmartFilterbar.getLiveMode() || oState.bLoadListAndFirstEntryOnStartup ;
1080
+ var bShouldDataBeLoaded = oState.oWorklistData.bWorkListEnabled || oSmartFilterbar.getLiveMode() || oState.bLoadListAndFirstEntryOnStartup;
1029
1081
 
1030
1082
  var sLoadBehaviour = getDataLoadSettings().loadDataOnAppLaunch;
1031
- if (!oSmartVariantManagement || oController.getOwnerComponent().getVariantManagementHidden()){
1083
+ if (!oSmartVariantManagement || oController.getOwnerComponent().getVariantManagementHidden()) {
1032
1084
  // No VM ->
1033
1085
  bShouldDataBeLoaded = bShouldDataBeLoaded || sLoadBehaviour === "always";
1034
1086
  bShouldDataBeLoaded = bShouldDataBeLoaded || (sLoadBehaviour === "ifAnyFilterExist" && oSmartFilterbar.getFiltersWithValues().length > 0);
@@ -1047,9 +1099,9 @@ sap.ui.define([
1047
1099
  oSmartVariantManagement && oSmartVariantManagement.setExecuteOnStandard(bDefaultExecuteOnStandard);
1048
1100
 
1049
1101
  // determine final setting according to user's variant settings
1050
- if (oState.oSmartFilterbar.isCurrentVariantStandard()){
1102
+ if (oState.oSmartFilterbar.isCurrentVariantStandard()) {
1051
1103
  var bExecuteOnStandard = oSmartVariantManagement.getExecuteOnStandard();
1052
- if (bDefaultExecuteOnStandard !== bExecuteOnStandard){
1104
+ if (bDefaultExecuteOnStandard !== bExecuteOnStandard) {
1053
1105
  // user has overruled setting, so user's choice wins
1054
1106
  bShouldDataBeLoaded = bExecuteOnStandard;
1055
1107
  } else {
@@ -1075,6 +1127,10 @@ sap.ui.define([
1075
1127
  oDataLoadedWrapper.setState(!!bShouldDataBeLoaded);
1076
1128
  }
1077
1129
 
1130
+ function onFEStartupInitialized() {
1131
+ return onFEStartupInitializedPromise;
1132
+ }
1133
+
1078
1134
  return {
1079
1135
  areDataShownInTable: areDataShownInTable,
1080
1136
  setDataShownInTable: fnSetDataShownInTable,
@@ -1085,12 +1141,13 @@ sap.ui.define([
1085
1141
  onAfterSFBVariantLoad: onAfterSFBVariantLoad,
1086
1142
  applyState: applyState,
1087
1143
  getCurrentAppState: getCurrentAppState, // separation of concerns - only provide state, statePreserver responsible for storing it
1088
- setFiltersUsingUIState : fnSetFiltersUsingUIState
1144
+ setFiltersUsingUIState: fnSetFiltersUsingUIState,
1145
+ onFEStartupInitialized: onFEStartupInitialized
1089
1146
  };
1090
1147
  }
1091
1148
 
1092
1149
  return BaseObject.extend("sap.suite.ui.generic.template.ListReport.controller.IappStateHandler", {
1093
- constructor: function(oState, oController, oTemplateUtils) {
1150
+ constructor: function (oState, oController, oTemplateUtils) {
1094
1151
  extend(this, getMethods(oState, oController, oTemplateUtils));
1095
1152
  }
1096
1153
  });
@@ -8,7 +8,7 @@
8
8
  "i18n": "i18n/i18n.properties",
9
9
  "applicationVersion": {
10
10
  "__comment": "applicationVersion oder componentversion??",
11
- "version": "1.120.44"
11
+ "version": "1.120.45"
12
12
  },
13
13
  "title": "{{TITLE}}",
14
14
  "description": "{{DESCRIPTION}}",
@@ -6,7 +6,7 @@
6
6
  "type": "component",
7
7
  "i18n": "i18n/i18n.properties",
8
8
  "applicationVersion": {
9
- "version": "1.120.44"
9
+ "version": "1.120.45"
10
10
  },
11
11
  "title": "{{TITLE}}",
12
12
  "description": "{{DESCRIPTION}}",
@@ -6,7 +6,7 @@
6
6
  "type": "component",
7
7
  "i18n": "i18n/i18n.properties",
8
8
  "applicationVersion": {
9
- "version": "1.120.44"
9
+ "version": "1.120.45"
10
10
  },
11
11
  "title": "{{TITLE}}",
12
12
  "description": "{{DESCRIPTION}}",
@@ -6,7 +6,7 @@
6
6
  "type": "component",
7
7
  "i18n": "i18n/i18n.properties",
8
8
  "applicationVersion": {
9
- "version": "1.120.44"
9
+ "version": "1.120.45"
10
10
  },
11
11
  "title": "{{TITLE}}",
12
12
  "description": "{{DESCRIPTION}}",
@@ -155,7 +155,7 @@ sap.ui.define([
155
155
  oPreliminaryState = oState;
156
156
 
157
157
  // Wait for all managed controls to be initialized before applying state
158
- oAllControlsInitializedPromise.then(function() {
158
+ return oAllControlsInitializedPromise.then(function() {
159
159
  bIsApplyingVariant = true;
160
160
  if (!oPreliminaryState) {
161
161
  // if no state is provided set default variant (not modified)
@@ -939,7 +939,7 @@ sap.ui.define([
939
939
  * @extends sap.ui.core.UIComponent
940
940
  * @abstract
941
941
  * @author SAP SE
942
- * @version 1.120.44
942
+ * @version 1.120.45
943
943
  * @name sap.suite.ui.generic.template.lib.AppComponent
944
944
  */
945
945
  return UIComponent.extend("sap.suite.ui.generic.template.lib.AppComponent", {
@@ -3094,7 +3094,7 @@ sap.ui.define(["sap/ui/base/Object",
3094
3094
  * @param {sap.suite.ui.generic.template.lib.AppComponent} oAppComponent The AppComponent instance
3095
3095
  * @public
3096
3096
  * @extends sap.ui.base.Object
3097
- * @version 1.120.44
3097
+ * @version 1.120.45
3098
3098
  * @since 1.30.0
3099
3099
  * @alias sap.suite.ui.generic.template.lib.NavigationController
3100
3100
  */
@@ -60,7 +60,7 @@ sap.ui.define([
60
60
  interfaces: [],
61
61
  controls: [],
62
62
  elements: [],
63
- version: "1.120.44",
63
+ version: "1.120.45",
64
64
  extensions: {
65
65
  //Configuration used for rule loading of Support Assistant
66
66
  "sap.ui.support": {