@sapui5/sap.fe.templates 1.100.0 → 1.102.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 (150) hide show
  1. package/package.json +4 -5
  2. package/src/sap/fe/templates/.library +1 -2
  3. package/src/sap/fe/templates/AnalyticalListPage/Component.js +24 -12
  4. package/src/sap/fe/templates/AnalyticalListPage/Component.ts +6 -0
  5. package/src/sap/fe/templates/AnalyticalListPage/chart/FEChartDelegate.js +30 -32
  6. package/src/sap/fe/templates/AnalyticalListPage/chart/FEChartDelegate.ts +25 -0
  7. package/src/sap/fe/templates/Feedback.js +80 -0
  8. package/src/sap/fe/templates/Feedback.ts +67 -0
  9. package/src/sap/fe/templates/ListComponent.js +156 -118
  10. package/src/sap/fe/templates/ListComponent.ts +105 -0
  11. package/src/sap/fe/templates/ListReport/Component.js +82 -53
  12. package/src/sap/fe/templates/ListReport/Component.ts +39 -0
  13. package/src/sap/fe/templates/ListReport/ExtensionAPI.js +126 -112
  14. package/src/sap/fe/templates/ListReport/ExtensionAPI.ts +106 -0
  15. package/src/sap/fe/templates/ListReport/ListReport.view.xml +106 -58
  16. package/src/sap/fe/templates/ListReport/ListReportController.controller.js +1196 -1081
  17. package/src/sap/fe/templates/ListReport/ListReportController.controller.ts +1088 -0
  18. package/src/sap/fe/templates/ListReport/ListReportTemplating.js +45 -0
  19. package/src/sap/fe/templates/ListReport/ListReportTemplating.ts +30 -0
  20. package/src/sap/fe/templates/ListReport/overrides/IntentBasedNavigation.js +54 -53
  21. package/src/sap/fe/templates/ListReport/overrides/IntentBasedNavigation.ts +55 -0
  22. package/src/sap/fe/templates/ListReport/overrides/Share.js +137 -137
  23. package/src/sap/fe/templates/ListReport/overrides/Share.ts +135 -0
  24. package/src/sap/fe/templates/ListReport/overrides/ViewState.js +451 -428
  25. package/src/sap/fe/templates/ListReport/overrides/ViewState.ts +419 -0
  26. package/src/sap/fe/templates/ListReport/view/fragments/CollectionVisualization.fragment.xml +25 -25
  27. package/src/sap/fe/templates/ListReport/view/fragments/MultipleMode.fragment.js +72 -0
  28. package/src/sap/fe/templates/ListReport/view/fragments/MultipleMode.fragment.ts +62 -0
  29. package/src/sap/fe/templates/ListReport/view/fragments/{MultipleMode.fragment.xml → MultipleModeOld.fragment.xml} +24 -23
  30. package/src/sap/fe/templates/ObjectPage/Component.js +169 -138
  31. package/src/sap/fe/templates/ObjectPage/Component.ts +131 -0
  32. package/src/sap/fe/templates/ObjectPage/ExtensionAPI.js +140 -142
  33. package/src/sap/fe/templates/ObjectPage/ExtensionAPI.ts +116 -0
  34. package/src/sap/fe/templates/ObjectPage/ObjectPage.view.xml +162 -22
  35. package/src/sap/fe/templates/ObjectPage/ObjectPageController.controller.js +1534 -1447
  36. package/src/sap/fe/templates/ObjectPage/ObjectPageController.controller.ts +1454 -0
  37. package/src/sap/fe/templates/ObjectPage/ObjectPageTemplating.js +872 -0
  38. package/src/sap/fe/templates/ObjectPage/ObjectPageTemplating.ts +837 -0
  39. package/src/sap/fe/templates/ObjectPage/controls/StashableHBox.js +136 -101
  40. package/src/sap/fe/templates/ObjectPage/controls/StashableHBox.ts +84 -0
  41. package/src/sap/fe/templates/ObjectPage/controls/StashableVBox.js +24 -21
  42. package/src/sap/fe/templates/ObjectPage/controls/StashableVBox.ts +10 -0
  43. package/src/sap/fe/templates/ObjectPage/controls/SubSectionBlock.js +98 -53
  44. package/src/sap/fe/templates/ObjectPage/controls/SubSectionBlock.ts +50 -0
  45. package/src/sap/fe/templates/ObjectPage/designtime/FlexBox.designtime.js +20 -19
  46. package/src/sap/fe/templates/ObjectPage/designtime/FlexBox.designtime.ts +15 -0
  47. package/src/sap/fe/templates/ObjectPage/designtime/StashableHBox.designtime.js +50 -47
  48. package/src/sap/fe/templates/ObjectPage/designtime/StashableHBox.designtime.ts +47 -0
  49. package/src/sap/fe/templates/ObjectPage/designtime/StashableVBox.designtime.js +34 -34
  50. package/src/sap/fe/templates/ObjectPage/designtime/StashableVBox.designtime.ts +34 -0
  51. package/src/sap/fe/templates/ObjectPage/flexibility/StashableHBox.flexibility.js +15 -15
  52. package/src/sap/fe/templates/ObjectPage/flexibility/StashableHBox.flexibility.ts +13 -0
  53. package/src/sap/fe/templates/ObjectPage/flexibility/StashableVBox.flexibility.js +11 -11
  54. package/src/sap/fe/templates/ObjectPage/flexibility/StashableVBox.flexibility.ts +7 -0
  55. package/src/sap/fe/templates/ObjectPage/overrides/IntentBasedNavigation.js +55 -52
  56. package/src/sap/fe/templates/ObjectPage/overrides/IntentBasedNavigation.ts +57 -0
  57. package/src/sap/fe/templates/ObjectPage/overrides/InternalRouting.js +15 -17
  58. package/src/sap/fe/templates/ObjectPage/overrides/InternalRouting.ts +13 -0
  59. package/src/sap/fe/templates/ObjectPage/overrides/MessageHandler.js +13 -17
  60. package/src/sap/fe/templates/ObjectPage/overrides/MessageHandler.ts +14 -0
  61. package/src/sap/fe/templates/ObjectPage/overrides/Paginator.js +23 -21
  62. package/src/sap/fe/templates/ObjectPage/overrides/Paginator.ts +21 -0
  63. package/src/sap/fe/templates/ObjectPage/overrides/Share.js +310 -317
  64. package/src/sap/fe/templates/ObjectPage/overrides/Share.ts +316 -0
  65. package/src/sap/fe/templates/ObjectPage/overrides/ViewState.js +66 -57
  66. package/src/sap/fe/templates/ObjectPage/overrides/ViewState.ts +65 -0
  67. package/src/sap/fe/templates/ObjectPage/view/fragments/Actions.fragment.xml +26 -33
  68. package/src/sap/fe/templates/ObjectPage/view/fragments/CollaborationDraft.fragment.xml +11 -10
  69. package/src/sap/fe/templates/ObjectPage/view/fragments/EditableHeaderFacet.fragment.xml +15 -15
  70. package/src/sap/fe/templates/ObjectPage/view/fragments/FooterContent.fragment.xml +31 -27
  71. package/src/sap/fe/templates/ObjectPage/view/fragments/FormActionButtons.fragment.xml +15 -16
  72. package/src/sap/fe/templates/ObjectPage/view/fragments/FormActions.fragment.xml +1 -5
  73. package/src/sap/fe/templates/ObjectPage/view/fragments/HeaderDataPoint.fragment.xml +1 -2
  74. package/src/sap/fe/templates/ObjectPage/view/fragments/HeaderDataPointTitle.fragment.xml +1 -3
  75. package/src/sap/fe/templates/ObjectPage/view/fragments/HeaderFacet.fragment.xml +3 -4
  76. package/src/sap/fe/templates/ObjectPage/view/fragments/Heading.fragment.xml +16 -17
  77. package/src/sap/fe/templates/ObjectPage/view/fragments/HeadingTitle.fragment.xml +3 -3
  78. package/src/sap/fe/templates/ObjectPage/view/fragments/ObjectPageHeaderForm.fragment.xml +3 -3
  79. package/src/sap/fe/templates/ObjectPage/view/fragments/RelatedApps.fragment.xml +7 -4
  80. package/src/sap/fe/templates/ObjectPage/view/fragments/Section.fragment.xml +71 -6
  81. package/src/sap/fe/templates/ObjectPage/view/fragments/SectionContent.fragment.xml +114 -94
  82. package/src/sap/fe/templates/ObjectPage/view/fragments/SectionContentLazyLoader.fragment.xml +127 -107
  83. package/src/sap/fe/templates/ObjectPage/view/fragments/SwitchDraftAndActiveObjectPopOver.fragment.xml +27 -0
  84. package/src/sap/fe/templates/RootContainer/controller/Fcl.controller.js +899 -817
  85. package/src/sap/fe/templates/RootContainer/controller/Fcl.controller.ts +833 -0
  86. package/src/sap/fe/templates/RootContainer/controller/NavContainer.controller.js +205 -189
  87. package/src/sap/fe/templates/RootContainer/controller/NavContainer.controller.ts +178 -0
  88. package/src/sap/fe/templates/RootContainer/controller/RootContainerBaseController.js +484 -459
  89. package/src/sap/fe/templates/RootContainer/controller/RootContainerBaseController.ts +438 -0
  90. package/src/sap/fe/templates/RootContainer/overrides/EditFlow.js +16 -14
  91. package/src/sap/fe/templates/RootContainer/overrides/EditFlow.ts +20 -0
  92. package/src/sap/fe/templates/TableScroller.js +45 -53
  93. package/src/sap/fe/templates/TableScroller.ts +48 -0
  94. package/src/sap/fe/templates/controls/Chart.fragment.xml +18 -17
  95. package/src/sap/fe/templates/controls/MacroChart.fragment.xml +23 -0
  96. package/src/sap/fe/templates/controls/Table.fragment.xml +3 -4
  97. package/src/sap/fe/templates/library.js +49 -63
  98. package/src/sap/fe/templates/library.ts +57 -0
  99. package/src/sap/fe/templates/messagebundle.properties +19 -7
  100. package/src/sap/fe/templates/messagebundle_ar.properties +12 -4
  101. package/src/sap/fe/templates/messagebundle_bg.properties +12 -4
  102. package/src/sap/fe/templates/messagebundle_ca.properties +12 -4
  103. package/src/sap/fe/templates/messagebundle_cs.properties +12 -4
  104. package/src/sap/fe/templates/messagebundle_cy.properties +12 -4
  105. package/src/sap/fe/templates/messagebundle_da.properties +12 -4
  106. package/src/sap/fe/templates/messagebundle_de.properties +12 -4
  107. package/src/sap/fe/templates/messagebundle_el.properties +12 -4
  108. package/src/sap/fe/templates/messagebundle_en.properties +12 -4
  109. package/src/sap/fe/templates/messagebundle_en_GB.properties +12 -4
  110. package/src/sap/fe/templates/messagebundle_en_US_sappsd.properties +13 -5
  111. package/src/sap/fe/templates/messagebundle_en_US_saprigi.properties +13 -5
  112. package/src/sap/fe/templates/messagebundle_en_US_saptrc.properties +13 -5
  113. package/src/sap/fe/templates/messagebundle_es.properties +12 -4
  114. package/src/sap/fe/templates/messagebundle_es_MX.properties +12 -4
  115. package/src/sap/fe/templates/messagebundle_et.properties +12 -4
  116. package/src/sap/fe/templates/messagebundle_fi.properties +12 -4
  117. package/src/sap/fe/templates/messagebundle_fr.properties +12 -4
  118. package/src/sap/fe/templates/messagebundle_fr_CA.properties +12 -4
  119. package/src/sap/fe/templates/messagebundle_hi.properties +12 -4
  120. package/src/sap/fe/templates/messagebundle_hr.properties +12 -4
  121. package/src/sap/fe/templates/messagebundle_hu.properties +12 -4
  122. package/src/sap/fe/templates/messagebundle_id.properties +12 -4
  123. package/src/sap/fe/templates/messagebundle_it.properties +12 -4
  124. package/src/sap/fe/templates/messagebundle_iw.properties +12 -4
  125. package/src/sap/fe/templates/messagebundle_ja.properties +12 -4
  126. package/src/sap/fe/templates/messagebundle_kk.properties +12 -4
  127. package/src/sap/fe/templates/messagebundle_ko.properties +12 -4
  128. package/src/sap/fe/templates/messagebundle_lt.properties +12 -4
  129. package/src/sap/fe/templates/messagebundle_lv.properties +12 -4
  130. package/src/sap/fe/templates/messagebundle_ms.properties +12 -4
  131. package/src/sap/fe/templates/messagebundle_nl.properties +12 -4
  132. package/src/sap/fe/templates/messagebundle_no.properties +12 -4
  133. package/src/sap/fe/templates/messagebundle_pl.properties +12 -4
  134. package/src/sap/fe/templates/messagebundle_pt.properties +13 -5
  135. package/src/sap/fe/templates/messagebundle_pt_PT.properties +12 -4
  136. package/src/sap/fe/templates/messagebundle_ro.properties +12 -4
  137. package/src/sap/fe/templates/messagebundle_ru.properties +12 -4
  138. package/src/sap/fe/templates/messagebundle_sh.properties +12 -4
  139. package/src/sap/fe/templates/messagebundle_sk.properties +12 -4
  140. package/src/sap/fe/templates/messagebundle_sl.properties +12 -4
  141. package/src/sap/fe/templates/messagebundle_sv.properties +12 -4
  142. package/src/sap/fe/templates/messagebundle_th.properties +12 -4
  143. package/src/sap/fe/templates/messagebundle_tr.properties +12 -4
  144. package/src/sap/fe/templates/messagebundle_uk.properties +12 -4
  145. package/src/sap/fe/templates/messagebundle_vi.properties +12 -4
  146. package/src/sap/fe/templates/messagebundle_zh_CN.properties +12 -4
  147. package/src/sap/fe/templates/messagebundle_zh_TW.properties +12 -4
  148. package/src/sap/fe/templates/ObjectPage/AnnotationHelper.js +0 -518
  149. package/src/sap/fe/templates/ObjectPage/templating/ObjectPageTemplating.js +0 -120
  150. package/src/sap/fe/templates/ObjectPage/templating/ObjectPageTemplating.ts +0 -138
@@ -0,0 +1,1454 @@
1
+ import ResourceBundle from "sap/base/i18n/ResourceBundle";
2
+ import Log from "sap/base/Log";
3
+ import merge from "sap/base/util/merge";
4
+ import CommonUtils from "sap/fe/core/CommonUtils";
5
+ import BusyLocker from "sap/fe/core/controllerextensions/BusyLocker";
6
+ import { connect } from "sap/fe/core/controllerextensions/collaboration/ActivitySync";
7
+ import { openManageDialog, showUserDetails } from "sap/fe/core/controllerextensions/collaboration/Manage";
8
+ import EditFlow from "sap/fe/core/controllerextensions/EditFlow";
9
+ import draft from "sap/fe/core/controllerextensions/editFlow/draft";
10
+ import IntentBasedNavigation from "sap/fe/core/controllerextensions/IntentBasedNavigation";
11
+ import InternalEditFlow from "sap/fe/core/controllerextensions/InternalEditFlow";
12
+ import InternalIntentBasedNavigation from "sap/fe/core/controllerextensions/InternalIntentBasedNavigation";
13
+ import InternalRouting from "sap/fe/core/controllerextensions/InternalRouting";
14
+ import MassEdit from "sap/fe/core/controllerextensions/MassEdit";
15
+ import MessageHandler from "sap/fe/core/controllerextensions/MessageHandler";
16
+ import PageReady from "sap/fe/core/controllerextensions/PageReady";
17
+ import Paginator from "sap/fe/core/controllerextensions/Paginator";
18
+ import Placeholder from "sap/fe/core/controllerextensions/Placeholder";
19
+ import Share from "sap/fe/core/controllerextensions/Share";
20
+ import ViewState from "sap/fe/core/controllerextensions/ViewState";
21
+ import { defineUI5Class, extensible, finalExtension, publicExtension, usingExtension } from "sap/fe/core/helpers/ClassSupport";
22
+ import ModelHelper, { InternalModelContext } from "sap/fe/core/helpers/ModelHelper";
23
+ import PageController from "sap/fe/core/PageController";
24
+ import ChartRuntime from "sap/fe/macros/chart/ChartRuntime";
25
+ import CommonHelper from "sap/fe/macros/CommonHelper";
26
+ import DelegateUtil from "sap/fe/macros/DelegateUtil";
27
+ import TableUtils from "sap/fe/macros/table/Utils";
28
+ import SelectionVariant from "sap/fe/navigation/SelectionVariant";
29
+ import { default as ExtensionAPI, default as ObjectPageExtensionAPI } from "sap/fe/templates/ObjectPage/ExtensionAPI";
30
+ import RootContainerBaseController from "sap/fe/templates/RootContainer/controller/RootContainerBaseController";
31
+ import EditFlowOverrides from "sap/fe/templates/RootContainer/overrides/EditFlow";
32
+ import TableScroller from "sap/fe/templates/TableScroller";
33
+ import InstanceManager from "sap/m/InstanceManager";
34
+ import Link from "sap/m/Link";
35
+ import MessageBox from "sap/m/MessageBox";
36
+ import Popover from "sap/m/Popover";
37
+ import SelectList from "sap/m/SelectList";
38
+ import Event from "sap/ui/base/Event";
39
+ import Control from "sap/ui/core/Control";
40
+ import Core from "sap/ui/core/Core";
41
+ import Fragment from "sap/ui/core/Fragment";
42
+ import Item from "sap/ui/core/Item";
43
+ import OverrideExecution from "sap/ui/core/mvc/OverrideExecution";
44
+ import XMLPreprocessor from "sap/ui/core/util/XMLPreprocessor";
45
+ import XMLTemplateProcessor from "sap/ui/core/XMLTemplateProcessor";
46
+ import Binding from "sap/ui/model/Binding";
47
+ import JSONModel from "sap/ui/model/json/JSONModel";
48
+ import Context from "sap/ui/model/odata/v4/Context";
49
+ import ODataListBinding from "sap/ui/model/odata/v4/ODataListBinding";
50
+ import ODataMetaModel from "sap/ui/model/odata/v4/ODataMetaModel";
51
+ import ODataModel from "sap/ui/model/odata/v4/ODataModel";
52
+ import ResourceModel from "sap/ui/model/resource/ResourceModel";
53
+ import ObjectPageDynamicHeaderTitle from "sap/uxap/ObjectPageDynamicHeaderTitle";
54
+ import ObjectPageLayout from "sap/uxap/ObjectPageLayout";
55
+ import ObjectPageSection from "sap/uxap/ObjectPageSection";
56
+ import ObjectPageSubSection from "sap/uxap/ObjectPageSubSection";
57
+ import IntentBasedNavigationOverride from "./overrides/IntentBasedNavigation";
58
+ import InternalRoutingOverride from "./overrides/InternalRouting";
59
+ import MessageHandlerOverride from "./overrides/MessageHandler";
60
+ import PaginatorOverride from "./overrides/Paginator";
61
+ import ShareOverrides from "./overrides/Share";
62
+ import ViewStateOverrides from "./overrides/ViewState";
63
+
64
+ @defineUI5Class("sap.fe.templates.ObjectPage.ObjectPageController")
65
+ class ObjectPageController extends PageController {
66
+ oView!: any;
67
+ @usingExtension(Placeholder)
68
+ placeholder!: Placeholder;
69
+ @usingExtension(EditFlow)
70
+ editFlow!: EditFlow;
71
+ @usingExtension(Share.override(ShareOverrides))
72
+ share!: Share;
73
+ @usingExtension(InternalEditFlow.override(EditFlowOverrides))
74
+ _editFlow!: InternalEditFlow;
75
+ @usingExtension(InternalRouting.override(InternalRoutingOverride))
76
+ _routing!: InternalRouting;
77
+ @usingExtension(Paginator.override(PaginatorOverride))
78
+ paginator!: Paginator;
79
+ @usingExtension(MessageHandler.override(MessageHandlerOverride))
80
+ messageHandler!: MessageHandler;
81
+ @usingExtension(IntentBasedNavigation.override(IntentBasedNavigationOverride))
82
+ intentBasedNavigation!: IntentBasedNavigation;
83
+ @usingExtension(
84
+ InternalIntentBasedNavigation.override({
85
+ getNavigationMode: function (this: InternalIntentBasedNavigation) {
86
+ const bIsStickyEditMode =
87
+ (this.getView().getController() as ObjectPageController).getStickyEditMode &&
88
+ (this.getView().getController() as ObjectPageController).getStickyEditMode();
89
+ return bIsStickyEditMode ? "explace" : undefined;
90
+ }
91
+ })
92
+ )
93
+ _intentBasedNavigation!: InternalIntentBasedNavigation;
94
+ @usingExtension(ViewState.override(ViewStateOverrides))
95
+ viewState!: ViewState;
96
+ @usingExtension(
97
+ PageReady.override({
98
+ isContextExpected: function () {
99
+ return true;
100
+ }
101
+ })
102
+ )
103
+ pageReady!: PageReady;
104
+ @usingExtension(MassEdit)
105
+ massEdit!: MassEdit;
106
+ private mCustomSectionExtensionAPIs?: Record<string, ObjectPageExtensionAPI>;
107
+ private extensionAPI?: ObjectPageExtensionAPI;
108
+ private oResourceBundle?: ResourceBundle;
109
+ private bSectionNavigated?: boolean;
110
+ private switchDraftAndActivePopOver?: Popover;
111
+ private currentBinding?: Binding;
112
+
113
+ @publicExtension()
114
+ @finalExtension()
115
+ getExtensionAPI(sId?: string): ExtensionAPI {
116
+ if (sId) {
117
+ // to allow local ID usage for custom pages we'll create/return own instances for custom sections
118
+ this.mCustomSectionExtensionAPIs = this.mCustomSectionExtensionAPIs || {};
119
+
120
+ if (!this.mCustomSectionExtensionAPIs[sId]) {
121
+ this.mCustomSectionExtensionAPIs[sId] = new ExtensionAPI(this, sId);
122
+ }
123
+ return this.mCustomSectionExtensionAPIs[sId];
124
+ } else {
125
+ if (!this.extensionAPI) {
126
+ this.extensionAPI = new ExtensionAPI(this);
127
+ }
128
+ return this.extensionAPI;
129
+ }
130
+ }
131
+
132
+ onInit() {
133
+ super.onInit();
134
+ const oObjectPage = this._getObjectPageLayoutControl();
135
+
136
+ // Setting defaults of internal model context
137
+ const oInternalModelContext = this.getView().getBindingContext("internal") as InternalModelContext;
138
+ oInternalModelContext.setProperty("externalNavigationContext", { "page": true });
139
+ oInternalModelContext.setProperty("relatedApps", {
140
+ visibility: false,
141
+ items: null
142
+ });
143
+ oInternalModelContext.setProperty("batchGroups", this._getBatchGroupsForView());
144
+ oInternalModelContext.setProperty("errorNavigationSectionFlag", false);
145
+ if (!(this.getView().getViewData() as any).useNewLazyLoading && (oObjectPage as any).getEnableLazyLoading()) {
146
+ //Attaching the event to make the subsection context binding active when it is visible.
147
+ oObjectPage.attachEvent("subSectionEnteredViewPort", this._handleSubSectionEnteredViewPort.bind(this));
148
+ }
149
+ }
150
+
151
+ onExit() {
152
+ if (this.mCustomSectionExtensionAPIs) {
153
+ for (const sId of Object.keys(this.mCustomSectionExtensionAPIs)) {
154
+ this.mCustomSectionExtensionAPIs[sId] && this.mCustomSectionExtensionAPIs[sId].destroy();
155
+ }
156
+ delete this.mCustomSectionExtensionAPIs;
157
+ }
158
+ this.extensionAPI && this.extensionAPI.destroy();
159
+ delete this.extensionAPI;
160
+
161
+ const oMessageButton = this.getView().byId("fe::FooterBar::MessageButton"),
162
+ oMessagePopover = oMessageButton ? (oMessageButton as any).oMessagePopover : null;
163
+ if (oMessagePopover && oMessagePopover.isOpen()) {
164
+ oMessagePopover.close();
165
+ }
166
+ //when exiting we set keepAlive context to false
167
+ const oContext = this.getView().getBindingContext() as Context;
168
+ if (oContext && oContext.isKeepAlive()) {
169
+ oContext.setKeepAlive(false);
170
+ }
171
+ }
172
+
173
+ _getTableBinding(oTable: any) {
174
+ return oTable && oTable.getRowBinding();
175
+ }
176
+
177
+ onBeforeRendering() {
178
+ PageController.prototype.onBeforeRendering.apply(this);
179
+ // In the retrieveTextFromValueList scenario we need to ensure in case of reload/refresh that the meta model in the methode retrieveTextFromValueList of the FieldRuntime is available
180
+ if (this.oView.oViewData.retrieveTextFromValueList && CommonHelper.getMetaModel() === undefined) {
181
+ CommonHelper.setMetaModel(this.getAppComponent().getMetaModel());
182
+ }
183
+ }
184
+
185
+ onAfterRendering() {
186
+ ((this.getView().getModel("sap.fe.i18n") as ResourceModel).getResourceBundle() as Promise<ResourceBundle>)
187
+ .then((response: any) => {
188
+ this.oResourceBundle = response;
189
+ })
190
+ .catch(function (oError: any) {
191
+ Log.error("Error while retrieving the resource bundle", oError);
192
+ });
193
+ }
194
+
195
+ _onBeforeBinding(oContext: any, mParameters: any) {
196
+ // TODO: we should check how this comes together with the transaction helper, same to the change in the afterBinding
197
+ const aTables = this._findTables(),
198
+ oObjectPage = this._getObjectPageLayoutControl() as ObjectPageLayout,
199
+ oInternalModelContext = this.getView().getBindingContext("internal") as InternalModelContext,
200
+ oInternalModel = this.getView().getModel("internal") as JSONModel,
201
+ aBatchGroups = oInternalModelContext.getProperty("batchGroups"),
202
+ iViewLevel = (this.getView().getViewData() as any).viewLevel;
203
+ let oFastCreationRow;
204
+ aBatchGroups.push("$auto");
205
+ if (mParameters.bDraftNavigation !== true) {
206
+ this._closeSideContent();
207
+ }
208
+ const opContext = oObjectPage.getBindingContext() as Context;
209
+ if (
210
+ opContext &&
211
+ opContext.hasPendingChanges() &&
212
+ !aBatchGroups.some((opContext.getModel() as ODataModel).hasPendingChanges.bind(opContext.getModel()))
213
+ ) {
214
+ /* In case there are pending changes for the creation row and no others we need to reset the changes
215
+ TODO: this is just a quick solution, this needs to be reworked
216
+ */
217
+
218
+ opContext.getBinding().resetChanges();
219
+ }
220
+
221
+ // For now we have to set the binding context to null for every fast creation row
222
+ // TODO: Get rid of this coding or move it to another layer - to be discussed with MDC and model
223
+ for (let i = 0; i < aTables.length; i++) {
224
+ oFastCreationRow = aTables[i].getCreationRow();
225
+ if (oFastCreationRow) {
226
+ oFastCreationRow.setBindingContext(null);
227
+ }
228
+ }
229
+
230
+ // Scroll to present Section so that bindings are enabled during navigation through paginator buttons, as there is no view rerendering/rebind
231
+ const fnScrollToPresentSection = function () {
232
+ if (!(oObjectPage as any).isFirstRendering() && !mParameters.bPersistOPScroll) {
233
+ oObjectPage.setSelectedSection(null as any);
234
+ }
235
+ };
236
+ oObjectPage.attachEventOnce("modelContextChange", fnScrollToPresentSection);
237
+
238
+ // if the structure of the ObjectPageLayout is changed then scroll to present Section
239
+ // FIXME Is this really working as intended ? Initially this was onBeforeRendering, but never triggered onBeforeRendering because it was registered after it
240
+ const oDelegateOnBefore = {
241
+ onAfterRendering: fnScrollToPresentSection
242
+ };
243
+ oObjectPage.addEventDelegate(oDelegateOnBefore, this);
244
+ this.pageReady.attachEventOnce("pageReady", function () {
245
+ oObjectPage.removeEventDelegate(oDelegateOnBefore);
246
+ });
247
+
248
+ //Set the Binding for Paginators using ListBinding ID
249
+ if (iViewLevel > 1) {
250
+ let oBinding = mParameters && mParameters.listBinding;
251
+ const oPaginatorCurrentContext = oInternalModel.getProperty("/paginatorCurrentContext");
252
+ if (oPaginatorCurrentContext) {
253
+ const oBindingToUse = oPaginatorCurrentContext.getBinding();
254
+ this.paginator.initialize(oBindingToUse, oPaginatorCurrentContext);
255
+ oInternalModel.setProperty("/paginatorCurrentContext", null);
256
+ } else if (oBinding) {
257
+ if (oBinding.isA("sap.ui.model.odata.v4.ODataListBinding")) {
258
+ this.paginator.initialize(oBinding, oContext);
259
+ } else {
260
+ //if the binding type is not ODataListBinding because of a deeplink navigation or a refresh of the page
261
+ // we need to create it
262
+ const sContextPath = oBinding.getPath().replace(/\([^\)]*\)*$/, ""); //removing the last tuple
263
+ oBinding = new (ODataListBinding as any)(oBinding.oModel, "", oBinding.oModel.createBindingContext(sContextPath));
264
+ const _setListBindingAsync = () => {
265
+ if (oBinding.getContexts().length > 0) {
266
+ this.paginator.initialize(oBinding, oContext);
267
+ oBinding.detachEvent("change", _setListBindingAsync);
268
+ }
269
+ };
270
+ oBinding.getContexts(0);
271
+ oBinding.attachEvent("change", _setListBindingAsync);
272
+ }
273
+ }
274
+ }
275
+ if (!(this.getView().getViewData() as any).useNewLazyLoading && oObjectPage.getEnableLazyLoading()) {
276
+ const aSections = oObjectPage.getSections();
277
+ const bUseIconTabBar = oObjectPage.getUseIconTabBar();
278
+ let iSkip = 2;
279
+ const bIsInEditMode = oObjectPage.getModel("ui").getProperty("/isEditable");
280
+ const bEditableHeader = (this.getView().getViewData() as any).editableHeaderContent;
281
+ for (let iSection = 0; iSection < aSections.length; iSection++) {
282
+ const oSection = aSections[iSection];
283
+ const aSubSections = oSection.getSubSections();
284
+ for (let iSubSection = 0; iSubSection < aSubSections.length; iSubSection++, iSkip--) {
285
+ // In IconTabBar mode keep the second section bound if there is an editable header and we are switching to display mode
286
+ if (iSkip < 1 || (bUseIconTabBar && (iSection > 1 || (iSection === 1 && !bEditableHeader && !bIsInEditMode)))) {
287
+ const oSubSection = aSubSections[iSubSection];
288
+ if (oSubSection.data().isVisibilityDynamic !== "true") {
289
+ oSubSection.setBindingContext(null as any);
290
+ }
291
+ }
292
+ }
293
+ }
294
+ }
295
+
296
+ if (this.placeholder.isPlaceholderEnabled() && mParameters.showPlaceholder) {
297
+ const oView = this.getView();
298
+ const oNavContainer = (oView.getParent() as any).oContainer.getParent();
299
+ if (oNavContainer) {
300
+ oNavContainer.showPlaceholder({});
301
+ }
302
+ }
303
+ }
304
+
305
+ _getFirstClickableElement(oObjectPage: any) {
306
+ let oFirstClickableElement;
307
+ const aActions = oObjectPage.getHeaderTitle() && oObjectPage.getHeaderTitle().getActions();
308
+ if (aActions && aActions.length) {
309
+ oFirstClickableElement = aActions.find(function (oAction: any) {
310
+ // Due to the left alignment of the Draft switch and the collaborative draft avatar controls
311
+ // there is a ToolbarSpacer in the actions aggregation which we need to exclude here!
312
+ return !oAction.isA("sap.m.ToolbarSpacer") && oAction.getVisible() && oAction.getEnabled();
313
+ });
314
+ }
315
+ return oFirstClickableElement;
316
+ }
317
+
318
+ _getFirstEmptyMandatoryFieldFromSubSection(aSubSections: any) {
319
+ if (aSubSections) {
320
+ for (let subSection = 0; subSection < aSubSections.length; subSection++) {
321
+ const aBlocks = aSubSections[subSection].getBlocks();
322
+
323
+ if (aBlocks) {
324
+ for (let block = 0; block < aBlocks.length; block++) {
325
+ let aFormContainers;
326
+
327
+ if (aBlocks[block].isA("sap.ui.layout.form.Form")) {
328
+ aFormContainers = aBlocks[block].getFormContainers();
329
+ } else if (
330
+ aBlocks[block].getContent &&
331
+ aBlocks[block].getContent() &&
332
+ aBlocks[block].getContent().isA("sap.ui.layout.form.Form")
333
+ ) {
334
+ aFormContainers = aBlocks[block].getContent().getFormContainers();
335
+ }
336
+
337
+ if (aFormContainers) {
338
+ for (let formContainer = 0; formContainer < aFormContainers.length; formContainer++) {
339
+ const aFormElements = aFormContainers[formContainer].getFormElements();
340
+ if (aFormElements) {
341
+ for (let formElement = 0; formElement < aFormElements.length; formElement++) {
342
+ const aFields = aFormElements[formElement].getFields();
343
+
344
+ // The first field is not necessarily an InputBase (e.g. could be a Text)
345
+ // So we need to check whether it has a getRequired method
346
+ try {
347
+ if (aFields[0].getRequired && aFields[0].getRequired() && !aFields[0].getValue()) {
348
+ return aFields[0];
349
+ }
350
+ } catch (error) {
351
+ Log.debug("Error when searching for mandaotry empty field: " + error);
352
+ }
353
+ }
354
+ }
355
+ }
356
+ }
357
+ }
358
+ }
359
+ }
360
+ }
361
+ return undefined;
362
+ }
363
+
364
+ _updateFocusInEditMode(aSubSections: any) {
365
+ const oObjectPage = this._getObjectPageLayoutControl() as ObjectPageLayout;
366
+
367
+ const oMandatoryField = this._getFirstEmptyMandatoryFieldFromSubSection(aSubSections);
368
+ let oFieldToFocus: any;
369
+ if (oMandatoryField) {
370
+ oFieldToFocus = oMandatoryField.content.getContentEdit()[0];
371
+ } else {
372
+ oFieldToFocus = (oObjectPage as any)._getFirstEditableInput() || this._getFirstClickableElement(oObjectPage);
373
+ }
374
+
375
+ if (oFieldToFocus) {
376
+ setTimeout(function () {
377
+ // We set the focus in a timeeout, otherwise the focus sometimes goes to the TabBar
378
+ oFieldToFocus.focus();
379
+ }, 0);
380
+ }
381
+ }
382
+
383
+ _handleSubSectionEnteredViewPort(oEvent: any) {
384
+ const oSubSection = oEvent.getParameter("subSection");
385
+ oSubSection.setBindingContext(undefined);
386
+ }
387
+
388
+ _onBackNavigationInDraft(oContext: any) {
389
+ if (this.getAppComponent().getRouterProxy().checkIfBackHasSameContext()) {
390
+ // Back nav will keep the same context --> no need to display the dialog
391
+ history.back();
392
+ } else {
393
+ draft.processDataLossOrDraftDiscardConfirmation(
394
+ function () {
395
+ history.back();
396
+ },
397
+ Function.prototype,
398
+ oContext,
399
+ this,
400
+ false,
401
+ draft.NavigationType.BackNavigation
402
+ );
403
+ }
404
+ }
405
+
406
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
407
+ _onAfterBinding(oBindingContext: any, mParameters: any) {
408
+ const oObjectPage = this._getObjectPageLayoutControl() as ObjectPageLayout;
409
+ const aTables = this._findTables();
410
+
411
+ this._sideEffects.clearPropertiesStatus();
412
+
413
+ // TODO: this is only a temp solution as long as the model fix the cache issue and we use this additional
414
+ // binding with ownRequest
415
+ oBindingContext = oObjectPage.getBindingContext();
416
+
417
+ let aIBNActions: any[] = [];
418
+ oObjectPage.getSections().forEach(function (oSection: any) {
419
+ oSection.getSubSections().forEach(function (oSubSection: any) {
420
+ aIBNActions = CommonUtils.getIBNActions(oSubSection, aIBNActions);
421
+ });
422
+ });
423
+
424
+ // Assign internal binding contexts to oFormContainer:
425
+ // 1. It is not possible to assign the internal binding context to the XML fragment
426
+ // (FormContainer.fragment.xml) yet - it is used already for the data-structure.
427
+ // 2. Another problem is, that FormContainers assigned to a 'MoreBlock' does not have an
428
+ // internal model context at all.
429
+
430
+ aTables.forEach(function (oTable: any) {
431
+ const oInternalModelContext = oTable.getBindingContext("internal");
432
+ oInternalModelContext.setProperty("creationRowFieldValidity", {});
433
+ oInternalModelContext.setProperty("creationRowCustomValidity", {});
434
+
435
+ aIBNActions = CommonUtils.getIBNActions(oTable, aIBNActions);
436
+ // temporary workaround for BCP: 2080218004
437
+ // Need to fix with BLI: FIORITECHP1-15274
438
+ // only for edit mode, we clear the table cache
439
+ // Workaround starts here!!
440
+ const oTableRowBinding = oTable.getRowBinding();
441
+ if (oTableRowBinding) {
442
+ if (ModelHelper.isStickySessionSupported(oTableRowBinding.getModel().getMetaModel())) {
443
+ // apply for both edit and display mode in sticky
444
+ oTableRowBinding.removeCachesAndMessages("");
445
+ }
446
+ }
447
+ // Workaround ends here!!
448
+
449
+ // Update 'enabled' property of DataFieldForAction buttons on table toolbar
450
+ // The same is also performed on Table selectionChange event
451
+ const oActionOperationAvailableMap = JSON.parse(
452
+ CommonHelper.parseCustomData(DelegateUtil.getCustomData(oTable, "operationAvailableMap")) as any
453
+ ),
454
+ aSelectedContexts = oTable.getSelectedContexts();
455
+
456
+ CommonUtils.setActionEnablement(oInternalModelContext, oActionOperationAvailableMap, aSelectedContexts);
457
+ });
458
+ CommonUtils.getSemanticTargetsFromPageModel(this, "_pageModel");
459
+ //Retrieve Object Page header actions from Object Page title control
460
+ const oObjectPageTitle = oObjectPage.getHeaderTitle();
461
+ let aIBNHeaderActions: any[] = [];
462
+ aIBNHeaderActions = CommonUtils.getIBNActions(oObjectPageTitle, aIBNHeaderActions);
463
+ aIBNActions = aIBNActions.concat(aIBNHeaderActions);
464
+ CommonUtils.updateDataFieldForIBNButtonsVisibility(aIBNActions, this.getView());
465
+
466
+ let oModel: any, oFinalUIState: any;
467
+
468
+ // TODO: this should be moved into an init event of the MDC tables (not yet existing) and should be part
469
+ // of any controller extension
470
+ /**
471
+ * @param oTable
472
+ * @param oListBinding
473
+ */
474
+ function enableFastCreationRow(oTable: any, oListBinding: any) {
475
+ const oFastCreationRow = oTable.getCreationRow();
476
+ let oFastCreationListBinding, oFastCreationContext;
477
+
478
+ if (oFastCreationRow) {
479
+ oFinalUIState
480
+ .then(function () {
481
+ if (oFastCreationRow.getModel("ui").getProperty("/isEditable")) {
482
+ oFastCreationListBinding = oModel.bindList(oListBinding.getPath(), oListBinding.getContext(), [], [], {
483
+ $$updateGroupId: "doNotSubmit",
484
+ $$groupId: "doNotSubmit"
485
+ });
486
+ // Workaround suggested by OData model v4 colleagues
487
+ oFastCreationListBinding.refreshInternal = function () {
488
+ /* do nothing */
489
+ };
490
+ /*
491
+ oFastCreationListBinding.hasPendingChanges = function() {
492
+ return false;
493
+ };
494
+ */
495
+
496
+ oFastCreationContext = oFastCreationListBinding.create();
497
+ oFastCreationRow.setBindingContext(oFastCreationContext);
498
+
499
+ // this is needed to avoid console error
500
+ oFastCreationContext.created().catch(function () {
501
+ Log.trace("transient fast creation context deleted");
502
+ });
503
+ }
504
+ })
505
+ .catch(function (oError: any) {
506
+ Log.error("Error while computing the final UI state", oError);
507
+ });
508
+ }
509
+ }
510
+
511
+ // this should not be needed at the all
512
+ /**
513
+ * @param oTable
514
+ */
515
+ const handleTableModifications = (oTable: any) => {
516
+ const oBinding = this._getTableBinding(oTable),
517
+ fnHandleTablePatchEvents = function () {
518
+ enableFastCreationRow(oTable, oBinding);
519
+ };
520
+
521
+ if (!oBinding) {
522
+ Log.error("Expected binding missing for table: " + oTable.getId());
523
+ return;
524
+ }
525
+
526
+ if (oBinding.oContext) {
527
+ fnHandleTablePatchEvents();
528
+ } else {
529
+ const fnHandleChange = function () {
530
+ if (oBinding.oContext) {
531
+ fnHandleTablePatchEvents();
532
+ oBinding.detachChange(fnHandleChange);
533
+ }
534
+ };
535
+ oBinding.attachChange(fnHandleChange);
536
+ }
537
+ };
538
+
539
+ if (oBindingContext) {
540
+ oModel = oBindingContext.getModel();
541
+
542
+ // Compute Edit Mode
543
+ oFinalUIState = this._editFlow.computeEditMode(oBindingContext);
544
+
545
+ if (ModelHelper.isCollaborationDraftSupported(oModel.getMetaModel())) {
546
+ oFinalUIState
547
+ .then(() => {
548
+ if (this.getView().getModel("ui").getProperty("/isEditable")) {
549
+ connect(this.getView());
550
+ }
551
+ })
552
+ .catch(function (oError: any) {
553
+ Log.error("Error while waiting for the final UI State", oError);
554
+ });
555
+ }
556
+
557
+ // update related apps once Data is received in case of binding cache is not available
558
+ // TODO: this is only a temp solution since we need to call _updateRelatedApps method only after data for Object Page is received (if there is no binding)
559
+ if (oBindingContext.getBinding().oCache) {
560
+ this._updateRelatedApps();
561
+ } else {
562
+ const fnUpdateRelatedApps = () => {
563
+ this._updateRelatedApps();
564
+ oBindingContext.getBinding().detachDataReceived(fnUpdateRelatedApps);
565
+ };
566
+ oBindingContext.getBinding().attachDataReceived(fnUpdateRelatedApps);
567
+ }
568
+
569
+ //Attach the patch sent and patch completed event to the object page binding so that we can react
570
+ const oBinding = (oBindingContext.getBinding && oBindingContext.getBinding()) || oBindingContext;
571
+
572
+ // Attach the event handler only once to the same binding
573
+ if (this.currentBinding !== oBinding) {
574
+ oBinding.attachEvent("patchSent", this.editFlow.handlePatchSent, this);
575
+ this.currentBinding = oBinding;
576
+ }
577
+
578
+ aTables.forEach(function (oTable: any) {
579
+ // access binding only after table is bound
580
+ TableUtils.whenBound(oTable)
581
+ .then(handleTableModifications)
582
+ .catch(function (oError: any) {
583
+ Log.error("Error while waiting for the table to be bound", oError);
584
+ });
585
+ });
586
+
587
+ if (!(this.getView().getViewData() as any).useNewLazyLoading) {
588
+ // should be called only after binding is ready hence calling it in onAfterBinding
589
+ (oObjectPage as any)._triggerVisibleSubSectionsEvents();
590
+ }
591
+ }
592
+ }
593
+
594
+ @publicExtension()
595
+ @extensible(OverrideExecution.After)
596
+ onPageReady(mParameters: any) {
597
+ const setFocus = () => {
598
+ // Set the focus to the first action button, or to the first editable input if in editable mode
599
+ const oObjectPage = this._getObjectPageLayoutControl();
600
+ const isInDisplayMode = !oObjectPage.getModel("ui").getProperty("/isEditable");
601
+
602
+ if (isInDisplayMode) {
603
+ const oFirstClickableElement = this._getFirstClickableElement(oObjectPage);
604
+ if (oFirstClickableElement) {
605
+ oFirstClickableElement.focus();
606
+ }
607
+ } else {
608
+ const oSelectedSection: any = Core.byId(oObjectPage.getSelectedSection());
609
+ this._updateFocusInEditMode(oSelectedSection.getSubSections());
610
+ }
611
+ };
612
+ // Apply app state only after the page is ready with the first section selected
613
+ const oView = this.getView();
614
+ const oInternalModelContext = oView.getBindingContext("internal") as InternalModelContext;
615
+ const oBindingContext = oView.getBindingContext();
616
+ //Show popup while navigating back from object page in case of draft
617
+ if (oBindingContext) {
618
+ const bIsStickyMode = ModelHelper.isStickySessionSupported((oBindingContext.getModel() as ODataModel).getMetaModel());
619
+ if (!bIsStickyMode) {
620
+ const oAppComponent = CommonUtils.getAppComponent(oView);
621
+ oAppComponent.getShellServices().setBackNavigation(() => this._onBackNavigationInDraft(oBindingContext));
622
+ }
623
+ }
624
+ this.getAppComponent()
625
+ .getAppStateHandler()
626
+ .applyAppState()
627
+ .then(() => {
628
+ if (mParameters.forceFocus) {
629
+ setFocus();
630
+ }
631
+ })
632
+ .catch(function (Error) {
633
+ Log.error("Error while setting the focus", Error);
634
+ });
635
+
636
+ oInternalModelContext.setProperty("errorNavigationSectionFlag", false);
637
+ this._checkDataPointTitleForExternalNavigation();
638
+ }
639
+
640
+ /**
641
+ * Get the status of edit mode for sticky session.
642
+ *
643
+ * @returns {boolean} The status of edit mode for sticky session
644
+ *
645
+ *
646
+ */
647
+ getStickyEditMode() {
648
+ const oBindingContext = this.getView().getBindingContext && (this.getView().getBindingContext() as Context);
649
+ let bIsStickyEditMode = false;
650
+ if (oBindingContext) {
651
+ const bIsStickyMode = ModelHelper.isStickySessionSupported(oBindingContext.getModel().getMetaModel() as ODataMetaModel);
652
+ if (bIsStickyMode) {
653
+ bIsStickyEditMode = this.getView().getModel("ui").getProperty("/isEditable");
654
+ }
655
+ }
656
+ return bIsStickyEditMode;
657
+ }
658
+
659
+ _getObjectPageLayoutControl() {
660
+ return this.byId("fe::ObjectPage") as ObjectPageLayout;
661
+ }
662
+
663
+ _getPageTitleInformation() {
664
+ const oObjectPage = this._getObjectPageLayoutControl();
665
+ const oObjectPageSubtitle = oObjectPage.getCustomData().find(function (oCustomData: any) {
666
+ return oCustomData.getKey() === "ObjectPageSubtitle";
667
+ });
668
+ const oTitleInfo = {
669
+ title: oObjectPage.data("ObjectPageTitle") || "",
670
+ subtitle: oObjectPageSubtitle && oObjectPageSubtitle.getValue(),
671
+ intent: "",
672
+ icon: ""
673
+ };
674
+
675
+ return oTitleInfo;
676
+ }
677
+
678
+ _executeHeaderShortcut(sId: any) {
679
+ const sButtonId = this.getView().getId() + "--" + sId,
680
+ oButton = (this._getObjectPageLayoutControl().getHeaderTitle() as ObjectPageDynamicHeaderTitle)
681
+ .getActions()
682
+ .find(function (oElement: any) {
683
+ return oElement.getId() === sButtonId;
684
+ });
685
+ CommonUtils.fireButtonPress(oButton);
686
+ }
687
+
688
+ _executeFooterShortcut(sId: any) {
689
+ const sButtonId = this.getView().getId() + "--" + sId,
690
+ oButton = (this._getObjectPageLayoutControl().getFooter() as any).getContent().find(function (oElement: any) {
691
+ return oElement.getMetadata().getName() === "sap.m.Button" && oElement.getId() === sButtonId;
692
+ });
693
+ CommonUtils.fireButtonPress(oButton);
694
+ }
695
+
696
+ _executeTabShortCut(oExecution: any) {
697
+ const oObjectPage = this._getObjectPageLayoutControl(),
698
+ aSections = oObjectPage.getSections(),
699
+ iSectionIndexMax = aSections.length - 1,
700
+ sCommand = oExecution.oSource.getCommand();
701
+ let newSection,
702
+ iSelectedSectionIndex = oObjectPage.indexOfSection(this.byId(oObjectPage.getSelectedSection()) as ObjectPageSection);
703
+ if (iSelectedSectionIndex !== -1 && iSectionIndexMax > 0) {
704
+ if (sCommand === "NextTab") {
705
+ if (iSelectedSectionIndex <= iSectionIndexMax - 1) {
706
+ newSection = aSections[++iSelectedSectionIndex];
707
+ }
708
+ } else {
709
+ // PreviousTab
710
+ if (iSelectedSectionIndex !== 0) {
711
+ newSection = aSections[--iSelectedSectionIndex];
712
+ }
713
+ }
714
+ if (newSection) {
715
+ oObjectPage.setSelectedSection(newSection);
716
+ newSection.focus();
717
+ }
718
+ }
719
+ }
720
+
721
+ _getFooterVisibility() {
722
+ const oInternalModelContext = this.getView().getBindingContext("internal") as InternalModelContext;
723
+ const sViewId = this.getView().getId();
724
+ oInternalModelContext.setProperty("messageFooterContainsErrors", false);
725
+ sap.ui
726
+ .getCore()
727
+ .getMessageManager()
728
+ .getMessageModel()
729
+ .getData()
730
+ .forEach(function (oMessage: any) {
731
+ if (oMessage.validation && oMessage.type === "Error" && oMessage.target.indexOf(sViewId) > -1) {
732
+ oInternalModelContext.setProperty("messageFooterContainsErrors", true);
733
+ }
734
+ });
735
+ }
736
+
737
+ _showMessagePopover(err?: any, oRet?: any) {
738
+ if (err) {
739
+ Log.error(err);
740
+ }
741
+ if (!(this.getAppComponent().getRootContainer() as any).getCurrentPage().isA("sap.m.MessagePage")) {
742
+ const oMessageButton = this.getView().byId("fe::FooterBar::MessageButton") as any,
743
+ oMessagePopover = oMessageButton.oMessagePopover,
744
+ oItemBinding = oMessagePopover.getBinding("items");
745
+
746
+ if (oItemBinding.getLength() > 0 && !oMessagePopover.isOpen()) {
747
+ oMessageButton.setVisible(true);
748
+ // workaround to ensure that oMessageButton is rendered when openBy is called
749
+ setTimeout(function () {
750
+ oMessagePopover.openBy(oMessageButton);
751
+ }, 0);
752
+ }
753
+ }
754
+ return oRet;
755
+ }
756
+
757
+ _editDocument(oContext: any) {
758
+ const oModel = this.getView().getModel("ui");
759
+ BusyLocker.lock(oModel);
760
+ return this.editFlow.editDocument.apply(this.editFlow, [oContext]).finally(function () {
761
+ BusyLocker.unlock(oModel);
762
+ });
763
+ }
764
+
765
+ _saveDocument(oContext: any) {
766
+ const oModel = this.getView().getModel("ui"),
767
+ aWaitCreateDocuments: any[] = [];
768
+ // indicates if we are creating a new row in the OP
769
+ let bExecuteSideEffectsOnError = false;
770
+ BusyLocker.lock(oModel);
771
+ this._findTables().forEach((oTable: any) => {
772
+ const oBinding = this._getTableBinding(oTable);
773
+ const mParameters: any = {
774
+ creationMode: oTable.data("creationMode"),
775
+ creationRow: oTable.getCreationRow(),
776
+ createAtEnd: oTable.data("createAtEnd") === "true"
777
+ };
778
+ const bCreateDocument =
779
+ mParameters.creationRow &&
780
+ mParameters.creationRow.getBindingContext() &&
781
+ Object.keys(mParameters.creationRow.getBindingContext().getObject()).length > 1;
782
+ if (bCreateDocument) {
783
+ // the bSkipSideEffects is a parameter created when we click the save key. If we press this key
784
+ // we don't execute the handleSideEffects funciton to avoid batch redundancy
785
+ mParameters.bSkipSideEffects = true;
786
+ bExecuteSideEffectsOnError = true;
787
+ aWaitCreateDocuments.push(
788
+ this.editFlow.createDocument(oBinding, mParameters).then(function () {
789
+ return oBinding;
790
+ })
791
+ );
792
+ }
793
+ });
794
+ return Promise.all(aWaitCreateDocuments)
795
+ .then((aBindings: any[]) => {
796
+ const mParameters = {
797
+ bExecuteSideEffectsOnError: bExecuteSideEffectsOnError,
798
+ bindings: aBindings
799
+ };
800
+ return this.editFlow.saveDocument(oContext, mParameters).catch(() => this._showMessagePopover);
801
+ })
802
+ .finally(function () {
803
+ if (BusyLocker.isLocked(oModel)) {
804
+ BusyLocker.unlock(oModel);
805
+ }
806
+ });
807
+ }
808
+
809
+ _manageCollaboration() {
810
+ openManageDialog(this.getView());
811
+ }
812
+
813
+ _showCollaborationUserDetails(event: any) {
814
+ showUserDetails(event, this.getView());
815
+ }
816
+
817
+ _cancelDocument(oContext: any, mParameters: any) {
818
+ mParameters.cancelButton = this.getView().byId(mParameters.cancelButton); //to get the reference of the cancel button from command execution
819
+ return this.editFlow.cancelDocument(oContext, mParameters);
820
+ }
821
+
822
+ _applyDocument(oContext: any) {
823
+ return this.editFlow.applyDocument(oContext).catch(() => this._showMessagePopover());
824
+ }
825
+
826
+ _showSwitchDraftAndActivePopover(event: Event) {
827
+ const view = this.getView(),
828
+ source = event.getSource(),
829
+ fragmentName = "sap.fe.templates.ObjectPage.view.fragments.SwitchDraftAndActiveObjectPopOver";
830
+
831
+ if (this.switchDraftAndActivePopOver) {
832
+ this.switchDraftAndActivePopOver.openBy(source, false);
833
+ } else {
834
+ const localThisModel = new JSONModel({}),
835
+ preprocessorSettings = {
836
+ bindingContexts: {
837
+ "this": localThisModel.createBindingContext("/")
838
+ },
839
+ models: {
840
+ "this": localThisModel
841
+ }
842
+ };
843
+ const popoverFragment = XMLTemplateProcessor.loadTemplate(fragmentName, "fragment");
844
+ Promise.resolve(XMLPreprocessor.process(popoverFragment, { name: fragmentName }, preprocessorSettings))
845
+ .then((fragment) => {
846
+ return Fragment.load({ definition: fragment, controller: this });
847
+ })
848
+ .then((popover: any) => {
849
+ view.addDependent(popover);
850
+ popover.setModel(view.getModel("sap.fe.i18n"), "i18n");
851
+ popover.setPlacement("Bottom");
852
+ this.switchDraftAndActivePopOver = popover;
853
+ popover.attachAfterOpen(() => {
854
+ // While the list entry corresponding to the currently displayed document version is emphasized with a blue
855
+ // background, we need to pre-focus the other entry
856
+ const context: any = this.getView().getBindingContext(),
857
+ isActiveEntity = context.getObject().IsActiveEntity;
858
+ const switchDraftAndActiveOptionsList: SelectList = (popover.getContent() as unknown as Control[]).find(
859
+ (element) => element.data("listIdentifier") === "switchDraftAndActivePopoverList"
860
+ ) as SelectList;
861
+ const listItemToFocus: Item = isActiveEntity
862
+ ? (switchDraftAndActiveOptionsList.getItems().find((element) => element.getKey() === "switchToDraft") as Item)
863
+ : (switchDraftAndActiveOptionsList.getItems().find((element) => element.getKey() === "switchToActive") as Item);
864
+ listItemToFocus.focus();
865
+ });
866
+ popover.openBy(source);
867
+ // ensure to remove the reference to the draft popover as it would be destroyed on exit
868
+ view.attachEventOnce("beforeExit", () => {
869
+ delete this.switchDraftAndActivePopOver;
870
+ });
871
+ })
872
+ .catch(function (Error) {
873
+ Log.error("Error while opening the draft switch popup", Error);
874
+ });
875
+ }
876
+ }
877
+
878
+ _switchDraftAndActivePopoverListSelect(event: Event) {
879
+ const context: any = this.getView().getBindingContext(),
880
+ selectedItemKey = event.getParameter("item").getProperty("key"),
881
+ isActiveEntity = context.getObject().IsActiveEntity;
882
+ // It was decided that we should NOT set the entry in the list corresponding to the currently displayed document version to
883
+ // disabled, hence the user can click entries which to not cause an action (clicking "Draft" when you already display the
884
+ // draft version of the document)
885
+ // Hence we check here which entry in the list was clicked and which document version we currently display and only do
886
+ // the switch between draft / active version if it makes sense.
887
+ if ((isActiveEntity && selectedItemKey === "switchToDraft") || (!isActiveEntity && selectedItemKey === "switchToActive")) {
888
+ this.editFlow.toggleDraftActive(context);
889
+ }
890
+ ((event.getSource() as Control).getParent() as Popover).close();
891
+ }
892
+
893
+ _updateRelatedApps() {
894
+ const oObjectPage = this._getObjectPageLayoutControl();
895
+ if (CommonUtils.resolveStringtoBoolean(oObjectPage.data("showRelatedApps"))) {
896
+ CommonUtils.updateRelatedAppsDetails(oObjectPage);
897
+ }
898
+ }
899
+
900
+ _findTableInSubSection(aParentElement: any, aSubsection: any, aTables: any) {
901
+ const aSubSectionTables = [];
902
+ for (let element = 0; element < aParentElement.length; element++) {
903
+ let oElement = aParentElement[element].getContent instanceof Function && aParentElement[element].getContent();
904
+ if (oElement && oElement.isA && oElement.isA("sap.ui.layout.DynamicSideContent")) {
905
+ oElement = oElement.getMainContent instanceof Function && oElement.getMainContent();
906
+ if (oElement && oElement.length > 0) {
907
+ oElement = oElement[0];
908
+ }
909
+ }
910
+ if (oElement && oElement.isA && oElement.isA("sap.fe.macros.TableAPI")) {
911
+ oElement = oElement.getContent instanceof Function && oElement.getContent();
912
+ if (oElement && oElement.length > 0) {
913
+ oElement = oElement[0];
914
+ }
915
+ }
916
+ if (oElement && oElement.isA && oElement.isA("sap.ui.mdc.Table")) {
917
+ aTables.push(oElement);
918
+ aSubSectionTables.push({
919
+ "table": oElement,
920
+ "gridTable": oElement.getType().isA("sap.ui.mdc.table.GridTableType")
921
+ });
922
+ }
923
+ }
924
+ if (
925
+ aSubSectionTables.length === 1 &&
926
+ aParentElement.length === 1 &&
927
+ aSubSectionTables[0].gridTable &&
928
+ !aSubsection.hasStyleClass("sapUxAPObjectPageSubSectionFitContainer")
929
+ ) {
930
+ //In case there is only a single table in a section we fit that to the whole page so that the scrollbar comes only on table and not on page
931
+ aSubsection.addStyleClass("sapUxAPObjectPageSubSectionFitContainer");
932
+ } else {
933
+ if (aSubSectionTables && !aSubsection.hasStyleClass("sapUxAPObjectPageSubSectionFitContainer")) {
934
+ aSubSectionTables.forEach(function (oTable: { table: any; gridTable: any }) {
935
+ if (oTable.gridTable) {
936
+ //Resetting the row count to default value in case we have a combination of forms and tables or multiple tables in a subsection
937
+ oTable.table.getType().setRowCount(null);
938
+ }
939
+ });
940
+ }
941
+ }
942
+ }
943
+
944
+ _getAllSubSections() {
945
+ const oObjectPage = this._getObjectPageLayoutControl();
946
+ let aSubSections: any[] = [];
947
+ oObjectPage.getSections().forEach(function (oSection: any) {
948
+ aSubSections = aSubSections.concat(oSection.getSubSections());
949
+ });
950
+ return aSubSections;
951
+ }
952
+
953
+ _getAllBlocks() {
954
+ let aBlocks: any[] = [];
955
+ this._getAllSubSections().forEach(function (oSubSection: any) {
956
+ aBlocks = aBlocks.concat(oSubSection.getBlocks());
957
+ });
958
+ return aBlocks;
959
+ }
960
+
961
+ _findTables() {
962
+ const aSubSections = this._getAllSubSections();
963
+ const aTables: any[] = [];
964
+ for (let subSection = 0; subSection < aSubSections.length; subSection++) {
965
+ this._findTableInSubSection(aSubSections[subSection].getBlocks(), aSubSections[subSection], aTables);
966
+ this._findTableInSubSection(aSubSections[subSection].getMoreBlocks(), aSubSections[subSection], aTables);
967
+ }
968
+ return aTables;
969
+ }
970
+
971
+ _closeSideContent() {
972
+ this._getAllBlocks().forEach(function (oBlock: any) {
973
+ const oContent = oBlock.getContent instanceof Function && oBlock.getContent();
974
+ if (oContent && oContent.isA && oContent.isA("sap.ui.layout.DynamicSideContent")) {
975
+ if (oContent.setShowSideContent instanceof Function) {
976
+ oContent.setShowSideContent(false);
977
+ }
978
+ }
979
+ });
980
+ }
981
+
982
+ /**
983
+ * Chart Context is resolved for 1:n microcharts.
984
+ *
985
+ * @param {sap.ui.model.Context} oChartContext The Context of the MicroChart
986
+ * @param {string} sChartPath The collectionPath of the the chart
987
+ * @returns {Array} Array of Attributes of the chart Context
988
+ */
989
+ _getChartContextData(oChartContext: any, sChartPath: string) {
990
+ const oContextData = oChartContext.getObject();
991
+ let oChartContextData = [oContextData];
992
+ if (oChartContext && sChartPath) {
993
+ if (oContextData[sChartPath]) {
994
+ oChartContextData = oContextData[sChartPath];
995
+ delete oContextData[sChartPath];
996
+ oChartContextData.push(oContextData);
997
+ }
998
+ }
999
+ return oChartContextData;
1000
+ }
1001
+
1002
+ /**
1003
+ * Scroll the tables to the row with the sPath
1004
+ *
1005
+ * @function
1006
+ * @name sap.fe.templates.ObjectPage.ObjectPageController.controller#_scrollTablesToRow
1007
+ * @param {string} sRowPath 'sPath of the table row'
1008
+ *
1009
+ */
1010
+
1011
+ _scrollTablesToRow(sRowPath: string) {
1012
+ if (this._findTables && this._findTables().length > 0) {
1013
+ const aTables = this._findTables();
1014
+ for (let i = 0; i < aTables.length; i++) {
1015
+ TableScroller.scrollTableToRow(aTables[i], sRowPath);
1016
+ }
1017
+ }
1018
+ }
1019
+
1020
+ /**
1021
+ * Method to merge selected contexts and filters.
1022
+ *
1023
+ * @function
1024
+ * @name _mergeMultipleContexts
1025
+ * @param {object} oPageContext Page context
1026
+ * @param {object|Array} aLineContext Selected Contexts
1027
+ * @param {string} sChartPath Collection name of the chart
1028
+ * @returns {object} Selection Variant Object
1029
+ */
1030
+ _mergeMultipleContexts(oPageContext: Context, aLineContext: any[], sChartPath: string) {
1031
+ let aAttributes: any[] = [],
1032
+ aPageAttributes = [],
1033
+ oContext,
1034
+ sMetaPathLine: string,
1035
+ sPathLine;
1036
+
1037
+ const sPagePath = oPageContext.getPath();
1038
+ const oMetaModel = oPageContext && oPageContext.getModel() && (oPageContext.getModel().getMetaModel() as ODataMetaModel);
1039
+ const sMetaPathPage = oMetaModel && oMetaModel.getMetaPath(sPagePath).replace(/^\/*/, "");
1040
+
1041
+ // Get single line context if necessary
1042
+ if (aLineContext && aLineContext.length) {
1043
+ oContext = aLineContext[0];
1044
+ sPathLine = oContext.getPath();
1045
+ sMetaPathLine = oMetaModel && oMetaModel.getMetaPath(sPathLine).replace(/^\/*/, "");
1046
+
1047
+ aLineContext.map((oSingleContext: any) => {
1048
+ if (sChartPath) {
1049
+ const oChartContextData = this._getChartContextData(oSingleContext, sChartPath);
1050
+ if (oChartContextData) {
1051
+ aAttributes = oChartContextData.map(function (oChartContextData: any) {
1052
+ return {
1053
+ contextData: oChartContextData,
1054
+ entitySet: sMetaPathPage + "/" + sChartPath
1055
+ };
1056
+ });
1057
+ }
1058
+ } else {
1059
+ aAttributes.push({
1060
+ contextData: oSingleContext.getObject(),
1061
+ entitySet: sMetaPathLine
1062
+ });
1063
+ }
1064
+ });
1065
+ }
1066
+ aPageAttributes.push({
1067
+ contextData: oPageContext.getObject(),
1068
+ entitySet: sMetaPathPage
1069
+ });
1070
+ // Adding Page Context to selection variant
1071
+ aPageAttributes = CommonUtils.removeSensitiveData(aPageAttributes, oMetaModel);
1072
+ const oPageLevelSV = CommonUtils.addPageContextToSelectionVariant(new SelectionVariant(), aPageAttributes, this.getView());
1073
+ aAttributes = CommonUtils.removeSensitiveData(aAttributes, oMetaModel);
1074
+ return {
1075
+ selectionVariant: oPageLevelSV,
1076
+ attributes: aAttributes
1077
+ };
1078
+ }
1079
+
1080
+ _getBatchGroupsForView() {
1081
+ const oViewData = this.getView().getViewData() as any,
1082
+ oConfigurations = oViewData.controlConfiguration,
1083
+ aConfigurations = oConfigurations && Object.keys(oConfigurations),
1084
+ aBatchGroups = ["$auto.Heroes", "$auto.Decoration", "$auto.Workers"];
1085
+
1086
+ if (aConfigurations && aConfigurations.length > 0) {
1087
+ aConfigurations.forEach(function (sKey: any) {
1088
+ const oConfiguration = oConfigurations[sKey];
1089
+ if (oConfiguration.requestGroupId === "LongRunners") {
1090
+ aBatchGroups.push("$auto.LongRunners");
1091
+ }
1092
+ });
1093
+ }
1094
+ return aBatchGroups;
1095
+ }
1096
+
1097
+ /*
1098
+ * Reset Breadcrumb links
1099
+ *
1100
+ * @function
1101
+ * @param {sap.m.Breadcrumbs} [oSource] parent control
1102
+ * @description Used when context of the objectpage changes.
1103
+ * This event callback is attached to modelContextChange
1104
+ * event of the Breadcrumb control to catch context change.
1105
+ * Then element binding and hrefs are updated for each Link.
1106
+ *
1107
+ * @ui5-restricted
1108
+ * @experimental
1109
+ */
1110
+ _setBreadcrumbLinks(oSource: any) {
1111
+ const oContext = oSource.getBindingContext();
1112
+ const oAppComponent = this.getAppComponent();
1113
+ if (oContext) {
1114
+ const sNewPath = oContext.getPath(),
1115
+ aPathParts = sNewPath.split("/"),
1116
+ oMetaModel = oAppComponent.getMetaModel();
1117
+ let sPath = "",
1118
+ iSkipParameterized = 0;
1119
+
1120
+ aPathParts.shift();
1121
+ aPathParts.splice(-1, 1);
1122
+ aPathParts.forEach(function (sPathPart: any, i: any) {
1123
+ sPath += "/" + sPathPart;
1124
+ const oRootViewController = oAppComponent.getRootViewController() as RootContainerBaseController;
1125
+ const sParameterPath = oMetaModel.getMetaPath(sPath);
1126
+ const bResultContext = oMetaModel.getObject(sParameterPath + "/@com.sap.vocabularies.Common.v1.ResultContext");
1127
+ if (bResultContext) {
1128
+ // We dont need to create a breadcrumb for Parameter path
1129
+ iSkipParameterized = 1;
1130
+ return;
1131
+ }
1132
+
1133
+ const pWaitForTitleHiearchyInfo = oRootViewController.getTitleInfoFromPath(sPath);
1134
+
1135
+ pWaitForTitleHiearchyInfo
1136
+ .then(function (oTitleHiearchyInfo: any) {
1137
+ const idx = i - iSkipParameterized,
1138
+ oLink = oSource.getLinks()[idx] ? oSource.getLinks()[idx] : new Link();
1139
+ // sCurrentEntity is a fallback value in case of empty title
1140
+ oLink.setText(oTitleHiearchyInfo.subtitle || oTitleHiearchyInfo.title);
1141
+ oLink.setHref(oTitleHiearchyInfo.intent);
1142
+ if (!oSource.getLinks()[idx]) {
1143
+ oSource.addLink(oLink);
1144
+ }
1145
+ })
1146
+ .catch(function (oError: any) {
1147
+ Log.error("Error while computing the title hierarchy", oError);
1148
+ });
1149
+ });
1150
+ }
1151
+ }
1152
+
1153
+ _checkDataPointTitleForExternalNavigation() {
1154
+ const oView = this.getView();
1155
+ const oInternalModelContext = oView.getBindingContext("internal") as InternalModelContext;
1156
+ const oDataPoints = CommonUtils.getHeaderFacetItemConfigForExternalNavigation(
1157
+ oView.getViewData(),
1158
+ this.getAppComponent().getRoutingService().getOutbounds()
1159
+ );
1160
+ const oShellServices = this.getAppComponent().getShellServices();
1161
+ const oPageContext = oView && (oView.getBindingContext() as Context);
1162
+ oInternalModelContext.setProperty("isHeaderDPLinkVisible", {});
1163
+ if (oPageContext) {
1164
+ oPageContext
1165
+ .requestObject()
1166
+ .then(function (oData: any) {
1167
+ fnGetLinks(oDataPoints, oData);
1168
+ })
1169
+ .catch(function (oError: any) {
1170
+ Log.error("Cannot retrieve the links from the shell service", oError);
1171
+ });
1172
+ }
1173
+
1174
+ /**
1175
+ * @param oError
1176
+ */
1177
+ function fnOnError(oError: any) {
1178
+ Log.error(oError);
1179
+ }
1180
+
1181
+ function fnSetLinkEnablement(id: string, aSupportedLinks: any) {
1182
+ const sLinkId = id;
1183
+ // process viable links from getLinks for all datapoints having outbound
1184
+ if (aSupportedLinks && aSupportedLinks.length === 1 && aSupportedLinks[0].supported) {
1185
+ oInternalModelContext.setProperty("isHeaderDPLinkVisible/" + sLinkId, true);
1186
+ }
1187
+ }
1188
+
1189
+ /**
1190
+ * @param oDataPoints
1191
+ * @param oPageData
1192
+ */
1193
+ function fnGetLinks(oDataPoints: any, oPageData: any) {
1194
+ for (const sId in oDataPoints) {
1195
+ const oDataPoint = oDataPoints[sId];
1196
+ const oParams: any = {};
1197
+ const oLink = oView.byId(sId);
1198
+ if (!oLink) {
1199
+ // for data points configured in app descriptor but not annotated in the header
1200
+ continue;
1201
+ }
1202
+ const oLinkContext = oLink.getBindingContext();
1203
+ const oLinkData: any = oLinkContext && oLinkContext.getObject();
1204
+ let oMixedContext: any = merge({}, oPageData, oLinkData);
1205
+ // process semantic object mappings
1206
+ if (oDataPoint.semanticObjectMapping) {
1207
+ const aSemanticObjectMapping = oDataPoint.semanticObjectMapping;
1208
+ for (const item in aSemanticObjectMapping) {
1209
+ const oMapping = aSemanticObjectMapping[item];
1210
+ const sMainProperty = oMapping["LocalProperty"]["$PropertyPath"];
1211
+ const sMappedProperty = oMapping["SemanticObjectProperty"];
1212
+ if (sMainProperty !== sMappedProperty) {
1213
+ if (oMixedContext.hasOwnProperty(sMainProperty)) {
1214
+ const oNewMapping: any = {};
1215
+ oNewMapping[sMappedProperty] = oMixedContext[sMainProperty];
1216
+ oMixedContext = merge({}, oMixedContext, oNewMapping);
1217
+ delete oMixedContext[sMainProperty];
1218
+ }
1219
+ }
1220
+ }
1221
+ }
1222
+
1223
+ if (oMixedContext) {
1224
+ for (const sKey in oMixedContext) {
1225
+ if (sKey.indexOf("_") !== 0 && sKey.indexOf("odata.context") === -1) {
1226
+ oParams[sKey] = oMixedContext[sKey];
1227
+ }
1228
+ }
1229
+ }
1230
+ // validate if a link must be rendered
1231
+ oShellServices
1232
+ .isNavigationSupported([
1233
+ {
1234
+ target: {
1235
+ semanticObject: oDataPoint.semanticObject,
1236
+ action: oDataPoint.action
1237
+ },
1238
+ params: oParams
1239
+ }
1240
+ ])
1241
+ .then((aLinks) => {
1242
+ return fnSetLinkEnablement(sId, aLinks);
1243
+ })
1244
+ .catch(fnOnError);
1245
+ }
1246
+ }
1247
+ }
1248
+
1249
+ handlers = {
1250
+ onTableContextChange(this: ObjectPageController, oEvent: any) {
1251
+ const oSource = oEvent.getSource();
1252
+ let oTable: any;
1253
+ this._findTables().some(function (_oTable: any) {
1254
+ if (_oTable.getRowBinding() === oSource) {
1255
+ oTable = _oTable;
1256
+ return true;
1257
+ }
1258
+ return false;
1259
+ });
1260
+
1261
+ const oCurrentActionPromise = this._editFlow.getCurrentActionPromise();
1262
+ if (oCurrentActionPromise) {
1263
+ let aTableContexts: any;
1264
+ if (oTable.getType().getMetadata().isA("sap.ui.mdc.table.GridTableType")) {
1265
+ aTableContexts = oSource.getContexts(0);
1266
+ } else {
1267
+ aTableContexts = oSource.getCurrentContexts();
1268
+ }
1269
+ //if contexts are not fully loaded the getcontexts function above will trigger a new change event call
1270
+ if (!aTableContexts[0]) {
1271
+ return;
1272
+ }
1273
+ oCurrentActionPromise
1274
+ .then((oActionResponse: any) => {
1275
+ if (!oActionResponse || oActionResponse.controlId !== oTable.sId) {
1276
+ return;
1277
+ }
1278
+ const oActionData = oActionResponse.oData;
1279
+ const aKeys = oActionResponse.keys;
1280
+ let iNewItemp = -1;
1281
+ aTableContexts.find(function (oTableContext: any, i: any) {
1282
+ const oTableData = oTableContext.getObject();
1283
+ const bCompare = aKeys.every(function (sKey: any) {
1284
+ return oTableData[sKey] === oActionData[sKey];
1285
+ });
1286
+ if (bCompare) {
1287
+ iNewItemp = i;
1288
+ }
1289
+ return bCompare;
1290
+ });
1291
+ if (iNewItemp !== -1) {
1292
+ const aDialogs = InstanceManager.getOpenDialogs();
1293
+ const oDialog =
1294
+ aDialogs.length > 0 ? aDialogs.find((dialog) => dialog.data("FullScreenDialog") !== true) : null;
1295
+ if (oDialog) {
1296
+ // by design, a sap.m.dialog set the focus to the previous focused element when closing.
1297
+ // we should wait for the dialog to be close before to focus another element
1298
+ oDialog.attachEventOnce("afterClose", function () {
1299
+ oTable.focusRow(iNewItemp, true);
1300
+ });
1301
+ } else {
1302
+ oTable.focusRow(iNewItemp, true);
1303
+ }
1304
+ this._editFlow.deleteCurrentActionPromise();
1305
+ }
1306
+ })
1307
+ .catch(function (err: any) {
1308
+ Log.error("An error occurs while scrolling to the newly created Item: " + err);
1309
+ });
1310
+ }
1311
+ // fire ModelContextChange on the message button whenever the table context changes
1312
+ const oMessageButton = this.getView().byId("fe::FooterBar::MessageButton");
1313
+ oMessageButton.fireModelContextChange();
1314
+ },
1315
+
1316
+ /**
1317
+ * Invokes an action - bound/unbound and sets the page dirty.
1318
+ *
1319
+ * @param oView
1320
+ * @param {string} sActionName The name of the action to be called
1321
+ * @param {map} [mParameters] Contains the following attributes:
1322
+ * @param {sap.ui.model.odata.v4.Context} [mParameters.contexts] Mandatory for a bound action, either one context or an array with contexts for which the action shall be called
1323
+ * @param {sap.ui.model.odata.v4.ODataModel} [mParameters.model] Mandatory for an unbound action; an instance of an OData V4 model
1324
+ * @returns {Promise}
1325
+ * @ui5-restricted
1326
+ * @final
1327
+ */
1328
+ onCallAction(oView: any, sActionName: string, mParameters: any) {
1329
+ const oController = oView.getController();
1330
+ const that = oController;
1331
+ return oController.editFlow
1332
+ .invokeAction(sActionName, mParameters)
1333
+ .then(that._showMessagePopover.bind(that, undefined))
1334
+ .catch(that._showMessagePopover.bind(that));
1335
+ },
1336
+ onDataPointTitlePressed(oController: any, oSource: any, oManifestOutbound: any, sControlConfig: any, sCollectionPath: any) {
1337
+ oManifestOutbound = typeof oManifestOutbound === "string" ? JSON.parse(oManifestOutbound) : oManifestOutbound;
1338
+ const oTargetInfo = oManifestOutbound[sControlConfig],
1339
+ aSemanticObjectMapping = CommonUtils.getSemanticObjectMapping(oTargetInfo),
1340
+ oDataPointOrChartBindingContext = oSource.getBindingContext(),
1341
+ sMetaPath = oDataPointOrChartBindingContext
1342
+ .getModel()
1343
+ .getMetaModel()
1344
+ .getMetaPath(oDataPointOrChartBindingContext.getPath());
1345
+ let aNavigationData = oController._getChartContextData(oDataPointOrChartBindingContext, sCollectionPath);
1346
+ let additionalNavigationParameters;
1347
+
1348
+ aNavigationData = aNavigationData.map(function (oNavigationData: any) {
1349
+ return {
1350
+ data: oNavigationData,
1351
+ metaPath: sMetaPath + (sCollectionPath ? "/" + sCollectionPath : "")
1352
+ };
1353
+ });
1354
+ if (oTargetInfo && oTargetInfo.parameters) {
1355
+ const oParams = oTargetInfo.parameters && oController._intentBasedNavigation.getOutboundParams(oTargetInfo.parameters);
1356
+ if (Object.keys(oParams).length > 0) {
1357
+ additionalNavigationParameters = oParams;
1358
+ }
1359
+ }
1360
+ if (oTargetInfo && oTargetInfo.semanticObject && oTargetInfo.action) {
1361
+ oController._intentBasedNavigation.navigate(oTargetInfo.semanticObject, oTargetInfo.action, {
1362
+ navigationContexts: aNavigationData,
1363
+ semanticObjectMapping: aSemanticObjectMapping,
1364
+ additionalNavigationParameters: additionalNavigationParameters
1365
+ });
1366
+ }
1367
+ },
1368
+ /**
1369
+ * Triggers an outbound navigation when a user chooses the chevron.
1370
+ *
1371
+ * @param {object} oController
1372
+ * @param {string} sOutboundTarget Name of the outbound target (needs to be defined in the manifest)
1373
+ * @param {sap.ui.model.odata.v4.Context} oContext The context that contains the data for the target app
1374
+ * @param {string} sCreatePath Create path when the chevron is created.
1375
+ * @returns {Promise} Promise which is resolved once the navigation is triggered (??? maybe only once finished?)
1376
+ * @ui5-restricted
1377
+ * @final
1378
+ */
1379
+ onChevronPressNavigateOutBound(oController: ObjectPageController, sOutboundTarget: string, oContext: any, sCreatePath: string) {
1380
+ return oController._intentBasedNavigation.onChevronPressNavigateOutBound(oController, sOutboundTarget, oContext, sCreatePath);
1381
+ },
1382
+
1383
+ onNavigateChange(this: ObjectPageController, oEvent: any) {
1384
+ //will be called always when we click on a section tab
1385
+ this.getExtensionAPI().updateAppState();
1386
+ this.bSectionNavigated = true;
1387
+
1388
+ const oInternalModelContext = this.getView().getBindingContext("internal") as InternalModelContext;
1389
+ const oObjectPage = this._getObjectPageLayoutControl();
1390
+ if (
1391
+ oObjectPage.getModel("ui").getProperty("/isEditable") &&
1392
+ (this.getView().getViewData() as any).sectionLayout === "Tabs" &&
1393
+ oInternalModelContext.getProperty("errorNavigationSectionFlag") === false
1394
+ ) {
1395
+ const oSubSection = oEvent.getParameter("subSection");
1396
+ this._updateFocusInEditMode([oSubSection]);
1397
+ }
1398
+ },
1399
+ onVariantSelected: function (this: ObjectPageController) {
1400
+ this.getExtensionAPI().updateAppState();
1401
+ },
1402
+ onVariantSaved: function (this: ObjectPageController) {
1403
+ //TODO: Should remove this setTimeOut once Variant Management provides an api to fetch the current variant key on save
1404
+ setTimeout(() => {
1405
+ this.getExtensionAPI().updateAppState();
1406
+ }, 500);
1407
+ },
1408
+ navigateToSubSection: function (oController: ObjectPageController, vDetailConfig: any) {
1409
+ const oDetailConfig = typeof vDetailConfig === "string" ? JSON.parse(vDetailConfig) : vDetailConfig;
1410
+ const oObjectPage = oController.getView().byId("fe::ObjectPage") as ObjectPageLayout;
1411
+ let oSection;
1412
+ let oSubSection;
1413
+ if (oDetailConfig.sectionId) {
1414
+ oSection = oController.getView().byId(oDetailConfig.sectionId) as ObjectPageSection;
1415
+ oSubSection = (
1416
+ oDetailConfig.subSectionId
1417
+ ? oController.getView().byId(oDetailConfig.subSectionId)
1418
+ : oSection && oSection.getSubSections() && oSection.getSubSections()[0]
1419
+ ) as ObjectPageSubSection;
1420
+ } else if (oDetailConfig.subSectionId) {
1421
+ oSubSection = oController.getView().byId(oDetailConfig.subSectionId) as ObjectPageSubSection;
1422
+ oSection = oSubSection && (oSubSection.getParent() as ObjectPageSection);
1423
+ }
1424
+ if (!oSection || !oSubSection || !oSection.getVisible() || !oSubSection.getVisible()) {
1425
+ ((oController.getView().getModel("sap.fe.i18n") as ResourceModel).getResourceBundle() as Promise<ResourceBundle>)
1426
+ .then(function (oResourceBundle) {
1427
+ const sTitle = CommonUtils.getTranslatedText(
1428
+ "C_ROUTING_NAVIGATION_DISABLED_TITLE",
1429
+ oResourceBundle,
1430
+ null,
1431
+ (oController.getView().getViewData() as any).entitySet
1432
+ );
1433
+ Log.error(sTitle);
1434
+ MessageBox.error(sTitle);
1435
+ })
1436
+ .catch(function (error) {
1437
+ Log.error(error);
1438
+ });
1439
+ } else {
1440
+ oObjectPage.scrollToSection(oSubSection.getId());
1441
+ // trigger iapp state change
1442
+ oObjectPage.fireNavigate({
1443
+ section: oSection,
1444
+ subSection: oSubSection
1445
+ });
1446
+ }
1447
+ },
1448
+ onChartSelectionChanged: function (oEvent: any) {
1449
+ ChartRuntime.fnUpdateChart(oEvent);
1450
+ }
1451
+ };
1452
+ }
1453
+
1454
+ export default ObjectPageController;