@sapui5/sap.suite.ui.generic.template 1.124.4 → 1.124.6

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 (24) 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/manifest.json +1 -1
  4. package/src/sap/suite/ui/generic/template/Canvas/manifest.json +1 -1
  5. package/src/sap/suite/ui/generic/template/ListReport/controller/IappStateHandler.js +9 -3
  6. package/src/sap/suite/ui/generic/template/ListReport/manifest.json +1 -1
  7. package/src/sap/suite/ui/generic/template/ObjectPage/controller/ControllerImplementation.js +19 -17
  8. package/src/sap/suite/ui/generic/template/ObjectPage/manifest.json +1 -1
  9. package/src/sap/suite/ui/generic/template/QuickCreate/manifest.json +1 -1
  10. package/src/sap/suite/ui/generic/template/QuickView/manifest.json +1 -1
  11. package/src/sap/suite/ui/generic/template/designtime/ObjectPage.designtime.js +6 -0
  12. package/src/sap/suite/ui/generic/template/fragments/SmartControlContextMenu.fragment.xml +6 -0
  13. package/src/sap/suite/ui/generic/template/genericUtilities/utils.js +25 -1
  14. package/src/sap/suite/ui/generic/template/js/AnnotationHelper.js +16 -3
  15. package/src/sap/suite/ui/generic/template/js/AnnotationHelperHiddenTermSupport.js +6 -12
  16. package/src/sap/suite/ui/generic/template/lib/AppComponent.js +1 -1
  17. package/src/sap/suite/ui/generic/template/lib/CommonEventHandlers.js +31 -1
  18. package/src/sap/suite/ui/generic/template/lib/CommonUtils.js +6 -1
  19. package/src/sap/suite/ui/generic/template/lib/ComponentUtils.js +6 -1
  20. package/src/sap/suite/ui/generic/template/lib/ContextMenuHandler.js +23 -67
  21. package/src/sap/suite/ui/generic/template/lib/FlexibleColumnLayoutHandler.js +2 -1
  22. package/src/sap/suite/ui/generic/template/lib/navigation/NavigationController.js +99 -5
  23. package/src/sap/suite/ui/generic/template/library.js +1 -1
  24. package/src/sap/suite/ui/generic/template/listTemplates/fragments/DetailSmartTable.fragment.xml +3 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sapui5/sap.suite.ui.generic.template",
3
- "version": "1.124.4",
3
+ "version": "1.124.6",
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.124.4</version>
10
+ <version>1.124.6</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.124.4"
11
+ "version": "1.124.6"
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.124.4"
11
+ "version": "1.124.6"
12
12
  },
13
13
  "title": "Canvas",
14
14
  "description": "Canvas Page",
@@ -14,9 +14,10 @@ sap.ui.define([
14
14
  "sap/suite/ui/generic/template/listTemplates/semanticDateRangeTypeHelper",
15
15
  "sap/suite/ui/generic/template/ListReport/controller/LegacyStateHandler",
16
16
  "sap/suite/ui/generic/template/genericUtilities/testableHelper",
17
- "sap/suite/ui/generic/template/js/StableIdHelper"
17
+ "sap/suite/ui/generic/template/js/StableIdHelper",
18
+ "sap/suite/ui/generic/template/genericUtilities/utils"
18
19
  ], function(BaseObject, ControllerExtension, NavError, listUtils, SelectionVariant, UIState, FeLogger, deepEqual, extend,
19
- isEmptyObject, FeError, Device, semanticDateRangeTypeHelper, LegacyStateHandler, testableHelper, StableIdHelper) {
20
+ isEmptyObject, FeError, Device, semanticDateRangeTypeHelper, LegacyStateHandler, testableHelper, StableIdHelper, Utils) {
20
21
  "use strict";
21
22
 
22
23
  var sClassName = "ListReport.controller.IappStateHandler";
@@ -27,6 +28,9 @@ sap.ui.define([
27
28
  var dataPropertyNameCustom = "sap.suite.ui.generic.template.customData",
28
29
  dataPropertyNameExtension = "sap.suite.ui.generic.template.extensionData",
29
30
  dataPropertyNameGeneric = "sap.suite.ui.generic.template.genericData";
31
+ // Array contains URL parameters that should be ignored and trigger app initialization as only
32
+ // default parameters were passed
33
+ var aIgnoreURLParameters = ["save-appvar-id"];
30
34
 
31
35
  function fnLogInfo(sMessage, vDetails){
32
36
  if (sap.ui.support) { //only if support assistant is loaded
@@ -746,7 +750,9 @@ sap.ui.define([
746
750
  break;
747
751
  case sap.fe.navigation.NavType.xAppState:
748
752
  case sap.fe.navigation.NavType.URLParams:
749
- if (oAppData.bNavSelVarHasDefaultsOnly){
753
+ if (oAppData.bNavSelVarHasDefaultsOnly
754
+ || oAppData.oSelectionVariant.getSelectOptionsPropertyNames().length && Utils.isASubsetOfB(oAppData.oSelectionVariant.getSelectOptionsPropertyNames(), aIgnoreURLParameters)
755
+ ){
750
756
  fnAdaptToAppStateStartUpWithParameters(oAppData, oURLParameters, sPreferredQuickVariantSelectionKey);
751
757
  } else {
752
758
  fnAdaptToAppStateNavigation(oAppData, oURLParameters, sPreferredQuickVariantSelectionKey);
@@ -8,7 +8,7 @@
8
8
  "i18n": "i18n/i18n.properties",
9
9
  "applicationVersion": {
10
10
  "__comment": "applicationVersion oder componentversion??",
11
- "version": "1.124.4"
11
+ "version": "1.124.6"
12
12
  },
13
13
  "title": "{{TITLE}}",
14
14
  "description": "{{DESCRIPTION}}",
@@ -1817,23 +1817,25 @@ sap.ui.define([
1817
1817
 
1818
1818
  // This function is called when a sub-section is getting in view-port
1819
1819
  function fnSubSectionEntered(oSubSection) {
1820
- var oSubSectionInfoObj = oTemplateUtils.oInfoObjectHandler.setInformationWithControl(oSubSection); // Assigning the SubSection control to Info Object, in case it is assigned infoObject is returned without doing anything
1821
- // Check if initialization code is executed for the SubSection. If not initialize the same
1822
- var sSubSectionId = oSubSection.getId();
1823
- if (!mSubSectionsInitState[sSubSectionId]) {
1824
- // Execute Application specific logic which needs to be executed
1825
- oController.onSubSectionEnteredExtension(oSubSection);
1826
- mSubSectionsInitState[sSubSectionId] = true;
1827
- }
1828
-
1829
- if (oSubSectionInfoObj) { // In case of EditableHeaderFacet Sections & SubSection is created at runtime and there is info object handling
1830
- oMultipleViewsHandler.subSectionEntered(oSubSectionInfoObj); // Assigning the SubSection control MultipleViewsHandler. In case not relevant method simply returns
1831
- // The loading strategy of a sub-section might depend on the content of oWaitForState (together with the strategy) and whether or not the sub-section is currently in view-port.
1832
- // The second condition is fulfilled for sure. Only check the first one.
1833
- var oStrategy = oSubSectionInfoObj.getLoadingStrategy();
1834
- var bExecuteNow = checkGlobalWaitState(oStrategy);
1835
- if (bExecuteNow) {
1836
- oStrategy.activeHandler(oSubSection, oSubSectionInfoObj);
1820
+ if (oWaitForState && oWaitForState.bRebindCompleted){
1821
+ var oSubSectionInfoObj = oTemplateUtils.oInfoObjectHandler.setInformationWithControl(oSubSection); // Assigning the SubSection control to Info Object, in case it is assigned infoObject is returned without doing anything
1822
+ // Check if initialization code is executed for the SubSection. If not initialize the same
1823
+ var sSubSectionId = oSubSection.getId();
1824
+ if (!mSubSectionsInitState[sSubSectionId]) {
1825
+ // Execute Application specific logic which needs to be executed
1826
+ oController.onSubSectionEnteredExtension(oSubSection);
1827
+ mSubSectionsInitState[sSubSectionId] = true;
1828
+ }
1829
+
1830
+ if (oSubSectionInfoObj) { // In case of EditableHeaderFacet Sections & SubSection is created at runtime and there is info object handling
1831
+ oMultipleViewsHandler.subSectionEntered(oSubSectionInfoObj); // Assigning the SubSection control MultipleViewsHandler. In case not relevant method simply returns
1832
+ // The loading strategy of a sub-section might depend on the content of oWaitForState (together with the strategy) and whether or not the sub-section is currently in view-port.
1833
+ // The second condition is fulfilled for sure. Only check the first one.
1834
+ var oStrategy = oSubSectionInfoObj.getLoadingStrategy();
1835
+ var bExecuteNow = checkGlobalWaitState(oStrategy);
1836
+ if (bExecuteNow) {
1837
+ oStrategy.activeHandler(oSubSection, oSubSectionInfoObj);
1838
+ }
1837
1839
  }
1838
1840
  }
1839
1841
  }
@@ -6,7 +6,7 @@
6
6
  "type": "component",
7
7
  "i18n": "i18n/i18n.properties",
8
8
  "applicationVersion": {
9
- "version": "1.124.4"
9
+ "version": "1.124.6"
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.124.4"
9
+ "version": "1.124.6"
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.124.4"
9
+ "version": "1.124.6"
10
10
  },
11
11
  "title": "{{TITLE}}",
12
12
  "description": "{{DESCRIPTION}}",
@@ -144,6 +144,12 @@ sap.ui.define(["sap/suite/ui/generic/template/designtime/utils/designtimeHelper"
144
144
  }
145
145
  }
146
146
  },
147
+ "sap.ui.layout.VerticalLayout": {
148
+ actions: ["remove"]
149
+ },
150
+ "sap.ui.layout.HorizontalLayout": {
151
+ actions: ["remove"]
152
+ },
147
153
  "sap.uxap.ObjectPageHeaderActionButton": {
148
154
  actions: ["remove", "reveal"]
149
155
  },
@@ -11,6 +11,12 @@
11
11
  press="._templateEventHandlers.onContextMenu($event, '{smartControlId>id}')"/>
12
12
  </items>
13
13
  </MenuItem>
14
+ <template:if test="{parts: [{path: 'listEntitySet>name'}, {path: 'parameter>/settings/subPages/'}, {path: 'facet>Target/AnnotationPath'}], formatter: 'AH.getDisplayNavigationIntent'}">
15
+ <customData>
16
+ <core:CustomData key="CrossNavigation"
17
+ value="{parts: [{path: 'listEntitySet>name'}, {path: 'parameter>/settings/subPages/'}, {path: 'facet>Target/AnnotationPath'}], formatter: 'AH.getDisplayNavigationIntent'}" />
18
+ </customData>
19
+ </template:if>
14
20
  </Menu>
15
21
  </template:with>
16
22
  </core:FragmentDefinition>
@@ -21,7 +21,31 @@ sap.ui.define([], function() {
21
21
  return sap.ui.require.toUrl(sAppComponentName.replace(/\./g, "/")) + "/" + sImageUrl; //replacing dots by slashes before calling sap.ui.require.toUrl method. com.xyz.abc to com/xyz/abc
22
22
  }
23
23
 
24
+ // Function check is B array values is a subset of A array values.
25
+ // A = [], B = ["1", "2", "3"] -> true
26
+ // A = ["4"], B = ["1", "2", "3"] -> false
27
+ // A = ["1"], B = ["1", "2", "3"] -> true
28
+ // A = ["1", "3"], B = ["1", "2", "3"] -> true
29
+ // A = ["3", "2", "1"], B = ["1", "2", "3"] -> true
30
+ // A = ["1", "4"], B = ["1", "2", "3"] -> false
31
+ // A = ["1", "2", "3", "4"], B = ["1", "2", "3"] -> false
32
+ function fnIsASubsetOfB(a, b) {
33
+ if (a === b) {
34
+ return true;
35
+ }
36
+ if (!a || !b) {
37
+ return false;
38
+ }
39
+ if (a.length > b.length) {
40
+ return false;
41
+ }
42
+ return a.every(function(entry) {
43
+ return b.includes(entry);
44
+ });
45
+ }
46
+
24
47
  return {
25
- adjustImageUrlPath: fnAdjustImageUrlPath
48
+ adjustImageUrlPath: fnAdjustImageUrlPath,
49
+ isASubsetOfB: fnIsASubsetOfB
26
50
  };
27
51
  });
@@ -460,6 +460,7 @@ sap.ui.define(["sap/ui/model/odata/AnnotationHelper",
460
460
  var oContextSet = oInterface.getInterface(0);
461
461
  var oModel = oInterface.getInterface(1).getModel();
462
462
  // p13nData for Semantically Connected Columns
463
+ var sLeadingPropertyForSCColumn = "";
463
464
  var aNavigationPropertiesForSCColumn = [];
464
465
  var aAdditionalPropertiesForSCColumn = [];
465
466
  var aAdditionalSortPropertiesForSCColumn = [];
@@ -509,9 +510,15 @@ sap.ui.define(["sap/ui/model/odata/AnnotationHelper",
509
510
  if (sP13N) {
510
511
  oP13N = JSON.parse(sP13N.replace(/\\/g, ""));
511
512
  }
512
-
513
- oP13N.leadingProperty && (aAdditionalPropertiesForSCColumn.indexOf(oP13N.leadingProperty) === -1) ? aAdditionalPropertiesForSCColumn.push(oP13N.leadingProperty) : Function.prototype;
514
- oP13N.leadingProperty && (aAdditionalSortPropertiesForSCColumn.indexOf(oP13N.leadingProperty) === -1) ? aAdditionalSortPropertiesForSCColumn.push(oP13N.leadingProperty) : Function.prototype;
513
+
514
+ // Make the first data field's "leadingProperty" as column's "leadingProperty"
515
+ // Add the remaining leading properties into "additionalProperty" and "additionalSortingProperty"
516
+ if (!sLeadingPropertyForSCColumn && oP13N.leadingProperty) {
517
+ sLeadingPropertyForSCColumn = oP13N.leadingProperty;
518
+ } else {
519
+ oP13N.leadingProperty && (aAdditionalPropertiesForSCColumn.indexOf(oP13N.leadingProperty) === -1) ? aAdditionalPropertiesForSCColumn.push(oP13N.leadingProperty) : Function.prototype;
520
+ oP13N.leadingProperty && (aAdditionalSortPropertiesForSCColumn.indexOf(oP13N.leadingProperty) === -1) ? aAdditionalSortPropertiesForSCColumn.push(oP13N.leadingProperty) : Function.prototype;
521
+ }
515
522
 
516
523
  oP13N.navigationProperty && (aNavigationPropertiesForSCColumn.indexOf(oP13N.navigationProperty) === -1) ? aNavigationPropertiesForSCColumn.push(oP13N.navigationProperty) : Function.prototype;
517
524
  // Add "additionalProperty" of current data field to the "additionalProperty" of current column's p13n
@@ -532,6 +539,12 @@ sap.ui.define(["sap/ui/model/odata/AnnotationHelper",
532
539
 
533
540
  sP13N += '", "filterProperty":"' + "";
534
541
 
542
+ // Add the leading property to "leadingProperty" and "sortProperty" of p13n
543
+ if (sLeadingPropertyForSCColumn) {
544
+ sP13N += '", "leadingProperty":"' + sLeadingPropertyForSCColumn;
545
+ sP13N += '", "sortProperty":"' + sLeadingPropertyForSCColumn;
546
+ }
547
+
535
548
  if (aNavigationPropertiesForSCColumn.length > 0) {
536
549
  sP13N += '", "navigationProperty":"' + aNavigationPropertiesForSCColumn.join();
537
550
  }
@@ -4,11 +4,6 @@ sap.ui.define([
4
4
  ], function (isEmptyObject, AnnotationHelper) {
5
5
  "use strict";
6
6
 
7
- var oHiddenColumnInfo = {
8
- staticHiddenColumns: [],
9
- columnKeyToCellHiddenPath: undefined
10
- };
11
-
12
7
  /*
13
8
  * This method is called in the initialization and dataReceived phase of the specified SmartTable.
14
9
  * It handles everything which can be done regarding hiding columns at this point in time.
@@ -28,16 +23,15 @@ sap.ui.define([
28
23
  });
29
24
  var sLineItemSuffix = (oCustomDataForLineItemQualifier && oCustomDataForLineItemQualifier.getValue()) ? ("#" + oCustomDataForLineItemQualifier.getValue()) : "";
30
25
  var aDataFields = oEntityType["com.sap.vocabularies.UI.v1.LineItem" + sLineItemSuffix] || [];
31
-
26
+
32
27
  var aStaticHiddenColumns = []; // list of keys of columns that are always hidden
33
28
  var mColumnKeyToDynamicHiddenPath = Object.create(null); // map of column keys to pathes that determine whether the column is shown
34
-
29
+
35
30
  aDataFields.forEach(fnAnalyzeColumnHideInfoForDataField.bind(null, aStaticHiddenColumns, mColumnKeyToDynamicHiddenPath, oMetaModel, oEntityType));
36
- if (!isEmptyObject(mColumnKeyToDynamicHiddenPath) || aStaticHiddenColumns.length) { // if there is at least one column with hide info we store this analysis in the info object
37
- oHiddenColumnInfo.staticHiddenColumns = aStaticHiddenColumns;
38
- oHiddenColumnInfo.columnKeyToCellHiddenPath = mColumnKeyToDynamicHiddenPath;
39
- }
40
- return oHiddenColumnInfo;
31
+ return {
32
+ staticHiddenColumns: aStaticHiddenColumns,
33
+ columnKeyToCellHiddenPath: mColumnKeyToDynamicHiddenPath
34
+ };
41
35
  }
42
36
 
43
37
  /*
@@ -920,7 +920,7 @@ sap.ui.define([
920
920
  * @extends sap.ui.core.UIComponent
921
921
  * @abstract
922
922
  * @author SAP SE
923
- * @version 1.124.4
923
+ * @version 1.124.6
924
924
  * @name sap.suite.ui.generic.template.lib.AppComponent
925
925
  */
926
926
  var oAppComponent = UIComponent.extend("sap.suite.ui.generic.template.lib.AppComponent", {
@@ -2685,6 +2685,35 @@ sap.ui.define(["sap/ui/base/Object",
2685
2685
  oComponentUtils.getBusyHelper().setBusy(oAIFilterQueryHandlerPromise);
2686
2686
  }
2687
2687
 
2688
+ /**
2689
+ * Performs intent based navigation and opens the given line item context in a new tab.
2690
+ *
2691
+ * @param {object} oOutbound The target outbound intent (contains semantic object and action)
2692
+ * @param {sap.ui.model.Context} oLineItemContext The line item context to be opened in new tab
2693
+ * @param {sap.ui.comp.smartfilterbar.SmartFilterBar} oSmartFilterBar The filter bar
2694
+ * @param {Function} fnHandleError The error handling function
2695
+ */
2696
+ function fnNavigateIntentOnNewTab(oOutbound, oLineItemContext, oSmartFilterBar, fnHandleError) {
2697
+ var sSelectionVariant,
2698
+ oSelectionVariant,
2699
+ sNavMode = "explace"; // "explace" is the navigation mode for opening in new tab
2700
+ // Get selection variant from filter bar
2701
+ if (oSmartFilterBar) {
2702
+ sSelectionVariant = oSmartFilterBar.getUiState().getSelectionVariant();
2703
+ if (typeof sSelectionVariant !== "string"){
2704
+ sSelectionVariant = JSON.stringify(sSelectionVariant);
2705
+ }
2706
+ }
2707
+ // Build the selection variant from line item context, page context and the selection variant of filter bar
2708
+ oSelectionVariant = fnBuildSelectionVariantForNavigation(oOutbound, [oLineItemContext], oController.getView().getBindingContext(), sSelectionVariant);
2709
+ var oObjectInfo = {
2710
+ semanticObject: oOutbound.semanticObject,
2711
+ action: oOutbound.action
2712
+ };
2713
+ oController.adaptNavigationParameterExtension(oSelectionVariant, oObjectInfo);
2714
+ oServices.oApplication.getNavigationHandler().navigate(oOutbound.semanticObject, oOutbound.action, oSelectionVariant.toJSONString(), null, fnHandleError, null, sNavMode);
2715
+ }
2716
+
2688
2717
  /* eslint-disable */
2689
2718
  var fnBuildSelectionVariantForNavigation = testableHelper.testable(fnBuildSelectionVariantForNavigation, "fnBuildSelectionVariantForNavigation");
2690
2719
  var fnEvaluateParameters = testableHelper.testable(fnEvaluateParameters, "fnEvaluateParameters");
@@ -2736,7 +2765,8 @@ sap.ui.define(["sap/ui/base/Object",
2736
2765
  onSmartFieldModeToggled: onSmartFieldModeToggled,
2737
2766
  onRenderTeamsContactCollabOptions: fnRenderTeamsContactCollabOptions,
2738
2767
  hideTableCells: fnHideTableCells,
2739
- onEasyFilterChange: fnHandleEasyFilterChange
2768
+ onEasyFilterChange: fnHandleEasyFilterChange,
2769
+ navigateIntentOnNewTab: fnNavigateIntentOnNewTab
2740
2770
  };
2741
2771
  }
2742
2772
 
@@ -728,6 +728,10 @@ sap.ui.define(["sap/ui/base/Object",
728
728
  oComponentUtils.navigateAccordingToContext(oContext, iDisplayMode, bReplace);
729
729
  }
730
730
 
731
+ function fnOpenContextInNewTabFromListItem (oContext) {
732
+ oComponentUtils.openContextInNewTab(oContext);
733
+ }
734
+
731
735
  // Fix for BCP 1770053414 where error message is displayed instead of error code
732
736
  function fnHandleError(oError) {
733
737
  if (oError instanceof sap.fe.navigation.NavError) {
@@ -1992,7 +1996,8 @@ sap.ui.define(["sap/ui/base/Object",
1992
1996
  getControlStateWrapperById: oControlStateWrapperFactory.getControlStateWrapperById,
1993
1997
  handleError: fnHandleError,
1994
1998
  transformTechnicalPropsOnExportedFile: fnTransformTechnicalPropsOnExportedFile,
1995
- includeEntitySetParametersToExportedFile: fnIncludeEntitySetParametersToExportedFile
1999
+ includeEntitySetParametersToExportedFile: fnIncludeEntitySetParametersToExportedFile,
2000
+ openContextInNewTabFromListItem: fnOpenContextInNewTabFromListItem
1996
2001
  };
1997
2002
  }
1998
2003
 
@@ -1071,6 +1071,10 @@ sap.ui.define(["sap/ui/base/Object",
1071
1071
  var oTemplatePrivateGlobalModel = getTemplatePrivateGlobalModel();
1072
1072
  return oTemplatePrivateGlobalModel.getProperty("/generic/ui5VersionInfo");
1073
1073
  }
1074
+
1075
+ function fnOpenContextInNewTab (oNavigationContext) {
1076
+ oComponentRegistryEntry.oTemplateContract.oNavigationControllerProxy.openContextInNewTab(oTreeNode, oNavigationContext);
1077
+ }
1074
1078
 
1075
1079
  return {
1076
1080
  getBusyHelper: function() {
@@ -1152,7 +1156,8 @@ sap.ui.define(["sap/ui/base/Object",
1152
1156
  getToolbarDataFieldForIBNCommandDetails: oCommandComponentUtils.getToolbarDataFieldForIBNCommandDetails,
1153
1157
  isStateHandlingSuspended: fnIsStateHandlingSuspended,
1154
1158
  adjustCopyButtonSettings: fnAdjustCopyButtonSettings,
1155
- getUI5VersionInfo: fnGetUI5VersionInfo
1159
+ getUI5VersionInfo: fnGetUI5VersionInfo,
1160
+ openContextInNewTab: fnOpenContextInNewTab
1156
1161
  };
1157
1162
  }
1158
1163
 
@@ -1,14 +1,12 @@
1
1
  sap.ui.define([
2
2
  "sap/base/util/extend",
3
3
  "sap/base/util/ObjectPath",
4
- "sap/f/library",
5
4
  "sap/m/MessageBox",
6
5
  "sap/suite/ui/generic/template/genericUtilities/controlHelper",
7
6
  "sap/suite/ui/generic/template/genericUtilities/FeLogger",
8
7
  "sap/ui/base/Object",
9
- "sap/ui/base/Event",
10
- "sap/ui/util/openWindow"
11
- ], function (extend, ObjectPath, fioriLibrary, MessageBox, controlHelper, FeLogger, BaseObject, Event, openWindow) {
8
+ "sap/ui/base/Event"
9
+ ], function (extend, ObjectPath, MessageBox, controlHelper, FeLogger, BaseObject, Event) {
12
10
  "use strict";
13
11
 
14
12
  /* This class provides generic functionality for handling of the context menu for one smart control (oSourceControl).
@@ -16,9 +14,7 @@ sap.ui.define([
16
14
  * oConfiguration is an object which contains logic which is specific to the floorplan using this functionality.
17
15
  */
18
16
  var oLogger = new FeLogger("lib.ContextMenuHandler").getLogger();
19
- // shortcut for sap.f.LayoutType
20
- var LayoutType = fioriLibrary.LayoutType;
21
-
17
+
22
18
  // Constants
23
19
  var MAX_RECORDS_OPEN_IN_NEW_TAB = 10;
24
20
  var aToolbarContentsToBeOmitted = ["btnPersonalisation", "btnExcelExport"];
@@ -65,7 +61,9 @@ sap.ui.define([
65
61
  var bNavigationSupported = oComponentUtils.canNavigateToSubEntitySet(oSourceControl.getEntitySet());
66
62
  var mHandlers; // maps keys of context menu entries to handler functions for the corresponding entry
67
63
  var iCreatedMenuItemsCounter = 0; // increased whenever a new MenuItem is being created In fnAddMenuItem). Used to generate a key for mHandlers.
68
-
64
+ // Store the outbound navigation target
65
+ var sOutboundNavigationTarget = oSourceControl.getTable().getContextMenu().data("CrossNavigation");
66
+ var oOutbound = sOutboundNavigationTarget && fnGetOutboundInfoFromManifest(sOutboundNavigationTarget);
69
67
  /**
70
68
  * The method does the following
71
69
  * - Adds an entry (menu item) to the context menu.
@@ -306,51 +304,14 @@ sap.ui.define([
306
304
  return !bIsEmptyRow;
307
305
  }
308
306
 
309
- /**
310
- * Constructs the app specific route for the target to be opened on new tab. The target route consists of
311
- * 1. Deep path of the context
312
- * 2. URL parameters of the current app specific route.
313
- *
314
- * Note: All the URL parameters from source are retained in the target except the "FCLLayout".
315
- * The target "FCLLayout" is calculated by the below logic:
316
- *
317
- * If the app supports FCL.
318
- * - If the current page is LR (iViewLevel = 0), the target layout is "MidColumnFullScreen"
319
- * - If the current page is OP (iViewLevel > 0), the target layout is "EndColumnFullScreen"
320
- *
321
- * @returns {string} target path
322
- */
323
- function fnConstructTargetAppSpecificRoute (oContext, oAppComponent, sSrcAppSpecificRoute) {
324
- var sUrlParams = sSrcAppSpecificRoute.includes("?") ? sSrcAppSpecificRoute.substring(sSrcAppSpecificRoute.indexOf("?")) : "";
325
- var oUrlParams = new URLSearchParams(sUrlParams);
326
- var sDeepPath = oContext.getDeepPath();
327
- var sTargetPathPrefix = sDeepPath.startsWith("/") ? "&" : "&/";
328
- // If the app supports FCL, the object page should be opened in full screen mode
329
- if (oAppComponent.getFlexibleColumnLayout()) {
330
- var iViewLevel = oComponentUtils.getViewLevel();
331
- var sTargetFCLLayout = iViewLevel === 0 ? LayoutType.MidColumnFullScreen : LayoutType.EndColumnFullScreen;
332
- // Update "FCLLayout"
333
- oUrlParams.set("FCLLayout", sTargetFCLLayout);
334
- }
335
- return sTargetPathPrefix + sDeepPath + "?" + oUrlParams.toString();
307
+ // Fetches the outbound target from manifest
308
+ function fnGetOutboundInfoFromManifest (sOutboundNavigationTarget) {
309
+ var oManifestEntry = oController.getOwnerComponent().getAppComponent().getManifestEntry("sap.app");
310
+ return oManifestEntry.crossNavigation.outbounds[sOutboundNavigationTarget];
336
311
  }
337
312
 
338
- // Opens the given context in a new tab
339
- function fnOpenContextInNewTab (oContext, oUrlParser, sFLPUrl, oAppComponent) {
340
- // Construct URL object from FLP URL
341
- var oFLPUrl = new URL(sFLPUrl);
342
- // Get the hash from URL object
343
- var sHash = oFLPUrl.hash;
344
- // Parse the hash and update "appSpecificRoute" with the calculated target path.
345
- // Then, reconstruct the hash with updated value.
346
- var oHash = oUrlParser.parseShellHash(sHash);
347
- oHash.appSpecificRoute = fnConstructTargetAppSpecificRoute(oContext, oAppComponent, oHash.appSpecificRoute);
348
- sHash = oUrlParser.constructShellHash(oHash);
349
- // Update the hash on the FLP URL and reconstruct the URL
350
- oFLPUrl.hash = sHash;
351
- var sTargetUrl = oFLPUrl.toString();
352
- //Open the new window with the target URL
353
- openWindow(sTargetUrl);
313
+ function fnCrossAppNavErrorHandler(oContext, oError) {
314
+ oLogger.error("Error while opening the context " + oContext.getPath() + "in new tab: " + oError);
354
315
  }
355
316
 
356
317
  /**
@@ -367,23 +328,17 @@ sap.ui.define([
367
328
  return;
368
329
  }
369
330
 
370
- var oAppComponent = oController.getOwnerComponent().getAppComponent();
371
- var UShellContainer = sap.ui.require("sap/ushell/Container");
372
- var oUrlParsingPromise = UShellContainer.getServiceAsync("URLParsing");
373
- var oFLPUrlPromise = UShellContainer.getFLPUrlAsync(true);
374
- // If the table has any pending changes, synchronize the draft before navigation.
375
331
  var oSynchronizeDraftPromise = oSourceControl.getModel().hasPendingChanges() ? oTemplateUtils.oServices.oApplicationController.synchronizeDraftAsync() : Promise.resolve();
376
-
377
- Promise.all([oUrlParsingPromise, oFLPUrlPromise, oSynchronizeDraftPromise]).then(function (aResults) {
378
- var oUrlParser = aResults[0];
379
- var sFLPUrl = aResults[1];
380
-
332
+ oSynchronizeDraftPromise.then(function () {
381
333
  aNavigableContexts.forEach(function (oContext) {
382
- fnOpenContextInNewTab(oContext, oUrlParser, sFLPUrl, oAppComponent);
334
+ if (oOutbound) {
335
+ var fnHandleError = fnCrossAppNavErrorHandler.bind(null, oContext);
336
+ oTemplateUtils.oCommonEventHandlers.navigateIntentOnNewTab(oOutbound, oContext, oState.oSmartFilterbar, fnHandleError);
337
+ } else {
338
+ oTemplateUtils.oCommonUtils.openContextInNewTabFromListItem(oContext);
339
+ }
383
340
  });
384
- }).catch(function (oError) {
385
- oLogger.error("Error while opening in new tab", oError);
386
- });
341
+ });
387
342
  }
388
343
 
389
344
  /**
@@ -394,7 +349,7 @@ sap.ui.define([
394
349
  * a. Navigation is not supported by the table
395
350
  * b. Direct edit flow (when the edit icon is pressed on row, the object is opened with draft record) is configured.
396
351
  * c. The controller is configured with onListNavigationExtension (i.e custom navigation logic written by app).
397
- * //TODO: These negative scenarios need to be revisited
352
+ * d. If ushell container is unavailable
398
353
  *
399
354
  * @param {FocusInfo} oFocusInfo
400
355
  * @returns {Promise<Function|undefined>} Promise which resolves the handler method
@@ -406,7 +361,8 @@ sap.ui.define([
406
361
 
407
362
  var bDirectEdit = oTemplateUtils.oServices.oApplication.getEditFlowOfRoot() === "direct";
408
363
  var bOnListNavigationExtensionFound = oController.hasOwnProperty("onListNavigationExtension");
409
- if (!bNavigationSupported || bDirectEdit || bOnListNavigationExtensionFound) {
364
+ var UshellContainer = sap.ui.require("sap/ushell/Container");
365
+ if (!bNavigationSupported || bDirectEdit || bOnListNavigationExtensionFound || !UshellContainer) {
410
366
  return;
411
367
  }
412
368
 
@@ -698,7 +698,8 @@ sap.ui.define(["sap/ui/base/Object", "sap/f/FlexibleColumnLayoutSemanticHelper",
698
698
  isListAndFirstEntryLoadedOnStartup: isListAndFirstEntryLoadedOnStartup,
699
699
  setStoredTargetLayoutToFullscreen: setStoredTargetLayoutToFullscreen,
700
700
  adaptAppStatesForExternalNavigation: fnAdaptAppStatesForExternalNavigation,
701
- willBeOpenedInFullscreen: fnWillBeOpenedInFullscreen
701
+ willBeOpenedInFullscreen: fnWillBeOpenedInFullscreen,
702
+ getFullscreenLayout: getFullscreenLayout
702
703
  };
703
704
  }
704
705
 
@@ -76,9 +76,10 @@ sap.ui.define(["sap/ui/base/Object",
76
76
  "sap/suite/ui/generic/template/lib/navigation/routingHelper",
77
77
  "sap/suite/ui/generic/template/lib/navigation/startupParameterHelper",
78
78
  "sap/suite/ui/generic/template/lib/TemplateComponent",
79
- "sap/base/strings/whitespaceReplacer"
79
+ "sap/base/strings/whitespaceReplacer",
80
+ "sap/ui/util/openWindow"
80
81
  ], function(BaseObject, extend, isEmptyObject, HashChanger, History, coreLibrary, controlHelper, FeLogger, jsonHelper, oDataModelHelper, ProcessObserver, Queue, testableHelper, CRUDHelper, MessageUtils, routingHelper, startupParameterHelper,
81
- TemplateComponent, whitespaceReplacer) {
82
+ TemplateComponent, whitespaceReplacer, openWindow) {
82
83
  "use strict";
83
84
  var sClassName = "lib.navigation.NavigationController";
84
85
  var oLogger = new FeLogger(sClassName).getLogger();
@@ -1670,6 +1671,67 @@ sap.ui.define(["sap/ui/base/Object",
1670
1671
  oTemplateContract.oBusyHelper.setBusy(oRet, undefined, undefined, oTargetIdentityInfo.willShowPlaceholder);
1671
1672
  return oRet;
1672
1673
  }
1674
+
1675
+ // Opens the context in new tab
1676
+ function fnOpenContextInNewTab(oSourceNode, oNavigationContext) {
1677
+ var oTargetIdentityInfo = getTargetIdentityInfoForContext({ treeNode: oSourceNode }, oNavigationContext, true, false);
1678
+ var oTargetIdentityPromise = oTargetIdentityInfo.promise;
1679
+ return oTargetIdentityPromise.then(function(oTargetIdentity){
1680
+ // Construct the query params
1681
+ var mQueryParameters = {};
1682
+ // In case FCL layout is supported by app, the target context should be opened in full screen mode.
1683
+ // So, calculate the full screen layout type and add it as a query param.
1684
+ var sFCLLayout = oTemplateContract.oFlexibleColumnLayoutHandler && oTemplateContract.oFlexibleColumnLayoutHandler.getFullscreenLayout(oTargetIdentity.treeNode.fCLLevel);
1685
+ if (sFCLLayout) {
1686
+ mQueryParameters["FCLLayout"] = sFCLLayout;
1687
+ }
1688
+ // Get the route information from target identity
1689
+ var oRouterInput = fnGetRouterInput(oTargetIdentity.treeNode, oTargetIdentity.keys, mQueryParameters);
1690
+ // Construct the app specific route URL from route name and parameters
1691
+ var sTargetAppSpecificRoute = oNavigationControllerProxy.oRouter.getURL(oRouterInput.route, oRouterInput.parameters);
1692
+ // Add the prefix
1693
+ var sRoutePrefix = sTargetAppSpecificRoute.startsWith("/") ? "&" : "&/";
1694
+ sTargetAppSpecificRoute = sRoutePrefix + sTargetAppSpecificRoute;
1695
+ // Construct the fully qualified URL updated with the target app route
1696
+ return fnConstructUrlFromRoute(sTargetAppSpecificRoute);
1697
+ }).then(function (sTargetUrl) {
1698
+ // Open the URL in new tab/window
1699
+ openWindow(sTargetUrl);
1700
+ }).catch(function (oError) {
1701
+ oLogger.error("Error while opening the context '" + oNavigationContext.getPath() + "' in a new tab: " + oError);
1702
+ });
1703
+ }
1704
+
1705
+ // Constructs the fully qualified URL with the given app specific route.
1706
+ function fnConstructUrlFromRoute(sTargetAppSpecificRoute) {
1707
+ var UShellContainer = sap.ui.require("sap/ushell/Container");
1708
+
1709
+ if (!UShellContainer) {
1710
+ return Promise.reject("Unable to proceed as 'sap/ushell/Container' is not found!");
1711
+ }
1712
+ //Encode the route
1713
+ sTargetAppSpecificRoute = encodeURI(sTargetAppSpecificRoute);
1714
+
1715
+ var oUrlParsingPromise = UShellContainer.getServiceAsync("URLParsing");
1716
+ var oFLPUrlPromise = UShellContainer.getFLPUrlAsync(true);
1717
+ return Promise.all([oUrlParsingPromise, oFLPUrlPromise]).then(function (aResults) {
1718
+ var oUrlParser = aResults[0];
1719
+ var sFLPUrl = aResults[1];
1720
+
1721
+ // Construct URL object from FLP URL
1722
+ var oFLPUrl = new URL(sFLPUrl);
1723
+ // Get the hash from URL object
1724
+ var sHash = oFLPUrl.hash;
1725
+ // Parse the hash and update "appSpecificRoute" with "sTargetAppSpecificRoute"
1726
+ var oHash = oUrlParser.parseShellHash(sHash);
1727
+ oHash.appSpecificRoute = sTargetAppSpecificRoute;
1728
+ // Then, reconstruct the hash with updated value.
1729
+ sHash = oUrlParser.constructShellHash(oHash);
1730
+ // Update the hash on the FLP URL and reconstruct the URL
1731
+ oFLPUrl.hash = sHash;
1732
+ return oFLPUrl.toString();
1733
+ });
1734
+ }
1673
1735
 
1674
1736
  // This function is called when only tables could be found as focus target for the message oMessage.
1675
1737
  // sFullTarget is one of the full targets defined for this message.
@@ -2834,13 +2896,44 @@ sap.ui.define(["sap/ui/base/Object",
2834
2896
  return true;
2835
2897
  }
2836
2898
  // Now handle the case of an internal navigation which was not controlled by FE (e.g. browser back, navigation menu, bookmark){
2837
- var oRouteInfo = oNavigationControllerProxy.oRouter.getRouteInfoByHash(oShellContext.innerAppRoute);
2899
+ var oRouteInfo = fnGetRouteInfoByHash(oNavigationControllerProxy.oRouter, oShellContext.innerAppRoute);
2900
+ if (!oRouteInfo) {
2901
+ return false;
2902
+ }
2838
2903
  var oTargetIdentity = fnRouteConfigToIdentity(oRouteInfo.name, oRouteInfo.arguments);
2839
2904
  return oTargetIdentity.treeNode !== oCurrentIdentity.treeNode || oTargetIdentity.keys.some(function(sKey, i){
2840
2905
  return sKey !== oCurrentIdentity.keys[i];
2841
2906
  });
2842
2907
  }
2843
2908
 
2909
+ /**
2910
+ * From the given app route hash, returns the route information.
2911
+ * Also takes nested app route hash as input
2912
+ * @param {sap.m.routing.Router|sap.f.routing.Router} oRouter
2913
+ * @param {string} sHash
2914
+ * @returns {sap.ui.core.routing.RouteInfo|undefined} An object containing the route <code>name</code> and the <code>arguments</code>
2915
+ * or <code>undefined</code>
2916
+ */
2917
+ function fnGetRouteInfoByHash(oRouter, sHash) {
2918
+ // If route info found by the input hash, just return it
2919
+ var oRouteInfo = oRouter.getRouteInfoByHash(sHash);
2920
+ if (oRouteInfo) {
2921
+ return oRouteInfo;
2922
+ }
2923
+ // Nested app route: Split the hash by "&/" and get the hash belongs to inner most app route (last index)
2924
+ // Then, check whether the route info found by inner most hash.
2925
+ var aNestedAppRoutes = sHash.split("&/");
2926
+ var sInnerMostHash = aNestedAppRoutes[aNestedAppRoutes.length - 1];
2927
+ oRouteInfo = oRouter.getRouteInfoByHash(sInnerMostHash);
2928
+ if (oRouteInfo) {
2929
+ return oRouteInfo;
2930
+ }
2931
+ // In case the inner most app route is prefixed with app name, just omit the app name and try to get route info from remaining hash.
2932
+ sInnerMostHash = sInnerMostHash.substring(sInnerMostHash.indexOf("/"));
2933
+ oRouteInfo = oRouter.getRouteInfoByHash(sInnerMostHash);
2934
+ return oRouteInfo;
2935
+ }
2936
+
2844
2937
  function getEditScopeHeaderNode(oTreeNode){
2845
2938
  var oMainNode = oTemplateContract.oApplicationProxy.getAncestralNode(oTreeNode, 1);
2846
2939
  return oMainNode.isDraft ? oMainNode : oTreeNode;
@@ -2952,12 +3045,13 @@ sap.ui.define(["sap/ui/base/Object",
2952
3045
  oNavigationControllerProxy.userHasAcceptedDataLoss = fnUserHasAcceptedDataLoss;
2953
3046
  oNavigationControllerProxy.unwantedDataLossPossible = fnUnwantedDataLossPossible;
2954
3047
  oNavigationControllerProxy.isBackLeavingTheEditScope = isBackLeavingTheEditScope;
2955
-
3048
+ oNavigationControllerProxy.openContextInNewTab = fnOpenContextInNewTab;
2956
3049
  // Make private function accessible to unit tests
2957
3050
  /* eslint-disable */
2958
3051
  var fnCreateTemplateComponent = testableHelper.testable(fnCreateTemplateComponent, "createTemplateComponent");
2959
3052
  var getParsedShellHashFromFLP = testableHelper.testable(getParsedShellHashFromFLP, "getParsedShellHashFromFLP");
2960
3053
  var fnPreloadComponent = testableHelper.testable(fnPreloadComponent, "preloadComponent");
3054
+ var fnGetRouteInfoByHash = testableHelper.testable(fnGetRouteInfoByHash, "getRouteInfoByHash");
2961
3055
 
2962
3056
  // Note: Function createHostView will be added by routingHelper.
2963
3057
  // Allow to mock this by unit tests
@@ -3055,7 +3149,7 @@ sap.ui.define(["sap/ui/base/Object",
3055
3149
  * @param {sap.suite.ui.generic.template.lib.AppComponent} oAppComponent The AppComponent instance
3056
3150
  * @public
3057
3151
  * @extends sap.ui.base.Object
3058
- * @version 1.124.4
3152
+ * @version 1.124.6
3059
3153
  * @since 1.30.0
3060
3154
  * @alias sap.suite.ui.generic.template.lib.NavigationController
3061
3155
  */
@@ -62,7 +62,7 @@ sap.ui.define([
62
62
  interfaces: [],
63
63
  controls: [],
64
64
  elements: [],
65
- version: "1.124.4",
65
+ version: "1.124.6",
66
66
  extensions: {
67
67
  //Configuration used for rule loading of Support Assistant
68
68
  "sap.ui.support": {
@@ -257,7 +257,9 @@
257
257
  </ColumnListItem>
258
258
  </items>
259
259
  <contextMenu>
260
- <core:Fragment fragmentName="sap.suite.ui.generic.template.fragments.SmartControlContextMenu" type="XML"/>
260
+ <template:with path="entitySet>" var="listEntitySet">
261
+ <core:Fragment fragmentName="sap.suite.ui.generic.template.fragments.SmartControlContextMenu" type="XML"/>
262
+ </template:with>
261
263
  </contextMenu>
262
264
  <dependents>
263
265
  <plugins.ContextMenuSetting scope="Selection"/>