@sapui5/sap.suite.ui.generic.template 1.122.2 → 1.123.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 (147) 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/controller/ControllerImplementation.js +19 -24
  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/controller/ControllerImplementation.js +22 -21
  7. package/src/sap/suite/ui/generic/template/ListReport/controller/MultipleViewsHandler.js +8 -3
  8. package/src/sap/suite/ui/generic/template/ListReport/manifest.json +1 -1
  9. package/src/sap/suite/ui/generic/template/ListReport/view/fragments/MultiEditDialog.fragment.xml +12 -1
  10. package/src/sap/suite/ui/generic/template/ObjectPage/controller/ControllerImplementation.js +25 -151
  11. package/src/sap/suite/ui/generic/template/ObjectPage/controller/PasteHandler.js +357 -0
  12. package/src/sap/suite/ui/generic/template/ObjectPage/controller/SectionTitleHandler.js +8 -8
  13. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n.properties +12 -0
  14. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_ar.properties +8 -0
  15. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_bg.properties +8 -0
  16. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_ca.properties +8 -0
  17. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_cnr.properties +8 -0
  18. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_cs.properties +8 -0
  19. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_cy.properties +8 -0
  20. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_da.properties +8 -0
  21. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_de.properties +8 -0
  22. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_el.properties +8 -0
  23. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_en.properties +8 -0
  24. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_en_GB.properties +8 -0
  25. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_en_US_saprigi.properties +8 -0
  26. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_es.properties +8 -0
  27. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_es_MX.properties +8 -0
  28. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_et.properties +8 -0
  29. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_fi.properties +8 -0
  30. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_fr.properties +8 -0
  31. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_fr_CA.properties +17 -9
  32. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_hi.properties +8 -0
  33. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_hr.properties +8 -0
  34. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_hu.properties +8 -0
  35. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_id.properties +8 -0
  36. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_it.properties +8 -0
  37. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_iw.properties +8 -0
  38. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_ja.properties +8 -0
  39. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_kk.properties +8 -0
  40. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_ko.properties +8 -0
  41. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_lt.properties +8 -0
  42. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_lv.properties +8 -0
  43. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_mk.properties +8 -0
  44. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_ms.properties +8 -0
  45. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_nl.properties +8 -0
  46. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_no.properties +8 -0
  47. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_pl.properties +8 -0
  48. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_pt.properties +8 -0
  49. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_pt_PT.properties +8 -0
  50. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_ro.properties +8 -0
  51. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_ru.properties +8 -0
  52. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_sh.properties +8 -0
  53. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_sk.properties +8 -0
  54. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_sl.properties +8 -0
  55. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_sr.properties +8 -0
  56. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_sv.properties +8 -0
  57. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_th.properties +8 -0
  58. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_tr.properties +8 -0
  59. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_uk.properties +8 -0
  60. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_vi.properties +8 -0
  61. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_zh_CN.properties +8 -0
  62. package/src/sap/suite/ui/generic/template/ObjectPage/i18n/i18n_zh_TW.properties +8 -0
  63. package/src/sap/suite/ui/generic/template/ObjectPage/manifest.json +1 -1
  64. package/src/sap/suite/ui/generic/template/ObjectPage/templateSpecificPreparationHelper.js +1 -5
  65. package/src/sap/suite/ui/generic/template/ObjectPage/view/fragments/Actions.fragment.xml +12 -0
  66. package/src/sap/suite/ui/generic/template/ObjectPage/view/fragments/ExtensionFacetLayout.fragment.xml +2 -1
  67. package/src/sap/suite/ui/generic/template/ObjectPage/view/fragments/SmartTable.fragment.xml +2 -0
  68. package/src/sap/suite/ui/generic/template/QuickCreate/manifest.json +1 -1
  69. package/src/sap/suite/ui/generic/template/QuickCreate/view/QuickCreate.controller.js +2 -7
  70. package/src/sap/suite/ui/generic/template/QuickView/manifest.json +1 -1
  71. package/src/sap/suite/ui/generic/template/designtime/ObjectPage.designtime.js +3 -0
  72. package/src/sap/suite/ui/generic/template/fragments/CreateWithDialog.fragment.xml +12 -1
  73. package/src/sap/suite/ui/generic/template/fragments/SmartControlContextMenu.fragment.xml +7 -1
  74. package/src/sap/suite/ui/generic/template/fragments/SmartTableResponsiveTableCommons.fragment.xml +0 -2
  75. package/src/sap/suite/ui/generic/template/fragments/SmartTableUiTableCommons.fragment.xml +3 -3
  76. package/src/sap/suite/ui/generic/template/genericUtilities/filterHelper.js +47 -28
  77. package/src/sap/suite/ui/generic/template/genericUtilities/metadataAnalyser.js +20 -0
  78. package/src/sap/suite/ui/generic/template/js/AnnotationHelper.js +32 -25
  79. package/src/sap/suite/ui/generic/template/lib/AdaptiveCardHelper.js +27 -13
  80. package/src/sap/suite/ui/generic/template/lib/AppComponent.js +21 -5
  81. package/src/sap/suite/ui/generic/template/lib/Application.js +4 -1
  82. package/src/sap/suite/ui/generic/template/lib/CommonUtils.js +5 -5
  83. package/src/sap/suite/ui/generic/template/lib/ComponentUtils.js +0 -1
  84. package/src/sap/suite/ui/generic/template/lib/ContextMenuHandler.js +257 -60
  85. package/src/sap/suite/ui/generic/template/lib/MessageUtils.js +28 -0
  86. package/src/sap/suite/ui/generic/template/lib/PageLeaveHandler.js +0 -1
  87. package/src/sap/suite/ui/generic/template/lib/ShareUtils.js +197 -67
  88. package/src/sap/suite/ui/generic/template/lib/StableIdDefinition.js +3 -0
  89. package/src/sap/suite/ui/generic/template/lib/i18n/i18n.properties +5 -5
  90. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ar.properties +3 -3
  91. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_bg.properties +3 -3
  92. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ca.properties +3 -3
  93. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cnr.properties +3 -3
  94. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cs.properties +3 -3
  95. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cy.properties +3 -3
  96. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_da.properties +3 -3
  97. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_de.properties +3 -3
  98. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_el.properties +3 -3
  99. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en.properties +3 -3
  100. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_GB.properties +3 -3
  101. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_US_saprigi.properties +3 -3
  102. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_es.properties +3 -3
  103. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_es_MX.properties +3 -3
  104. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_et.properties +3 -3
  105. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fi.properties +3 -3
  106. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fr.properties +3 -3
  107. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fr_CA.properties +14 -14
  108. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hi.properties +3 -3
  109. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hr.properties +3 -3
  110. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hu.properties +3 -3
  111. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_id.properties +3 -3
  112. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_it.properties +3 -3
  113. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_iw.properties +3 -3
  114. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ja.properties +3 -3
  115. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_kk.properties +3 -3
  116. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ko.properties +3 -3
  117. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_lt.properties +3 -3
  118. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_lv.properties +3 -3
  119. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_mk.properties +3 -3
  120. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ms.properties +3 -3
  121. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_nl.properties +3 -3
  122. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_no.properties +3 -3
  123. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pl.properties +3 -3
  124. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pt.properties +3 -3
  125. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pt_PT.properties +3 -3
  126. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ro.properties +3 -3
  127. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ru.properties +3 -3
  128. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sh.properties +3 -3
  129. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sk.properties +3 -3
  130. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sl.properties +3 -3
  131. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sr.properties +3 -3
  132. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sv.properties +3 -3
  133. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_th.properties +3 -3
  134. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_tr.properties +3 -3
  135. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_uk.properties +3 -3
  136. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_vi.properties +3 -3
  137. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_zh_CN.properties +3 -3
  138. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_zh_TW.properties +3 -3
  139. package/src/sap/suite/ui/generic/template/lib/insights/InsightsFECardProvider.js +10 -3
  140. package/src/sap/suite/ui/generic/template/lib/insights/InsightsHandler.js +2 -1
  141. package/src/sap/suite/ui/generic/template/lib/multipleViews/MultipleTablesModeHelper.js +4 -3
  142. package/src/sap/suite/ui/generic/template/lib/multipleViews/MultipleViewsHandler.js +6 -14
  143. package/src/sap/suite/ui/generic/template/lib/multipleViews/SingleTableModeHelper.js +13 -5
  144. package/src/sap/suite/ui/generic/template/lib/navigation/NavigationController.js +1 -1
  145. package/src/sap/suite/ui/generic/template/lib/presentationControl/SmartTableHandler.js +46 -2
  146. package/src/sap/suite/ui/generic/template/library.js +1 -1
  147. package/src/sap/suite/ui/generic/template/listTemplates/controller/MultipleViewsHandler.js +8 -3
@@ -1,17 +1,48 @@
1
1
  sap.ui.define([
2
+ "sap/base/util/extend",
3
+ "sap/base/util/ObjectPath",
4
+ "sap/f/library",
5
+ "sap/m/MessageBox",
6
+ "sap/suite/ui/generic/template/genericUtilities/controlHelper",
7
+ "sap/suite/ui/generic/template/genericUtilities/FeLogger",
2
8
  "sap/ui/base/Object",
3
9
  "sap/ui/base/Event",
4
- "sap/base/util/extend",
5
- "sap/suite/ui/generic/template/genericUtilities/controlHelper"
6
- ], function(BaseObject, Event, extend, controlHelper) {
10
+ "sap/ui/util/openWindow"
11
+ ], function (extend, ObjectPath, fioriLibrary, MessageBox, controlHelper, FeLogger, BaseObject, Event, openWindow) {
7
12
  "use strict";
8
13
 
9
14
  /* This class provides generic functionality for handling of the context menu for one smart control (oSourceControl).
10
15
  * Note that this is currently restricted to the case that oSourceControl is a table.
11
16
  * oConfiguration is an object which contains logic which is specific to the floorplan using this functionality.
12
17
  */
18
+ var oLogger = new FeLogger("lib.ContextMenuHandler").getLogger();
19
+ // shortcut for sap.f.LayoutType
20
+ var LayoutType = fioriLibrary.LayoutType;
21
+
22
+ // Constants
23
+ var MAX_RECORDS_OPEN_IN_NEW_TAB = 10;
24
+
13
25
  function getMethods(oController, oTemplateUtils, oState, oSourceControl, oConfiguration) {
14
26
 
27
+ //Type definitions
28
+
29
+ /**
30
+ * @typedef {Object} FocusInfo Information about the applicable records for the context menu
31
+ * @property {sap.ui.model.Context} focussedBindingContext - Binding context of the currently focussed row
32
+ * @property {Array<sap.ui.model.Context>} applicableContexts - Array of contexts applicable to the context menu
33
+ * @property {boolean} doesApplicableEqualSelected - If the focussed row is part of selected rows
34
+ */
35
+
36
+ /**
37
+ * @typedef {Object} ContextMenuEntry Context menu entry
38
+ * @property {string} text - Text
39
+ * @property {string} icon - Icon
40
+ * @property {string} key - Uniquely identifiable key
41
+ * @property {boolean} enabled - Is the entry enabled
42
+ * @property {Array<ContextMenuEntry>} children - Child entries
43
+ * @property {Promise<Function|undefined>} handlerPromise - A promise which resolves the handler method for the current entry
44
+ */
45
+
15
46
  var oView = oController.getView();
16
47
  var oTemplatePrivateModel = oView.getModel("_templPriv");
17
48
  var oCommonUtils = oTemplateUtils.oCommonUtils;
@@ -33,21 +64,55 @@ sap.ui.define([
33
64
  var mHandlers; // maps keys of context menu entries to handler functions for the corresponding entry
34
65
  var iCreatedMenuItemsCounter = 0; // increased whenever a new MenuItem is being created In fnAddMenuItem). Used to generate a key for mHandlers.
35
66
 
36
- // add meta data of a menu item to the list of items (aItems).
37
- // sText and sIcon represent the text and the icon of the menu entry.
38
- // bStartsSection is a boolean telling whether the entry starts a new section with the menu (will be ignored for the first entry of aItems).
39
- // oHandlerPromise is optional. If faulty the corresponding menu item will never be resolved.
40
- function fnAddMenuItem(sPathToItems, aItems, sText, sIcon, bStartsSection, oHandlerPromise){
67
+ /**
68
+ * The method does the following
69
+ * - Adds an entry (menu item) to the context menu.
70
+ * - Waits for the handler promise to be resolved and
71
+ * - Enables the menu item only if it has the handler method
72
+ * - Registers the press event handler to the "mHandlers"
73
+ * - If the current menu item contains child entries, it waits for all the children handler promises to be resolved and
74
+ * - Enables the child menu items based on the availability of respective handlers
75
+ * - Enables the current menu item if at least one child item is enabled.
76
+ *
77
+ * Note: When the current entry has children, please pass "oHandlerPromise" as null.
78
+ *
79
+ * @param {string} sPathToItems Binding path for the items
80
+ * @param {Array<ContextMenuEntry>} aItems Array which stores all context menu entries
81
+ * @param {string} sText Text of the context menu item
82
+ * @param {string} sIcon Icon for the context menu item
83
+ * @param {boolean} bStartsSection Defines whether a visual separator should be rendered before the item
84
+ * @param {Promise<Function|boolean>} oHandlerPromise Optional parameter. A promise which resolves the press handler method to the current menu item
85
+ * @param {Array<ContextMenuEntry>} aChildren Child entries for the current menu item
86
+ */
87
+ function fnAddMenuItem(sPathToItems, aItems, sText, sIcon, bStartsSection, oHandlerPromise, aChildren){
41
88
  iCreatedMenuItemsCounter++;
42
89
  var sKey = "ContextMenuKey" + iCreatedMenuItemsCounter;
90
+ var iPosition = aItems.length;
91
+ aChildren = aChildren || [];
43
92
  if (oHandlerPromise){
44
- var iPosition = aItems.length;
45
93
  oHandlerPromise.then(function(fnHandler){
46
94
  if (fnHandler){
47
95
  mHandlers[sKey] = fnHandler;
48
96
  oTemplatePrivateModel.setProperty(sPathToItems + "/" + iPosition + "/enabled", true);
49
97
  }
50
98
  });
99
+ } else if (aChildren.length > 0) {
100
+ var aHandlerPromisesForChildren = aChildren.map(function (oMenuItem){
101
+ return oMenuItem.handlerPromise;
102
+ });
103
+ Promise.all(aHandlerPromisesForChildren).then(function (aHandlersForChildren) {
104
+ var bParentEnabled = false;
105
+ // Enabling the child menu items
106
+ aHandlersForChildren.forEach(function (fnHandler, iIndex) {
107
+ if (fnHandler) {
108
+ oTemplatePrivateModel.setProperty(sPathToItems + "/" + iPosition + "/children/" + iIndex + "/enabled", true);
109
+ // Parent is enabled if at least one child is enabled
110
+ bParentEnabled = true;
111
+ }
112
+ });
113
+ // Enabling the parent
114
+ oTemplatePrivateModel.setProperty(sPathToItems + "/" + iPosition + "/enabled", bParentEnabled);
115
+ });
51
116
  }
52
117
  bStartsSection = bStartsSection && aItems.length > 0;
53
118
  aItems.push({
@@ -55,7 +120,9 @@ sap.ui.define([
55
120
  icon: sIcon,
56
121
  key: sKey,
57
122
  enabled: false,
58
- startsSection: bStartsSection
123
+ startsSection: bStartsSection,
124
+ children: aChildren,
125
+ handlerPromise: oHandlerPromise
59
126
  });
60
127
  }
61
128
 
@@ -90,11 +157,27 @@ sap.ui.define([
90
157
 
91
158
  // Invokes the "press" event handler of breakout control
92
159
  function fnExecuteCustomActionByPressEvent (oBreakoutControlData, oToolbarControl) {
160
+ // Get the press handler name from the "press" property of action from manifest
93
161
  var sPressHandlerName = oBreakoutControlData.press;
162
+ var fnEventHandler = null;
163
+ // Case 1: If the extension controller extends "sap.ui.core.mvc.ControllerExtension",
164
+ // the press handler name would be in ".extension.controller_extension_name." format.
165
+ // Here, event handler function is derived using ObjectPath.
166
+ //
167
+ // Case 2: If the extension controller extends "sap.ui.core.mvc.Controller",
168
+ // then the press property from manifest has the event handler name.
169
+ // Here, event handler function can be directly obtained from oController.
170
+ if (sPressHandlerName.startsWith(".")) {
171
+ // Omit the leading "." to find out the press handler path
172
+ var sPressHandlerPath = sPressHandlerName.substring(1);
173
+ fnEventHandler = ObjectPath.create(sPressHandlerPath, oController);
174
+ } else {
175
+ fnEventHandler = oController[sPressHandlerName];
176
+ }
94
177
  var oEventSource = oToolbarControl;
95
178
  // Creating a custom event with toolbar control as source
96
179
  var oPressEvent = new Event("press", oEventSource);
97
- oController[sPressHandlerName].apply(oController, [oPressEvent]);
180
+ fnEventHandler && fnEventHandler.apply(oController, [oPressEvent]);
98
181
  }
99
182
 
100
183
  // Returns the handler for standard action
@@ -130,7 +213,9 @@ sap.ui.define([
130
213
  }
131
214
 
132
215
  function fnAddToolbarButtonToContextMenu(sPathToItems, oFocusInfo, oToolbarControlsData, aItems, oButton, bStartsNewSection){
133
- var sButtonId = oView.getLocalId(oButton.getId());
216
+ // If button has the stable id, find local id using "oButton.getId()".
217
+ // Otherwise, if the button was created using design time adaption, use the custom data "originalButtonId" to find local id.
218
+ var sButtonId = oView.getLocalId(oButton.getId()) || oView.getLocalId(oButton.data("originalButtonId"));
134
219
  // In the multi table multi view scenario, the toolbar button id is suffixed with icon tab bar's current key.
135
220
  var oMultipleViewsHandler = oState.oMultipleViewsHandler;
136
221
  var sButtonIdSuffix = oMultipleViewsHandler.getMode && oMultipleViewsHandler.getMode() === "multi" ? oState.oMultipleViewsHandler.getSelectedKey() : "";
@@ -162,6 +247,28 @@ sap.ui.define([
162
247
  return false;
163
248
  }
164
249
 
250
+ // Adds the menu button to context menu and creates a sub-menu for the child entries
251
+ function fnAddMenuButtonToContextMenu(sPathToItems, oFocusInfo, oToolbarControlsData, aItems, oMenuButton, bStartsNewSection) {
252
+ var aMenuItems = oMenuButton.getMenu().getItems();
253
+
254
+ var aChildContextMenuEntries = [];
255
+ aMenuItems.forEach(function (oMenuItem) {
256
+ var bStartsSectionOnSubMenu = oMenuItem.getStartsSection();
257
+ fnAddToolbarButtonToContextMenu(sItemsPath, oFocusInfo, oToolbarControlsData, aChildContextMenuEntries, oMenuItem, bStartsSectionOnSubMenu);
258
+ });
259
+
260
+ if (aChildContextMenuEntries.length > 0) {
261
+ fnAddMenuItem(sPathToItems, aItems, oMenuButton.getText(), oMenuButton.getIcon(), bStartsNewSection, null, aChildContextMenuEntries);
262
+ return true;
263
+ }
264
+ return false;
265
+ }
266
+
267
+ /**
268
+ * Adds the toolbar buttons and menu buttons to the context menu
269
+ * @param {FocusInfo} oFocusInfo Focus info
270
+ * @param {Array<ContextMenuEntry>} aItems Array of context menu items
271
+ */
165
272
  function fnAddToolbarButtonsToContextMenu(oFocusInfo, aItems){
166
273
  var aStandardActions = oCommonUtils.getToolbarCustomData(oSourceControl);
167
274
  var mBreakoutActions = oCommonUtils.getBreakoutActions(oSourceControl);
@@ -180,78 +287,168 @@ sap.ui.define([
180
287
  }
181
288
  if (controlHelper.isButton(oToolbarEntry)){
182
289
  bFirst = !fnAddToolbarButtonToContextMenu(sItemsPath, oFocusInfo, oToolbarControlsData, aItems, oToolbarEntry, bFirst) && bFirst;
290
+ } else if (controlHelper.isMenuButton(oToolbarEntry)){
291
+ bFirst = !fnAddMenuButtonToContextMenu(sItemsPath, oFocusInfo, oToolbarControlsData, aItems, oToolbarEntry, bFirst) && bFirst;
183
292
  }
184
293
  });
185
294
  }
186
- /*
187
- function fnAddInlineActionsToContextMenu(oFocusInfo, aItems){
188
- if (oFocusInfo.applicableContexts.length !== 1){
189
- return;
295
+
296
+ /********************************************************
297
+ * Methods related to "Open in new tab" functionality
298
+ ********************************************************/
299
+
300
+ // Currently the inactive contexts (inline creation rows which are untouched and missing required props)
301
+ // are considered as non navigable contexts
302
+ function fnIsContextNavigable (oContext) {
303
+ var bIsEmptyRow = oContext.isInactive();
304
+ //TODO: add other conditions if necessary
305
+ return !bIsEmptyRow;
306
+ }
307
+
308
+ /**
309
+ * Constructs the app specific route for the target to be opened on new tab. The target route consists of
310
+ * 1. Deep path of the context
311
+ * 2. URL parameters of the current app specific route.
312
+ *
313
+ * Note: All the URL parameters from source are retained in the target except the "FCLLayout".
314
+ * The target "FCLLayout" is calculated by the below logic:
315
+ *
316
+ * If the app supports FCL.
317
+ * - If the current page is LR (iViewLevel = 0), the target layout is "MidColumnFullScreen"
318
+ * - If the current page is OP (iViewLevel > 0), the target layout is "EndColumnFullScreen"
319
+ *
320
+ * @returns {string} target path
321
+ */
322
+ function fnConstructTargetAppSpecificRoute (oContext, oAppComponent, sSrcAppSpecificRoute) {
323
+ var sUrlParams = sSrcAppSpecificRoute.includes("?") ? sSrcAppSpecificRoute.substring(sSrcAppSpecificRoute.indexOf("?")) : "";
324
+ var oUrlParams = new URLSearchParams(sUrlParams);
325
+ var sDeepPath = oContext.getDeepPath();
326
+ var sTargetPathPrefix = sDeepPath.startsWith("/") ? "&" : "&/";
327
+ // If the app supports FCL, the object page should be opened in full screen mode
328
+ if (oAppComponent.getFlexibleColumnLayout()) {
329
+ var iViewLevel = oTemplateUtils.oComponentUtils.getViewLevel();
330
+ var sTargetFCLLayout = iViewLevel === 0 ? LayoutType.MidColumnFullScreen : LayoutType.EndColumnFullScreen;
331
+ // Update "FCLLayout"
332
+ oUrlParams.set("FCLLayout", sTargetFCLLayout);
190
333
  }
191
- var oSelectedContext = oFocusInfo.applicableContexts[0];
192
- var oTableRow = oPresentationControlHandler.getRowForContext(oSelectedContext);
193
- if (oTableRow){
194
- //var bIsFirst = true;
195
- controlHelper.searchInTree(oTableRow, function(oRowEntry){
196
- return false;
197
- if (controlHelper.isButton(oRowEntry)){
198
- oHandlerPromise = Promise.resolve(oRowEntry.getEnabled() && function(){
199
-
200
- });
201
- fnAddMainMenuItem(aItems, oRowEntry.getText(), oRowEntry.getIcon(), bIsFirst, oHandlerPromise);
202
- bIsFirst = false;
203
- return false;
204
- }
205
- });
334
+ return sTargetPathPrefix + sDeepPath + "?" + oUrlParams.toString();
335
+ }
336
+
337
+ // Opens the given context in a new tab
338
+ function fnOpenContextInNewTab (oContext, oUrlParser, sFLPUrl, oAppComponent) {
339
+ // Construct URL object from FLP URL
340
+ var oFLPUrl = new URL(sFLPUrl);
341
+ // Get the hash from URL object
342
+ var sHash = oFLPUrl.hash;
343
+ // Parse the hash and update "appSpecificRoute" with the calculated target path.
344
+ // Then, reconstruct the hash with updated value.
345
+ var oHash = oUrlParser.parseShellHash(sHash);
346
+ oHash.appSpecificRoute = fnConstructTargetAppSpecificRoute(oContext, oAppComponent, oHash.appSpecificRoute);
347
+ sHash = oUrlParser.constructShellHash(oHash);
348
+ // Update the hash on the FLP URL and reconstruct the URL
349
+ oFLPUrl.hash = sHash;
350
+ var sTargetUrl = oFLPUrl.toString();
351
+ //Open the new window with the target URL
352
+ openWindow(sTargetUrl);
353
+ }
354
+
355
+ /**
356
+ * Opens all the eligible contexts in new tab.
357
+ * Also, validates the maximum allowed number of records to be opened.
358
+ * @param {FocusInfo} oFocusInfo
359
+ * @param {Array<sap.ui.model.Context>} aNavigableContexts
360
+ * @returns
361
+ */
362
+ function fnOpenNavigableContextsInNewTab (oFocusInfo, aNavigableContexts) {
363
+ if (oFocusInfo.applicableContexts.length > MAX_RECORDS_OPEN_IN_NEW_TAB) {
364
+ var sWarningMessage = oTemplateUtils.oCommonUtils.getText("T_TABLE_NAVIGATION_TOO_MANY_ITEMS_SELECTED", [MAX_RECORDS_OPEN_IN_NEW_TAB]);
365
+ MessageBox.warning(sWarningMessage);
366
+ return;
206
367
  }
207
368
 
208
- } */
369
+ var oAppComponent = oController.getOwnerComponent().getAppComponent();
370
+ var UShellContainer = sap.ui.require("sap/ushell/Container");
371
+ var oUrlParsingPromise = UShellContainer.getServiceAsync("URLParsing");
372
+ var oFLPUrlPromise = UShellContainer.getFLPUrlAsync(true);
373
+ // If the table has any pending changes, synchronize the draft before navigation.
374
+ var oSynchronizeDraftPromise = oSourceControl.getModel().hasPendingChanges() ? oTemplateUtils.oServices.oApplicationController.synchronizeDraftAsync() : Promise.resolve();
209
375
 
210
- // iExpadMode: 0 = no expad, 1 = in new tab, 2 = in new window
211
- function fnNavigateToContext(oTargetContext, iExpadMode){
376
+ Promise.all([oUrlParsingPromise, oFLPUrlPromise, oSynchronizeDraftPromise]).then(function (aResults) {
377
+ var oUrlParser = aResults[0];
378
+ var sFLPUrl = aResults[1];
212
379
 
380
+ aNavigableContexts.forEach(function (oContext) {
381
+ fnOpenContextInNewTab(oContext, oUrlParser, sFLPUrl, oAppComponent);
382
+ });
383
+ }).catch(function (oError) {
384
+ oLogger.error("Error while opening in new tab", oError);
385
+ });
213
386
  }
214
387
 
388
+ /**
389
+ * Returns the promise which resolves the event handler for "Open in new tab/window" entry.
390
+ *
391
+ * Negative scenario: It just returns without value when anyone of the following condition met.
392
+ * a. Navigation is not supported by the table
393
+ * b. Direct edit flow (when the edit icon is pressed on row, the object is opened with draft record) is configured.
394
+ * c. The controller is configured with onListNavigationExtension (i.e custom navigation logic written by app).
395
+ * //TODO: These negative scenarios need to be revisited
396
+ *
397
+ * @param {FocusInfo} oFocusInfo
398
+ * @returns {Promise<Function|undefined>} Promise which resolves the handler method
399
+ */
400
+ function getHandlePromiseForOpenInNewTab (oFocusInfo) {
401
+ var getHandler = function (bEnabled, oFocusInfo, aNavigableContexts) {
402
+ return bEnabled && fnOpenNavigableContextsInNewTab.bind(null, oFocusInfo, aNavigableContexts);
403
+ };
215
404
 
216
- function getNavigationOptions(oFocusInfo){
217
- var oRet = {};
218
- if (!bNavigationSupported || oFocusInfo.applicableContexts.length !== 1){
219
- return oRet;
405
+ var bDirectEdit = oTemplateUtils.oServices.oApplication.getEditFlowOfRoot() === "direct";
406
+ var bOnListNavigationExtensionFound = oController.hasOwnProperty("onListNavigationExtension");
407
+ if (!bNavigationSupported || bDirectEdit || bOnListNavigationExtensionFound) {
408
+ return;
220
409
  }
221
- var oSelectedContext = oFocusInfo.applicableContexts[0];
222
- oRet.openForEdit = oConfiguration.getOpenForEdit && oConfiguration.getOpenForEdit(oSelectedContext);
223
- if (oRet.openForEdit){ // currently we assume that the options open for edit and open are exclusive
224
- return oRet;
410
+
411
+ // Enable the context menu entry only if at least one navigable context is available
412
+ var aNavigableContexts = oFocusInfo.applicableContexts.filter(fnIsContextNavigable);
413
+ var bEnabled = aNavigableContexts.length > 0;
414
+
415
+ return Promise.resolve(getHandler(bEnabled, oFocusInfo, aNavigableContexts));
416
+ }
417
+
418
+ /**
419
+ * Adds "Open in wew tab/window" entry to context menu
420
+ * @param {FocusInfo} oFocusInfo
421
+ * @param {Array<ContextMenuEntry>} aItems
422
+ */
423
+ function fnAddOpenInNewTabToContextMenu(oFocusInfo, aItems) {
424
+ var oHandlePromise = getHandlePromiseForOpenInNewTab(oFocusInfo);
425
+ var bStartsSection = true;
426
+ if (oHandlePromise) {
427
+ fnAddMainMenuItem(aItems, oCommonUtils.getText("ST_OPEN_NEW_TAB_OR_WINDOW"), null, bStartsSection, oHandlePromise);
225
428
  }
226
- oRet.open = fnNavigateToContext.bind(null, oSelectedContext, 0);
227
- var oDraftInfo = oTemplateUtils.oServices.oApplication.getDraftInfoForContext(oSelectedContext);
228
- oRet.openExpad = !oDraftInfo.bIsDraft && fnNavigateToContext.bind(null, oSelectedContext);
229
- return oRet;
230
429
  }
231
430
 
232
- /* eslint-disable */
431
+ /************************************************************
432
+ * End of methods related to "Open in new tab" functionality
433
+ ************************************************************/
434
+
233
435
  function getContextMenuItems(oEvent){
234
436
  var oFocusInfo = oPresentationControlHandler.getFocusInfoForContextMenuEvent(oEvent);
235
437
  mHandlers = Object.create(null);
236
438
  var aRet = [];
439
+ // Add the toolbar buttons to context menu
237
440
  fnAddToolbarButtonsToContextMenu(oFocusInfo, aRet);
238
- // fnAddInlineActionsToContextMenu(oFocusInfo, aRet);
239
- var oNavigationOptions = getNavigationOptions(oFocusInfo);
240
- if (oNavigationOptions.openExpad1){ // temp
241
- fnAddMainMenuItem(aRet, oCommonUtils.getText("ST_OPEN_NEW_TAB"), null, true, Promise.resolve(oNavigationOptions.openExpad.bind(null, 1)));
242
- fnAddMainMenuItem(aRet, oCommonUtils.getText("ST_OPEN_NEW_WINDOW"), null, false, Promise.resolve(oNavigationOptions.openExpad.bind(null, 2)));
243
- }
441
+ //Add an entry for "Open in new tab or window"
442
+ fnAddOpenInNewTabToContextMenu(oFocusInfo, aRet);
244
443
  return aRet;
245
444
  }
246
- /* eslint-enable */
247
445
 
248
446
  function fnBeforeOpenContextMenu(oEvent){
249
- oEvent.preventDefault();
250
- // var aContextMenuItems = getContextMenuItems(oEvent);
251
- // oTemplatePrivateModel.setProperty(sModelPath + "/items", aContextMenuItems);
252
- // if (aContextMenuItems.length === 0) {
253
- // oEvent.preventDefault();
254
- // }
447
+ var aContextMenuItems = getContextMenuItems(oEvent);
448
+ oTemplatePrivateModel.setProperty(sModelPath + "/items", aContextMenuItems);
449
+ if (aContextMenuItems.length === 0) {
450
+ oEvent.preventDefault();
451
+ }
255
452
  }
256
453
 
257
454
  function onContextMenu(oEvent){
@@ -462,9 +462,37 @@ sap.ui.define([
462
462
  oSettingModel.setProperty("/cancelButtonText", oTemplateContract.getText("CANCEL"));
463
463
  oSettingModel.setProperty("/closeButtonText", oTemplateContract.getText("ST_GENERIC_DIALOG_CLOSE_BUT"));
464
464
  };
465
+ /**
466
+ * Callback function that resolves a promise after validating an URL.
467
+ * The URL is validated by sap.ushell.services.Navigation#isUrlSupported method.
468
+ *
469
+ * @callback sap.m.MessageView~asyncURLHandler
470
+ * @param {object} oConfig A single parameter object
471
+ * @param {string} oConfig.url URL to validate
472
+ * @param {string|int} oConfig.id ID of the validation job
473
+ * @param {object} oConfig.promise Promise object that contains resolve and reject methods
474
+ * @param {function} oConfig.promise.resolve Method to resolve promise
475
+ * @param {function} oConfig.promise.reject Method to reject promise
476
+ */
477
+ var fnAsyncURLHandler = function (oConfig) {
478
+ var UShellContainer = sap.ui.require("sap/ushell/Container");
479
+ if (!UShellContainer) {
480
+ oConfig.promise.resolve({allowed: false, id: oConfig.id});
481
+ }
482
+ UShellContainer.getServiceAsync("Navigation").then(function (oNavService) {
483
+ oNavService.isUrlSupported(oConfig.url).then(function () {
484
+ oConfig.promise.resolve({allowed: true, id: oConfig.id});
485
+ }).catch(function () {
486
+ oConfig.promise.resolve({allowed: false, id: oConfig.id});
487
+ });
488
+ });
489
+ };
490
+
465
491
  oTemplateContract.oApplicationProxy.getDialogFragmentAsync("sap.suite.ui.generic.template.fragments.MessageDialog", oDialogFragmentController, "settings", fnOnFragmentCreated, false, true).then(function(odialog){
466
492
  oDialog = odialog;
467
493
  oMessageView = oDialog.getContent()[0];
494
+ // Add the URL handler to message view
495
+ oMessageView.setAsyncURLHandler(fnAsyncURLHandler);
468
496
  // the following code prepares the grouping of messages.
469
497
  // Note that grouping will only be done when at least one message is attached to another group then the generic one
470
498
  var oModel = oDialog.getModel();
@@ -188,7 +188,6 @@ sap.ui.define(["sap/ui/base/Object",
188
188
 
189
189
  // public instance methods
190
190
  return {
191
- discardDraft: fnDiscardDraft,
192
191
  performAfterDiscardOrKeepDraft: fnPerformAfterDiscardOrKeepDraft
193
192
  };
194
193
  }