@sapui5/sap.suite.ui.generic.template 1.151.0 → 1.152.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.
Files changed (41) hide show
  1. package/package.json +1 -1
  2. package/src/sap/suite/ui/generic/template/.library +1 -1
  3. package/src/sap/suite/ui/generic/template/AnalyticalListPage/control/visualfilterbar/SmartVisualFilterBar.js +4 -3
  4. package/src/sap/suite/ui/generic/template/AnalyticalListPage/manifest.json +1 -1
  5. package/src/sap/suite/ui/generic/template/Canvas/manifest.json +1 -1
  6. package/src/sap/suite/ui/generic/template/ListReport/Component.js +4 -2
  7. package/src/sap/suite/ui/generic/template/ListReport/i18n/i18n_sv.properties +1 -1
  8. package/src/sap/suite/ui/generic/template/ListReport/manifest.json +1 -1
  9. package/src/sap/suite/ui/generic/template/ListReport/view/fragments/FullscreenPage.fragment.xml +3 -0
  10. package/src/sap/suite/ui/generic/template/ObjectPage/controller/ControllerImplementation.js +3 -1
  11. package/src/sap/suite/ui/generic/template/ObjectPage/controller/RelatedAppsHandler.js +1 -1
  12. package/src/sap/suite/ui/generic/template/ObjectPage/manifest.json +1 -1
  13. package/src/sap/suite/ui/generic/template/QuickCreate/manifest.json +1 -1
  14. package/src/sap/suite/ui/generic/template/QuickView/manifest.json +1 -1
  15. package/src/sap/suite/ui/generic/template/genericUtilities/controlStateWrapperFactory/SmartFilterBarWrapper.js +5 -4
  16. package/src/sap/suite/ui/generic/template/genericUtilities/controlStateWrapperFactory/SmartTableChartCommon.js +10 -0
  17. package/src/sap/suite/ui/generic/template/genericUtilities/controlStateWrapperFactory/SmartVariantManagementWrapper.js +1 -8
  18. package/src/sap/suite/ui/generic/template/js/AnnotationHelper.js +21 -17
  19. package/src/sap/suite/ui/generic/template/lib/AppComponent.js +3 -1
  20. package/src/sap/suite/ui/generic/template/lib/Application.js +15 -2
  21. package/src/sap/suite/ui/generic/template/lib/CommonEventHandlers.js +30 -8
  22. package/src/sap/suite/ui/generic/template/lib/CommonUtils.js +3 -3
  23. package/src/sap/suite/ui/generic/template/lib/PageLeaveHandler.js +19 -14
  24. package/src/sap/suite/ui/generic/template/lib/ShareUtils.js +1 -1
  25. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillAIOrchestrator.js +1 -6
  26. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillApplyHandler.js +25 -44
  27. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillDialogController.js +80 -64
  28. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillFieldCollector.js +442 -259
  29. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillFormRenderer.js +125 -161
  30. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillHandler.js +134 -160
  31. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillTableRenderer.js +55 -189
  32. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/fragments/EasyFillDialog.fragment.xml +67 -85
  33. package/src/sap/suite/ui/generic/template/lib/ai/EasyFilterBarHandler.js +138 -17
  34. package/src/sap/suite/ui/generic/template/lib/ai/EasyFilterDataFetcherHelper.js +1 -1
  35. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_US_saptrc.properties +6 -6
  36. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fi.properties +4 -4
  37. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sl.properties +1 -1
  38. package/src/sap/suite/ui/generic/template/lib/insights/InsightsCardHelper.js +16 -4
  39. package/src/sap/suite/ui/generic/template/lib/navigation/NavigationController.js +3 -2
  40. package/src/sap/suite/ui/generic/template/library.js +1 -1
  41. package/src/sap/suite/ui/generic/template/themes/base/ObjectPage.less +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sapui5/sap.suite.ui.generic.template",
3
- "version": "1.151.0",
3
+ "version": "1.152.0",
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.151.0</version>
10
+ <version>1.152.0</version>
11
11
 
12
12
  <documentation>Library with generic Suite UI templates.</documentation>
13
13
 
@@ -13,6 +13,7 @@ sap.ui.define([
13
13
  "sap/m/VBox",
14
14
  "sap/m/Button",
15
15
  "sap/m/Title",
16
+ "sap/m/Text",
16
17
  "sap/suite/ui/generic/template/AnalyticalListPage/controller/DropDownController",
17
18
  "sap/suite/ui/generic/template/AnalyticalListPage/controller/DynamicDateRangeController",
18
19
  "sap/suite/ui/generic/template/AnalyticalListPage/control/visualfilterbar/FilterItemMicroBar",
@@ -49,6 +50,7 @@ sap.ui.define([
49
50
  VBox,
50
51
  Button,
51
52
  Title,
53
+ Text,
52
54
  DropDownController,
53
55
  DynamicDateRangeController,
54
56
  FilterItemMicroBar,
@@ -854,10 +856,9 @@ sap.ui.define([
854
856
  titleMD.addStyleClass("sapSmartTemplatesAnalyticalListPageRequired");
855
857
  }
856
858
  //second part of the title i.e unit and currency
857
- var titleUnitCurr = new Title({
859
+ var titleUnitCurr = new Text({
858
860
  text: titleObject.titleUnitCurr.length > 1 ? "| " + titleObject.titleUnitCurr : "",
859
- titleStyle: SapCoreLibrary.TitleLevel.H6,
860
- level: SapCoreLibrary.TitleLevel.Auto,
861
+ wrapping: false,
861
862
  width: titleObject.titleUnitCurr.length > 1 ? "4.15rem" : "0rem"
862
863
  });
863
864
 
@@ -8,7 +8,7 @@
8
8
  "i18n": "i18n/i18n.properties",
9
9
  "applicationVersion": {
10
10
  "__comment": "applicationVersion oder componentversion??",
11
- "version": "1.151.0"
11
+ "version": "1.152.0"
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.151.0"
11
+ "version": "1.152.0"
12
12
  },
13
13
  "title": "Canvas",
14
14
  "description": "Canvas Page",
@@ -59,8 +59,10 @@ sap.ui.define(["sap/ui/core/mvc/OverrideExecution",
59
59
  var oTemplatePrivate = oComponent.getModel("_templPriv");
60
60
  oTemplatePrivate.setProperty("/listReport", {}); // Note that component properties are not yet available here
61
61
  },
62
- onActivate: function() {
63
- oViewProxy.onComponentActivate();
62
+ onActivate: function(sBindingPath, bIsComponentCurrentlyActive, bIsBackwards) {
63
+ if (bIsBackwards) {
64
+ oViewProxy.onComponentActivate();
65
+ }
64
66
  },
65
67
  adaptToChildContext: function(sCurrentChildContext) {
66
68
  oViewProxy.adaptToChildContext(sCurrentChildContext);
@@ -73,7 +73,7 @@ CANCEL_AND_DISCARD=F\u00F6rkasta utkast?
73
73
 
74
74
  DISCARD_EDIT=F\u00F6rkasta alla \u00E4ndringar?
75
75
 
76
- DISCARD=F\u00F6rkasta
76
+ DISCARD=Kasta
77
77
 
78
78
  DELETE=Radera
79
79
 
@@ -8,7 +8,7 @@
8
8
  "i18n": "i18n/i18n.properties",
9
9
  "applicationVersion": {
10
10
  "__comment": "applicationVersion oder componentversion??",
11
- "version": "1.151.0"
11
+ "version": "1.152.0"
12
12
  },
13
13
  "title": "{{TITLE}}",
14
14
  "description": "{{DESCRIPTION}}",
@@ -93,6 +93,9 @@
93
93
  </template:with>
94
94
  </OverflowToolbar>
95
95
  </f:footer>
96
+ <f:landmarkInfo>
97
+ <f:DynamicPageAccessibleLandmarkInfo footerRole="ContentInfo"/>
98
+ </f:landmarkInfo>
96
99
  </f:DynamicPage>
97
100
  </template:with>
98
101
  </template:with>
@@ -2804,9 +2804,11 @@ sap.ui.define([
2804
2804
  onDataFieldForIntentBasedNavigation: function (oEvent) {
2805
2805
  oEvent = merge({}, oEvent);
2806
2806
  oTemplateUtils.oServices.oApplication.performAfterSideEffectExecution(function () {
2807
+ var oCustomData = oTemplateUtils.oCommonUtils.getCustomDataFromEvent(oEvent);
2808
+ var oTarget = { semanticObject: oCustomData.SemanticObject, action: oCustomData.Action };
2807
2809
  oTemplateUtils.oCommonUtils.fnProcessDataLossOrDraftDiscardConfirmation(function () {
2808
2810
  oTemplateUtils.oCommonEventHandlers.onDataFieldForIntentBasedNavigation(oEvent, oBase.state);
2809
- }, Function.prototype, "LeaveApp");
2811
+ }, Function.prototype, "LeaveApp", false, oTarget);
2810
2812
  }, true);
2811
2813
  },
2812
2814
  onDataFieldWithIntentBasedNavigation: function (oEvent) {
@@ -25,7 +25,7 @@ sap.ui.define([
25
25
  oTemplateUtils.oCommonUtils.fnProcessDataLossOrDraftDiscardConfirmation(function () {
26
26
  var oContext = oController.getView().getBindingContext();
27
27
  oTemplateUtils.oCommonEventHandlers.onRelatedAppNavigation(oTarget, oContext);
28
- }, Function.prototype, "LeaveApp");
28
+ }, Function.prototype, "LeaveApp", false, oTarget);
29
29
  }
30
30
  }, "buttons");
31
31
  }
@@ -6,7 +6,7 @@
6
6
  "type": "component",
7
7
  "i18n": "i18n/i18n.properties",
8
8
  "applicationVersion": {
9
- "version": "1.151.0"
9
+ "version": "1.152.0"
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.151.0"
9
+ "version": "1.152.0"
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.151.0"
9
+ "version": "1.152.0"
10
10
  },
11
11
  "title": "{{TITLE}}",
12
12
  "description": "{{DESCRIPTION}}",
@@ -33,6 +33,8 @@ sap.ui.define([
33
33
  // not yet been called (race condition on second navigation: bAllControlsInitialized=true
34
34
  // causes fnApplyVariantState to run synchronously, triggering afterVariantLoad before the
35
35
  // Promise.all in SmartVariantManagementWrapper resolves and calls setSVMWrapperCallbacks).
36
+ // Cold-start _CUSTOM restore is also handled there: afterVariantLoad("INIT") fires before
37
+ // getInitializedPromise() resolves, so modifyStartupExtension always gets the final word.
36
38
  var oSVMWrapperCallbacks = null;
37
39
 
38
40
  var oVariantManagementInitializedPromise;
@@ -59,10 +61,9 @@ sap.ui.define([
59
61
  if (oCustomData && oCustomData[dataPropertyNameGeneric]) {
60
62
  oGenericData = oCustomData[dataPropertyNameGeneric];
61
63
  } else {
62
- // getCustomFilterData() returns null on cold start (no prior sap-iapp-state) because
63
- // setCustomFilterData() is only called from beforeVariantFetch (variant save path),
64
- // never during the initial LREP variant load. The _CUSTOM section is present in the
65
- // variant content — fall back to reading it via getVariantContent().
64
+ // getCustomFilterData() returns null when no beforeVariantFetch has run yet for this
65
+ // variant (e.g. a named variant being switched to for the first time in the session, or cold-start INIT).
66
+ // The _CUSTOM section is present in the variant content — fall back to reading it via getVariantContent().
66
67
  try {
67
68
  var oSVM = oSmartFilterBar.getSmartVariant();
68
69
  // getCurrentVariantId() converts STANDARDVARIANTKEY to "" which _getVariantById can't look up.
@@ -49,6 +49,12 @@ sap.ui.define([
49
49
  function getControlWrapper(oControl) {
50
50
  var bIsApplying = false; // avoid forwarding change event when caused by us applying a state
51
51
  function fnGetState() {
52
+ // getCurrentState can iterate a managed control whose view was already torn down (e.g. navigation
53
+ // while an appState write is in flight). Reading state from a destroyed control crashes in
54
+ // getUiState() because its inner aggregation is gone, so skip it.
55
+ if (oControl.isDestroyed()) {
56
+ return undefined;
57
+ }
52
58
  var oControlUiState = oControl.getUiState(); // unfortunately not serializable, but a managed object
53
59
  var oStateUiState = {
54
60
  oPresentationVariant: oControlUiState.getPresentationVariant(),
@@ -66,6 +72,10 @@ sap.ui.define([
66
72
  }
67
73
 
68
74
  function fnSetState(oState) {
75
+ // Symmetric to fnGetState: never apply state to a destroyed control.
76
+ if (oControl.isDestroyed()) {
77
+ return;
78
+ }
69
79
  if (oState) {
70
80
  if (!oState.oUiState) {
71
81
  // Legacy handling for state without additional level oUiState (created with 1.99.0 - 1.99.3). Could be relevant on LR and OP, and independent of VM
@@ -85,14 +85,7 @@ sap.ui.define([
85
85
  setManagedControlStates: function(oState){
86
86
  aWrapperInfo.forEach(function(oInfo){
87
87
  if (!oInfo.bVMConnection) {
88
- // Defer setState until the control is ready (oReadyPromise resolves after the
89
- // control fires its initialise event and its inner table/chart is created).
90
- // Without this guard, afterVariantLoad can call setState before SmartTable._oTable
91
- // exists, causing getUiState() to crash with a null-dereference on getTable().
92
- var oReady = oInfo.wrapper.oReadyPromise || Promise.resolve();
93
- oReady.then(function() {
94
- oInfo.wrapper.setState(oState[oInfo.wrapper.getLocalId()]);
95
- });
88
+ oInfo.wrapper.setState(oState[oInfo.wrapper.getLocalId()]);
96
89
  }
97
90
  });
98
91
  }
@@ -924,26 +924,30 @@ sap.ui.define(["sap/ui/model/odata/AnnotationHelper",
924
924
  oDataField = oCollection[i];
925
925
  oResult = null;
926
926
  // if type is DataFieldForAnnotation, then loop over target annotations
927
- if (oDataField.RecordType === "com.sap.vocabularies.UI.v1.DataFieldForAnnotation" &&
928
- oDataField.Target.AnnotationPath.indexOf("com.sap.vocabularies.UI.v1.FieldGroup") >= 0) {
929
- // oDataField = oAnnotationHelper.getDataFieldFromDataFieldForAnnotation(oInterface, oDataField);
930
- var oTargetLineItem = oMetaModel.getContext(oInterface.getPath() + "/" + i + "/Target");
931
- var sResolvedPath = AnnotationHelperModel.resolvePath(oTargetLineItem);
932
- var oDataFieldTarget = oMetaModel.getObject(sResolvedPath);
933
-
934
- if (oDataFieldTarget.Data && oDataFieldTarget.Data.length > 0) {
935
- for (var j = 0; j < oDataFieldTarget.Data.length; j++) {
936
- oResult = oAnnotationHelper.generateAnnotatedActionCustomData(oDataFieldTarget.Data[j], oFacet, oTabItem, oChartItem);
937
- if (oResult) {
938
- aButtonsData.push(oResult);
927
+ try {
928
+ if (oDataField.RecordType === "com.sap.vocabularies.UI.v1.DataFieldForAnnotation" &&
929
+ oDataField.Target.AnnotationPath.indexOf("com.sap.vocabularies.UI.v1.FieldGroup") >= 0) {
930
+ // oDataField = oAnnotationHelper.getDataFieldFromDataFieldForAnnotation(oInterface, oDataField);
931
+ var oTargetLineItem = oMetaModel.getContext(oInterface.getPath() + "/" + i + "/Target");
932
+ var sResolvedPath = AnnotationHelperModel.resolvePath(oTargetLineItem);
933
+ var oDataFieldTarget = oMetaModel.getObject(sResolvedPath);
934
+
935
+ if (oDataFieldTarget.Data && oDataFieldTarget.Data.length > 0) {
936
+ for (var j = 0; j < oDataFieldTarget.Data.length; j++) {
937
+ oResult = oAnnotationHelper.generateAnnotatedActionCustomData(oDataFieldTarget.Data[j], oFacet, oTabItem, oChartItem);
938
+ if (oResult) {
939
+ aButtonsData.push(oResult);
940
+ }
939
941
  }
940
942
  }
943
+ } else {
944
+ oResult = oAnnotationHelper.generateAnnotatedActionCustomData(oDataField, oFacet, oTabItem, oChartItem);
945
+ if (oResult) {
946
+ aButtonsData.push(oResult);
947
+ }
941
948
  }
942
- } else {
943
- oResult = oAnnotationHelper.generateAnnotatedActionCustomData(oDataField, oFacet, oTabItem, oChartItem);
944
- if (oResult) {
945
- aButtonsData.push(oResult);
946
- }
949
+ } catch (oError) {
950
+ oLogger.error("configure - " + JSON.stringify(oDataField));
947
951
  }
948
952
  }
949
953
  }
@@ -661,6 +661,7 @@ sap.ui.define([
661
661
 
662
662
  function restore(){
663
663
  oTemplateContract.oBusyHelper.setBusyReason("exiting", false);
664
+ oTemplateContract.oApplicationProxy.resetExternalNavigation();
664
665
  for (var sComponentId in oTemplateContract.componentRegistry){
665
666
  var oRegistryEntry = oTemplateContract.componentRegistry[sComponentId];
666
667
  if (oRegistryEntry.methods.onRestore) {
@@ -942,6 +943,7 @@ sap.ui.define([
942
943
  var fnNormalizePagesMapToArray = testableHelper.testable(fnNormalizePagesMapToArray, "fnNormalizePagesMapToArray");
943
944
  getConfig = testableHelper.testable(getConfig, "getConfig");
944
945
  testableHelper.testable(setLeaveAppPromise, "AppComponent_setLeaveAppPromise");
946
+ testableHelper.testable(restore, "AppComponent_restore");
945
947
  /* eslint-enable */
946
948
 
947
949
  return oMethods;
@@ -959,7 +961,7 @@ sap.ui.define([
959
961
  * @public
960
962
  * @extends sap.ui.core.UIComponent
961
963
  * @author SAP SE
962
- * @version 1.151.0
964
+ * @version 1.152.0
963
965
  * @name sap.suite.ui.generic.template.lib.AppComponent
964
966
  */
965
967
  var oAppComponent = UIComponent.extend("sap.suite.ui.generic.template.lib.AppComponent", {
@@ -82,6 +82,11 @@ sap.ui.define(["sap/ui/base/Object",
82
82
  */
83
83
  function getMethods(oTemplateContract) {
84
84
 
85
+ // Set on first fnNavigateExternal call; blocks re-entry until reset. NavigationHandler.navigate() calls fnOnError
86
+ // on all failure paths and does not call it on the success path (app is leaving). The two valid reset points are
87
+ // therefore fnOnErrorWrapper (navigation failed) and AppComponent.restore() (FLP re-activated this app).
88
+ var bExternalNavigationTriggered = false;
89
+
85
90
  var oFocusHelper = new FocusHelper(oTemplateContract);
86
91
  var oContextBookkeeping = new ContextBookkeeping(oTemplateContract);
87
92
  var mEntitySetToETagInfo = Object.create(null); // maps the name of the entity sets which have been already checked for eTag
@@ -671,8 +676,13 @@ sap.ui.define(["sap/ui/base/Object",
671
676
  if (oCurrentNavigationHandler === GHOSTNAVIGATIONHANDLER){
672
677
  return;
673
678
  }
679
+ if (bExternalNavigationTriggered){
680
+ return;
681
+ }
682
+ bExternalNavigationTriggered = true;
674
683
  oTemplateContract.oNavigationControllerProxy.leave();
675
- var fnOnErrorWrapper = function(){
684
+ var fnOnErrorWrapper = function () {
685
+ bExternalNavigationTriggered = false;
676
686
  oFocusHelper.setNextFocus(Function.prototype); // Do not change focus in case exiting the application fails
677
687
  oTemplateContract.oBusyHelper.setBusyReason("exiting", false); // in error case we are not navigating away
678
688
  if (fnOnError){
@@ -834,7 +844,10 @@ sap.ui.define(["sap/ui/base/Object",
834
844
  removeTransientMessages: fnRemoveTransientMessages,
835
845
  getTransientMessages: getTransientMessages,
836
846
  setNextFocus: oFocusHelper.setNextFocus,
837
- setStates: setStates
847
+ setStates: setStates,
848
+ resetExternalNavigation: function() {
849
+ bExternalNavigationTriggered = false;
850
+ }
838
851
  };
839
852
 
840
853
  return {
@@ -720,7 +720,16 @@ sap.ui.define(["sap/ui/base/Object",
720
720
  }
721
721
 
722
722
  // null object has to be passed as the fourth argument (i.e. for oInnerAppData) to the navigate method as an indicator that the state should not be overwritten
723
- oServices.oApplication.navigateExternal(oOutbound.semanticObject, oOutbound.action, oSelectionVariant.toJSONString(), null, oCommonUtils.handleError);
723
+ // Explace outbounds must bypass fnNavigateExternal to avoid setting the app busy and consuming the re-entry guard.
724
+ // getNavigationHandler() returns a ghost stub (no .navigate) when ghostapp=true — guard before calling.
725
+ if (oOutbound.parameters && oOutbound.parameters["sap-ushell-navmode"] === "explace") {
726
+ var oNavHandler = oServices.oApplication.getNavigationHandler();
727
+ if (oNavHandler.navigate) {
728
+ oNavHandler.navigate(oOutbound.semanticObject, oOutbound.action, oSelectionVariant.toJSONString(), null, oCommonUtils.handleError, null, "explace");
729
+ }
730
+ } else {
731
+ oServices.oApplication.navigateExternal(oOutbound.semanticObject, oOutbound.action, oSelectionVariant.toJSONString(), null, oCommonUtils.handleError);
732
+ }
724
733
  }
725
734
 
726
735
  function fnNavigateIntentSmartLink(oOutbound, oEventSource) {
@@ -803,9 +812,10 @@ sap.ui.define(["sap/ui/base/Object",
803
812
 
804
813
  function fnOnSemanticObjectLinkNavigationPressed(oEventSource, oEventParameters){
805
814
  var oEventObject = deepExtend({}, oEventSource);
815
+ var sSemanticObject = oEventObject.data('SemanticObject');
816
+ var sAction = oEventObject.data('Action');
817
+ var oTarget = (sSemanticObject && sAction) ? { semanticObject: sSemanticObject, action: sAction } : undefined;
806
818
  oCommonUtils.fnProcessDataLossOrDraftDiscardConfirmation(function() {
807
- var sSemanticObject = oEventObject.data('SemanticObject');
808
- var sAction = oEventObject.data('Action');
809
819
  var sSemanticAttributes = oEventObject.data('SemanticAttributes');
810
820
  if (sSemanticObject && sAction){
811
821
  var oOutbound = {
@@ -818,7 +828,7 @@ sap.ui.define(["sap/ui/base/Object",
818
828
  }
819
829
  fnNavigateIntentSmartLink(oOutbound, oEventObject);
820
830
  }
821
- }, Function.prototype, "LeaveApp");
831
+ }, Function.prototype, "LeaveApp", false, oTarget);
822
832
  }
823
833
 
824
834
  function fnOnSemanticObjectLinkNavigationTargetObtained(sEntitySet, mFieldSemanticObjects, oEventParameters, oState, sTitle) {
@@ -1988,6 +1998,7 @@ sap.ui.define(["sap/ui/base/Object",
1988
1998
  var oContext = oEventSource.getParent().getBindingContext();
1989
1999
  var sSemanticObject = oEventSource.data("SemanticObject");
1990
2000
  var sAction = oEventSource.data("Action");
2001
+ var oTarget = { semanticObject: sSemanticObject, action: sAction };
1991
2002
 
1992
2003
  oCommonUtils.fnProcessDataLossOrDraftDiscardConfirmation(function() {
1993
2004
  var oOutbound = {
@@ -1995,7 +2006,7 @@ sap.ui.define(["sap/ui/base/Object",
1995
2006
  semanticObject: sSemanticObject
1996
2007
  };
1997
2008
  fnNavigateIntent(oOutbound, [oContext], oState.oSmartFilterbar || undefined);
1998
- }, Function.prototype, "LeaveApp");
2009
+ }, Function.prototype, "LeaveApp", false, oTarget);
1999
2010
  }
2000
2011
 
2001
2012
  /*
@@ -2025,13 +2036,15 @@ sap.ui.define(["sap/ui/base/Object",
2025
2036
  if (bRequiresContext && !aSelectedContexts.length) { // not consistent, since contexts missing
2026
2037
  fnShowMessageForInvalidNumberOfSelects(aSelectedContexts.length);
2027
2038
  } else {
2039
+ var oTarget = { semanticObject: oCustomData.SemanticObject, action: oCustomData.Action };
2028
2040
  oCommonUtils.fnProcessDataLossOrDraftDiscardConfirmation(function () {
2029
2041
  onDataFieldForIntentBasedNavigationSelectedContext(oCustomData, aSelectedContexts, oSmartFilterbar);
2030
- }, Function.prototype, "LeaveApp");
2042
+ }, Function.prototype, "LeaveApp", false, oTarget);
2031
2043
  }
2032
2044
  }
2033
2045
 
2034
2046
  function onInlineDataFieldForIntentBasedNavigation(oEventSource, oState){
2047
+ var oTarget = { semanticObject: oEventSource.data("SemanticObject"), action: oEventSource.data("Action") };
2035
2048
  oCommonUtils.fnProcessDataLossOrDraftDiscardConfirmation(function() {
2036
2049
  var oOutbound = {
2037
2050
  semanticObject: oEventSource.data("SemanticObject"),
@@ -2039,7 +2052,7 @@ sap.ui.define(["sap/ui/base/Object",
2039
2052
  };
2040
2053
  var oContext = oEventSource.getParent().getBindingContext();
2041
2054
  fnNavigateIntent(oOutbound, [oContext], oState.oSmartFilterbar);
2042
- }, Function.prototype, "LeaveApp");
2055
+ }, Function.prototype, "LeaveApp", false, oTarget);
2043
2056
  }
2044
2057
 
2045
2058
  function onInlineDataFieldForAction(oEvent) {
@@ -2709,7 +2722,16 @@ sap.ui.define(["sap/ui/base/Object",
2709
2722
  var oSelectionVariant = fnBuildSelectionVariantForNavigation(oOutbound, [], oContext);
2710
2723
  oController.adaptNavigationParameterExtension(oSelectionVariant, oOutbound);
2711
2724
  oCommonUtils.setComponentRefreshBehaviour(oOutbound);
2712
- oServices.oApplication.navigateExternal(oOutbound.semanticObject, oOutbound.action, oSelectionVariant.toJSONString(), null, oCommonUtils.handleError);
2725
+ // Explace outbounds must bypass fnNavigateExternal to avoid setting the app busy and consuming the re-entry guard.
2726
+ // getNavigationHandler() returns a ghost stub (no .navigate) when ghostapp=true — guard before calling.
2727
+ if (oOutbound.parameters && oOutbound.parameters["sap-ushell-navmode"] === "explace") {
2728
+ var oNavHandler = oServices.oApplication.getNavigationHandler();
2729
+ if (oNavHandler.navigate) {
2730
+ oNavHandler.navigate(oOutbound.semanticObject, oOutbound.action, oSelectionVariant.toJSONString(), null, oCommonUtils.handleError, null, "explace");
2731
+ }
2732
+ } else {
2733
+ oServices.oApplication.navigateExternal(oOutbound.semanticObject, oOutbound.action, oSelectionVariant.toJSONString(), null, oCommonUtils.handleError);
2734
+ }
2713
2735
  }
2714
2736
 
2715
2737
  function onSmartFieldInitialise(oEvent,sViewId){
@@ -845,7 +845,7 @@ sap.ui.define(["sap/ui/base/Object",
845
845
  //indicator that the state should not be overwritten
846
846
  //if draft enabled then passing NavigateExternal else on back button passing LeavePage
847
847
  }
848
- }, Function.prototype, "LeaveApp");
848
+ }, Function.prototype, "LeaveApp", false, { semanticObject: oOutbound.semanticObject, action: oOutbound.action });
849
849
  }
850
850
 
851
851
  function fnGetNavigationKeyProperties(sTargetEntitySet) {
@@ -1369,10 +1369,10 @@ sap.ui.define(["sap/ui/base/Object",
1369
1369
  // "LeaveApp": leave the app via a forward navigation
1370
1370
  // "LeavePage": leave the page via an internal navigation or a backward navigation (which may or may not be internal)
1371
1371
  // Note: if sMode is faulty it will be considered as "LeavePage"
1372
- function fnProcessDataLossOrDraftDiscardConfirmation(fnProcessFunction, fnCancelFunction, sMode, bNoBusyCheck){
1372
+ function fnProcessDataLossOrDraftDiscardConfirmation(fnProcessFunction, fnCancelFunction, sMode, bNoBusyCheck, oTarget){
1373
1373
  sMode = sMode || "LeavePage";
1374
1374
  if (oComponentUtils.isDraftEnabled()){
1375
- return oServices.oPageLeaveHandler.performAfterDiscardOrKeepDraft(fnProcessFunction, fnCancelFunction, sMode, bNoBusyCheck, false);
1375
+ return oServices.oPageLeaveHandler.performAfterDiscardOrKeepDraft(fnProcessFunction, fnCancelFunction, sMode, bNoBusyCheck, false, oTarget);
1376
1376
  } else {
1377
1377
  return oServices.oDataLossHandler.performIfNoDataLoss(fnProcessFunction, fnCancelFunction, sMode, bNoBusyCheck, false);
1378
1378
  }
@@ -22,19 +22,24 @@ sap.ui.define(["sap/ui/base/Object",
22
22
  firstListItemOption.focus();
23
23
  }
24
24
 
25
- function checkIfNavigationIsExplace() {
25
+ function checkIfNavigationIsExplace(oTarget) {
26
26
  var UShellContainer = sap.ui.require("sap/ushell/Container");
27
27
  if (!UShellContainer) {
28
- return Promise.resolve(false); // No UShell container, assume inplace navigation
28
+ return Promise.resolve(false);
29
29
  }
30
30
 
31
- return UShellContainer.getServiceAsync("FioriElements").then(function(oFioriElementsService) {
32
- if (oFioriElementsService && typeof oFioriElementsService.isExplaceNavigation === "function") {
33
- return oFioriElementsService.isExplaceNavigation();
34
- }
35
- return false; // API not available, default to inplace behavior
36
- }).catch(function() {
37
- return false; // Service not available or error, default to inplace behavior
31
+ return new Promise(function(resolve) {
32
+ sap.ui.require(["sap/ushell/api/FioriElements"], function(FioriElements) {
33
+ FioriElements.isExplaceNavigation(oTarget ? { target: oTarget } : undefined)
34
+ .then(function(bExplace) {
35
+ resolve(bExplace);
36
+ })
37
+ .catch(function() {
38
+ resolve(false);
39
+ });
40
+ }, function() {
41
+ resolve(false);
42
+ });
38
43
  });
39
44
  }
40
45
 
@@ -147,7 +152,7 @@ sap.ui.define(["sap/ui/base/Object",
147
152
  return oDiscardPromise;
148
153
  }
149
154
 
150
- function fnPerformAfterDiscardOrKeepDraftImpl(fnPositive, fnNegative, sMode, bIsTechnical) {
155
+ function fnPerformAfterDiscardOrKeepDraftImpl(fnPositive, fnNegative, sMode, bIsTechnical, oTarget) {
151
156
  var sEnableDiscardDraftConfirmation = oTemplateContract.oNavigationControllerProxy.isDiscardDraftConfirmationNeeded();
152
157
  var bNeedsPopup = ((sEnableDiscardDraftConfirmation === "always" && sMode.startsWith("Leave")) || (sEnableDiscardDraftConfirmation === "restricted" && sMode === "LeavePage")) && isObjectEditable();
153
158
 
@@ -157,7 +162,7 @@ sap.ui.define(["sap/ui/base/Object",
157
162
  }
158
163
 
159
164
  // Check if navigation will be explace and skip popup if so
160
- checkIfNavigationIsExplace().then(function(bIsExplace) {
165
+ checkIfNavigationIsExplace(oTarget).then(function(bIsExplace) {
161
166
  if (bIsExplace) {
162
167
  fnPositive(); // Skip popup for explace navigation
163
168
  } else {
@@ -195,7 +200,7 @@ sap.ui.define(["sap/ui/base/Object",
195
200
  }
196
201
 
197
202
  // Parameter sMode has same possible values as fnProcessDataLossOrDraftDiscardConfirmation in CommonUtils
198
- function fnPerformAfterDiscardOrKeepDraft(fnProcessFunction, fnCancelFunction, sMode, bNoBusyCheck, bIsTechnical) {
203
+ function fnPerformAfterDiscardOrKeepDraft(fnProcessFunction, fnCancelFunction, sMode, bNoBusyCheck, bIsTechnical, oTarget) {
199
204
  var oRet = new Promise(function (fnResolve, fnReject) {
200
205
  var fnPositive = function () {
201
206
  var oRet = fnProcessFunction();
@@ -206,9 +211,9 @@ sap.ui.define(["sap/ui/base/Object",
206
211
  fnReject();
207
212
  };
208
213
  if (bNoBusyCheck) {
209
- fnPerformAfterDiscardOrKeepDraftImpl(fnPositive, fnNegative, sMode, bIsTechnical);
214
+ fnPerformAfterDiscardOrKeepDraftImpl(fnPositive, fnNegative, sMode, bIsTechnical, oTarget);
210
215
  } else {
211
- oTemplateContract.oApplicationProxy.performAfterSideEffectExecution(fnPerformAfterDiscardOrKeepDraftImpl.bind(null, fnPositive, fnNegative, sMode, bIsTechnical), true);
216
+ oTemplateContract.oApplicationProxy.performAfterSideEffectExecution(fnPerformAfterDiscardOrKeepDraftImpl.bind(null, fnPositive, fnNegative, sMode, bIsTechnical, oTarget), true);
212
217
  }
213
218
  });
214
219
  return oRet;
@@ -13,7 +13,7 @@ sap.ui.define(["sap/base/util/ObjectPath", "sap/ushell/ui/footerbar/AddBookmarkB
13
13
  // Here we have introduced probing as for test scenarios as sap.ushell is not present all the iframe cases
14
14
  var UShellContainer = sap.ui.require("sap/ushell/Container");
15
15
  return UShellContainer ? new Promise(function(fnResolve){
16
- UShellContainer.getFLPUrlAsync(true).done(function (sFLPUrl){
16
+ UShellContainer.getFLPUrlAsync(true).then(function (sFLPUrl){
17
17
  fnResolve(sFLPUrl);
18
18
  });
19
19
  }) : Promise.resolve(document.URL);
@@ -188,14 +188,9 @@ sap.ui.define([
188
188
  oSplitResult.collectionsWithRejectedNewRows[sFieldName] = sRejectionType;
189
189
  }
190
190
 
191
+ // All proposed new rows are accepted when creation is allowed
191
192
  var aNewRows = bAllowsCreation ? aRawNewRows : [];
192
193
 
193
- // Cap new rows to one per table; flag if the AI proposed more
194
- if (aNewRows.length > 1) {
195
- oSplitResult.attemptedMultipleNewRows = true;
196
- aNewRows = [aNewRows[0]];
197
- }
198
-
199
194
  var aRowUpdates = aExistingRowUpdates.concat(aNewRows);
200
195
 
201
196
  var oValidation = oFieldCollector.isValidSmartTable(oFieldMeta.entitySet, oObjectPage);