@sapui5/sap.fe.templates 1.100.0 → 1.101.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 (132) 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 +123 -112
  14. package/src/sap/fe/templates/ListReport/ExtensionAPI.ts +100 -0
  15. package/src/sap/fe/templates/ListReport/ListReport.view.xml +2 -1
  16. package/src/sap/fe/templates/ListReport/ListReportController.controller.js +1111 -1081
  17. package/src/sap/fe/templates/ListReport/ListReportController.controller.ts +1009 -0
  18. package/src/sap/fe/templates/ListReport/overrides/IntentBasedNavigation.js +54 -53
  19. package/src/sap/fe/templates/ListReport/overrides/IntentBasedNavigation.ts +55 -0
  20. package/src/sap/fe/templates/ListReport/overrides/Share.js +134 -137
  21. package/src/sap/fe/templates/ListReport/overrides/Share.ts +134 -0
  22. package/src/sap/fe/templates/ListReport/overrides/ViewState.js +443 -428
  23. package/src/sap/fe/templates/ListReport/overrides/ViewState.ts +413 -0
  24. package/src/sap/fe/templates/ListReport/view/fragments/CollectionVisualization.fragment.xml +25 -25
  25. package/src/sap/fe/templates/ListReport/view/fragments/MultipleMode.fragment.js +72 -0
  26. package/src/sap/fe/templates/ListReport/view/fragments/MultipleMode.fragment.ts +62 -0
  27. package/src/sap/fe/templates/ListReport/view/fragments/{MultipleMode.fragment.xml → MultipleModeOld.fragment.xml} +24 -23
  28. package/src/sap/fe/templates/ObjectPage/AnnotationHelper.js +478 -514
  29. package/src/sap/fe/templates/ObjectPage/AnnotationHelper.ts +511 -0
  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 +3 -9
  35. package/src/sap/fe/templates/ObjectPage/ObjectPageController.controller.js +1530 -1447
  36. package/src/sap/fe/templates/ObjectPage/ObjectPageController.controller.ts +1442 -0
  37. package/src/sap/fe/templates/ObjectPage/controls/StashableHBox.js +136 -101
  38. package/src/sap/fe/templates/ObjectPage/controls/StashableHBox.ts +84 -0
  39. package/src/sap/fe/templates/ObjectPage/controls/StashableVBox.js +24 -21
  40. package/src/sap/fe/templates/ObjectPage/controls/StashableVBox.ts +10 -0
  41. package/src/sap/fe/templates/ObjectPage/controls/SubSectionBlock.js +98 -53
  42. package/src/sap/fe/templates/ObjectPage/controls/SubSectionBlock.ts +50 -0
  43. package/src/sap/fe/templates/ObjectPage/designtime/FlexBox.designtime.js +20 -19
  44. package/src/sap/fe/templates/ObjectPage/designtime/FlexBox.designtime.ts +15 -0
  45. package/src/sap/fe/templates/ObjectPage/designtime/StashableHBox.designtime.js +50 -47
  46. package/src/sap/fe/templates/ObjectPage/designtime/StashableHBox.designtime.ts +47 -0
  47. package/src/sap/fe/templates/ObjectPage/designtime/StashableVBox.designtime.js +34 -34
  48. package/src/sap/fe/templates/ObjectPage/designtime/StashableVBox.designtime.ts +34 -0
  49. package/src/sap/fe/templates/ObjectPage/flexibility/StashableHBox.flexibility.js +15 -15
  50. package/src/sap/fe/templates/ObjectPage/flexibility/StashableHBox.flexibility.ts +13 -0
  51. package/src/sap/fe/templates/ObjectPage/flexibility/StashableVBox.flexibility.js +11 -11
  52. package/src/sap/fe/templates/ObjectPage/flexibility/StashableVBox.flexibility.ts +7 -0
  53. package/src/sap/fe/templates/ObjectPage/overrides/IntentBasedNavigation.js +55 -52
  54. package/src/sap/fe/templates/ObjectPage/overrides/IntentBasedNavigation.ts +57 -0
  55. package/src/sap/fe/templates/ObjectPage/overrides/InternalRouting.js +15 -17
  56. package/src/sap/fe/templates/ObjectPage/overrides/InternalRouting.ts +13 -0
  57. package/src/sap/fe/templates/ObjectPage/overrides/MessageHandler.js +13 -17
  58. package/src/sap/fe/templates/ObjectPage/overrides/MessageHandler.ts +14 -0
  59. package/src/sap/fe/templates/ObjectPage/overrides/Paginator.js +23 -21
  60. package/src/sap/fe/templates/ObjectPage/overrides/Paginator.ts +21 -0
  61. package/src/sap/fe/templates/ObjectPage/overrides/Share.js +310 -317
  62. package/src/sap/fe/templates/ObjectPage/overrides/Share.ts +316 -0
  63. package/src/sap/fe/templates/ObjectPage/overrides/ViewState.js +66 -57
  64. package/src/sap/fe/templates/ObjectPage/overrides/ViewState.ts +65 -0
  65. package/src/sap/fe/templates/ObjectPage/templating/ObjectPageTemplating.js +1 -1
  66. package/src/sap/fe/templates/ObjectPage/templating/ObjectPageTemplating.ts +1 -1
  67. package/src/sap/fe/templates/ObjectPage/view/fragments/Actions.fragment.xml +18 -24
  68. package/src/sap/fe/templates/ObjectPage/view/fragments/CollaborationDraft.fragment.xml +11 -9
  69. package/src/sap/fe/templates/ObjectPage/view/fragments/FooterContent.fragment.xml +4 -4
  70. package/src/sap/fe/templates/ObjectPage/view/fragments/SwitchDraftAndActiveObjectPopOver.fragment.xml +27 -0
  71. package/src/sap/fe/templates/RootContainer/controller/Fcl.controller.js +851 -817
  72. package/src/sap/fe/templates/RootContainer/controller/Fcl.controller.ts +795 -0
  73. package/src/sap/fe/templates/RootContainer/controller/NavContainer.controller.js +205 -189
  74. package/src/sap/fe/templates/RootContainer/controller/NavContainer.controller.ts +178 -0
  75. package/src/sap/fe/templates/RootContainer/controller/RootContainerBaseController.js +484 -459
  76. package/src/sap/fe/templates/RootContainer/controller/RootContainerBaseController.ts +438 -0
  77. package/src/sap/fe/templates/RootContainer/overrides/EditFlow.js +16 -14
  78. package/src/sap/fe/templates/RootContainer/overrides/EditFlow.ts +20 -0
  79. package/src/sap/fe/templates/TableScroller.js +45 -53
  80. package/src/sap/fe/templates/TableScroller.ts +48 -0
  81. package/src/sap/fe/templates/controls/Chart.fragment.xml +18 -17
  82. package/src/sap/fe/templates/controls/MacroChart.fragment.xml +22 -0
  83. package/src/sap/fe/templates/library.js +49 -63
  84. package/src/sap/fe/templates/library.ts +57 -0
  85. package/src/sap/fe/templates/messagebundle.properties +19 -7
  86. package/src/sap/fe/templates/messagebundle_ar.properties +6 -2
  87. package/src/sap/fe/templates/messagebundle_bg.properties +6 -2
  88. package/src/sap/fe/templates/messagebundle_ca.properties +6 -2
  89. package/src/sap/fe/templates/messagebundle_cs.properties +6 -2
  90. package/src/sap/fe/templates/messagebundle_cy.properties +6 -2
  91. package/src/sap/fe/templates/messagebundle_da.properties +6 -2
  92. package/src/sap/fe/templates/messagebundle_de.properties +6 -2
  93. package/src/sap/fe/templates/messagebundle_el.properties +6 -2
  94. package/src/sap/fe/templates/messagebundle_en.properties +6 -2
  95. package/src/sap/fe/templates/messagebundle_en_GB.properties +6 -2
  96. package/src/sap/fe/templates/messagebundle_en_US_saprigi.properties +6 -2
  97. package/src/sap/fe/templates/messagebundle_en_US_saptrc.properties +6 -2
  98. package/src/sap/fe/templates/messagebundle_es.properties +6 -2
  99. package/src/sap/fe/templates/messagebundle_es_MX.properties +6 -2
  100. package/src/sap/fe/templates/messagebundle_et.properties +6 -2
  101. package/src/sap/fe/templates/messagebundle_fi.properties +6 -2
  102. package/src/sap/fe/templates/messagebundle_fr.properties +6 -2
  103. package/src/sap/fe/templates/messagebundle_fr_CA.properties +6 -2
  104. package/src/sap/fe/templates/messagebundle_hi.properties +6 -2
  105. package/src/sap/fe/templates/messagebundle_hr.properties +6 -2
  106. package/src/sap/fe/templates/messagebundle_hu.properties +6 -2
  107. package/src/sap/fe/templates/messagebundle_id.properties +6 -2
  108. package/src/sap/fe/templates/messagebundle_it.properties +6 -2
  109. package/src/sap/fe/templates/messagebundle_iw.properties +6 -2
  110. package/src/sap/fe/templates/messagebundle_ja.properties +6 -2
  111. package/src/sap/fe/templates/messagebundle_kk.properties +6 -2
  112. package/src/sap/fe/templates/messagebundle_ko.properties +6 -2
  113. package/src/sap/fe/templates/messagebundle_lt.properties +6 -2
  114. package/src/sap/fe/templates/messagebundle_lv.properties +6 -2
  115. package/src/sap/fe/templates/messagebundle_ms.properties +6 -2
  116. package/src/sap/fe/templates/messagebundle_nl.properties +6 -2
  117. package/src/sap/fe/templates/messagebundle_no.properties +6 -2
  118. package/src/sap/fe/templates/messagebundle_pl.properties +6 -2
  119. package/src/sap/fe/templates/messagebundle_pt.properties +6 -2
  120. package/src/sap/fe/templates/messagebundle_pt_PT.properties +6 -2
  121. package/src/sap/fe/templates/messagebundle_ro.properties +6 -2
  122. package/src/sap/fe/templates/messagebundle_ru.properties +6 -2
  123. package/src/sap/fe/templates/messagebundle_sh.properties +6 -2
  124. package/src/sap/fe/templates/messagebundle_sk.properties +6 -2
  125. package/src/sap/fe/templates/messagebundle_sl.properties +6 -2
  126. package/src/sap/fe/templates/messagebundle_sv.properties +6 -2
  127. package/src/sap/fe/templates/messagebundle_th.properties +6 -2
  128. package/src/sap/fe/templates/messagebundle_tr.properties +6 -2
  129. package/src/sap/fe/templates/messagebundle_uk.properties +6 -2
  130. package/src/sap/fe/templates/messagebundle_vi.properties +6 -2
  131. package/src/sap/fe/templates/messagebundle_zh_CN.properties +6 -2
  132. package/src/sap/fe/templates/messagebundle_zh_TW.properties +6 -2
@@ -0,0 +1,795 @@
1
+ import Log from "sap/base/Log";
2
+ import FlexibleColumnLayout from "sap/f/FlexibleColumnLayout";
3
+ import FlexibleColumnLayoutSemanticHelper from "sap/f/FlexibleColumnLayoutSemanticHelper";
4
+ import fLibrary from "sap/f/library";
5
+ import AppComponent from "sap/fe/core/AppComponent";
6
+ import ViewState from "sap/fe/core/controllerextensions/ViewState";
7
+ import { defineUI5Class, usingExtension } from "sap/fe/core/helpers/ClassSupport";
8
+ import KeepAliveHelper from "sap/fe/core/helpers/KeepAliveHelper";
9
+ import RouterProxy from "sap/fe/core/RouterProxy";
10
+ import Link from "sap/m/Link";
11
+ import MessageBox, { Action, Icon } from "sap/m/MessageBox";
12
+ import MessagePage from "sap/m/MessagePage";
13
+ import Control from "sap/ui/core/Control";
14
+ import JSONModel from "sap/ui/model/json/JSONModel";
15
+ import BaseController from "./RootContainerBaseController";
16
+
17
+ const LayoutType = fLibrary.LayoutType;
18
+
19
+ const CONSTANTS = {
20
+ page: {
21
+ names: ["BeginColumn", "MidColumn", "EndColumn"],
22
+ currentGetter: {
23
+ prefix: "getCurrent",
24
+ suffix: "Page"
25
+ },
26
+ getter: {
27
+ prefix: "get",
28
+ suffix: "Pages"
29
+ }
30
+ }
31
+ };
32
+ const _getViewFromContainer = function (oContainer: any) {
33
+ if (oContainer.isA("sap.ui.core.ComponentContainer")) {
34
+ return oContainer.getComponentInstance().getRootControl();
35
+ } else {
36
+ return oContainer;
37
+ }
38
+ };
39
+
40
+ @defineUI5Class("sap.fe.templates.RootContainer.controller.Fcl")
41
+ class FclController extends BaseController {
42
+ @usingExtension(
43
+ ViewState.override({
44
+ applyInitialStateOnly: function () {
45
+ return false;
46
+ },
47
+ adaptBindingRefreshControls: function (this: ViewState, aControls: any) {
48
+ (this.getView().getController() as FclController)._getAllVisibleViews().forEach(function (oChildView: any) {
49
+ const pChildView = new Promise(function (resolve: (value: any) => void) {
50
+ resolve(oChildView);
51
+ });
52
+ aControls.push(pChildView);
53
+ });
54
+ },
55
+ adaptStateControls: function (this: ViewState, aStateControls: any) {
56
+ (this.getView().getController() as FclController)._getAllVisibleViews().forEach(function (oChildView: any) {
57
+ const pChildView = new Promise(function (resolve: (value: any) => void) {
58
+ resolve(oChildView);
59
+ });
60
+ aStateControls.push(pChildView);
61
+ });
62
+ },
63
+ onRestore: function (this: ViewState) {
64
+ const oView = this.getView(),
65
+ oNavContainer = oView.byId("appContent");
66
+ const oFCLController = this.getView().getController();
67
+ const oInternalModel = oNavContainer.getModel("internal") as JSONModel;
68
+ const oPages = oInternalModel.getProperty("/pages");
69
+
70
+ for (const sComponentId in oPages) {
71
+ oInternalModel.setProperty("/pages/" + sComponentId + "/restoreStatus", "pending");
72
+ }
73
+ (oFCLController as FclController).onContainerReady();
74
+ },
75
+ onSuspend: function (this: ViewState) {
76
+ const oFCLController = this.getView().getController() as FclController;
77
+ const oFCLControl = oFCLController.getFclControl();
78
+ const aBeginColumnPages: Control[] = oFCLControl.getBeginColumnPages() || [];
79
+ const aMidColumnPages: Control[] = oFCLControl.getMidColumnPages() || [];
80
+ const aEndColumnPages: Control[] = oFCLControl.getEndColumnPages() || [];
81
+ const aPages = ([] as Control[]).concat(aBeginColumnPages, aMidColumnPages, aEndColumnPages);
82
+
83
+ aPages.forEach(function (oPage: any) {
84
+ const oTargetView = _getViewFromContainer(oPage);
85
+
86
+ const oController = oTargetView && oTargetView.getController();
87
+ if (oController && oController.viewState && oController.viewState.onSuspend) {
88
+ return oController.viewState.onSuspend();
89
+ }
90
+ });
91
+ }
92
+ })
93
+ )
94
+ viewState!: ViewState;
95
+
96
+ private _oRouterProxy!: RouterProxy;
97
+ private sCurrentRouteName!: string;
98
+ private sCurrentArguments?: any;
99
+ private sPreviousLayout!: string;
100
+ private SQUERYKEYNAME!: string;
101
+ private _oFCLConfig: any;
102
+ private oAdditionalViewForNavRowsComputation: any;
103
+ private _oTargetsAggregation: any;
104
+ private _oTargetsFromRoutePattern: any;
105
+ private aMessagePages?: any[];
106
+ /**
107
+ * @private
108
+ * @name sap.fe.templates.RootContainer.controller.Fcl.getMetadata
109
+ * @function
110
+ */
111
+
112
+ onInit() {
113
+ super.onInit();
114
+
115
+ this._internalInit();
116
+ }
117
+
118
+ attachRouteMatchers() {
119
+ this.getRouter().attachBeforeRouteMatched(this._getViewForNavigatedRowsComputation, this);
120
+ super.attachRouteMatchers();
121
+ this._internalInit();
122
+
123
+ this.getRouter().attachBeforeRouteMatched(this.onBeforeRouteMatched, this);
124
+ this.getRouter().attachRouteMatched(this.onRouteMatched, this);
125
+ this.getFclControl().attachStateChange(this._saveLayout, this);
126
+ }
127
+
128
+ _internalInit() {
129
+ if (this._oRouterProxy) {
130
+ return; // Already initialized
131
+ }
132
+
133
+ this.sCurrentRouteName = "";
134
+ this.sCurrentArguments = {};
135
+ this.SQUERYKEYNAME = "?query";
136
+
137
+ const oAppComponent = this.getAppComponent();
138
+
139
+ this._oRouterProxy = oAppComponent.getRouterProxy();
140
+
141
+ // Get FCL configuration in the manifest
142
+ this._oFCLConfig = { maxColumnsCount: 3 };
143
+ const oRoutingConfig = (oAppComponent.getManifest() as any)["sap.ui5"].routing;
144
+ if (oRoutingConfig && oRoutingConfig.config) {
145
+ if (oRoutingConfig.config.flexibleColumnLayout) {
146
+ const oFCLManifestConfig = oRoutingConfig.config.flexibleColumnLayout;
147
+
148
+ // Default layout for 2 columns
149
+ if (oFCLManifestConfig.defaultTwoColumnLayoutType) {
150
+ this._oFCLConfig.defaultTwoColumnLayoutType = oFCLManifestConfig.defaultTwoColumnLayoutType;
151
+ }
152
+
153
+ // Default layout for 3 columns
154
+ if (oFCLManifestConfig.defaultThreeColumnLayoutType) {
155
+ this._oFCLConfig.defaultThreeColumnLayoutType = oFCLManifestConfig.defaultThreeColumnLayoutType;
156
+ }
157
+
158
+ // Limit FCL to 2 columns ?
159
+ if (oFCLManifestConfig.limitFCLToTwoColumns === true) {
160
+ this._oFCLConfig.maxColumnsCount = 2;
161
+ }
162
+ }
163
+ if (oRoutingConfig.config.controlAggregation) {
164
+ this._oFCLConfig.defaultControlAggregation = oRoutingConfig.config.controlAggregation;
165
+ }
166
+ }
167
+
168
+ this._initializeTargetAggregation(oAppComponent);
169
+ this._initializeRoutesInformation(oAppComponent);
170
+ }
171
+
172
+ getFclControl() {
173
+ return this.getView().getContent()[0] as FlexibleColumnLayout;
174
+ }
175
+
176
+ _saveLayout(oEvent: any) {
177
+ this.sPreviousLayout = oEvent.getParameters().layout;
178
+ }
179
+
180
+ /**
181
+ * Get the additionnal view (on top of the visible views), to be able to compute the latest table navigated rows of the most right visible view after a nav back or column fullscreen.
182
+ *
183
+ * @function
184
+ * @name sap.fe.templates.RootContainer.controller.Fcl.controller#_getRightMostViewBeforeRouteMatched
185
+ * @memberof sap.fe.templates.RootContainer.controller.Fcl.controller
186
+ *
187
+ */
188
+
189
+ _getViewForNavigatedRowsComputation() {
190
+ const aAllVisibleViewsBeforeRouteMatched = this._getAllVisibleViews(this.sPreviousLayout);
191
+ const oRightMostViewBeforeRouteMatched = aAllVisibleViewsBeforeRouteMatched[aAllVisibleViewsBeforeRouteMatched.length - 1];
192
+ let oRightMostView;
193
+ this.getRouter().attachEventOnce("routeMatched", (oEvent: any) => {
194
+ oRightMostView = _getViewFromContainer(oEvent.getParameter("views")[oEvent.getParameter("views").length - 1]);
195
+ if (oRightMostViewBeforeRouteMatched) {
196
+ // Navigation forward from L2 to view level L3 (FullScreenLayout):
197
+ if (oRightMostView.getViewData() && oRightMostView.getViewData().viewLevel === this._oFCLConfig.maxColumnsCount) {
198
+ this.oAdditionalViewForNavRowsComputation = oRightMostView;
199
+ }
200
+ // Navigations backward from L3 down to L2, L1, L0 (ThreeColumn layout):
201
+ if (
202
+ oRightMostView.getViewData() &&
203
+ oRightMostViewBeforeRouteMatched.getViewData() &&
204
+ oRightMostViewBeforeRouteMatched.getViewData().viewLevel < this._oFCLConfig.maxColumnsCount &&
205
+ oRightMostViewBeforeRouteMatched.getViewData() &&
206
+ oRightMostViewBeforeRouteMatched.getViewData().viewLevel > oRightMostView.getViewData().viewLevel &&
207
+ oRightMostView !== oRightMostViewBeforeRouteMatched
208
+ ) {
209
+ this.oAdditionalViewForNavRowsComputation = oRightMostViewBeforeRouteMatched;
210
+ }
211
+ }
212
+ });
213
+ }
214
+
215
+ getViewForNavigatedRowsComputation() {
216
+ return this.oAdditionalViewForNavRowsComputation;
217
+ }
218
+
219
+ onExit() {
220
+ this.getRouter().detachRouteMatched(this.onRouteMatched, this);
221
+ this.getRouter().detachBeforeRouteMatched(this.onBeforeRouteMatched, this);
222
+ this.getFclControl().detachStateChange(this.onStateChanged, this);
223
+ this.getFclControl().detachAfterEndColumnNavigate(this.onStateChanged, this);
224
+ this._oTargetsAggregation = null;
225
+ this._oTargetsFromRoutePattern = null;
226
+
227
+ BaseController.prototype.onExit.bind(this)();
228
+ }
229
+
230
+ /**
231
+ * Check if the FCL component is enabled.
232
+ *
233
+ * @function
234
+ * @name sap.fe.templates.RootContainer.controller.Fcl.controller#isFclEnabled
235
+ * @memberof sap.fe.templates.RootContainer.controller.Fcl.controller
236
+ * @returns {boolean} `true` since we are in FCL scenario
237
+ *
238
+ * @ui5-restricted
239
+ * @final
240
+ */
241
+ isFclEnabled() {
242
+ return true;
243
+ }
244
+
245
+ displayMessagePage(sErrorMessage: any, mParameters: any): Promise<boolean> {
246
+ const oFCLControl = this.getFclControl();
247
+
248
+ if (this._oFCLConfig && mParameters.FCLLevel >= this._oFCLConfig.maxColumnsCount) {
249
+ mParameters.FCLLevel = this._oFCLConfig.maxColumnsCount - 1;
250
+ }
251
+
252
+ if (!this.aMessagePages) {
253
+ this.aMessagePages = [null, null, null];
254
+ }
255
+ let oMessagePage = this.aMessagePages[mParameters.FCLLevel];
256
+ if (!oMessagePage) {
257
+ oMessagePage = new MessagePage({
258
+ showHeader: false,
259
+ icon: "sap-icon://message-error"
260
+ });
261
+ this.aMessagePages[mParameters.FCLLevel] = oMessagePage;
262
+
263
+ switch (mParameters.FCLLevel) {
264
+ case 0:
265
+ oFCLControl.addBeginColumnPage(oMessagePage);
266
+ break;
267
+
268
+ case 1:
269
+ oFCLControl.addMidColumnPage(oMessagePage);
270
+ break;
271
+
272
+ default:
273
+ oFCLControl.addEndColumnPage(oMessagePage);
274
+ }
275
+ }
276
+
277
+ oMessagePage.setText(sErrorMessage);
278
+
279
+ if (mParameters.technicalMessage) {
280
+ oMessagePage.setCustomDescription(
281
+ new Link({
282
+ text: mParameters.description || mParameters.technicalMessage,
283
+ press: function () {
284
+ MessageBox.show(mParameters.technicalMessage, {
285
+ icon: Icon.ERROR,
286
+ title: mParameters.title,
287
+ actions: [Action.OK],
288
+ defaultAction: Action.OK,
289
+ details: mParameters.technicalDetails || "",
290
+ contentWidth: "60%"
291
+ } as any);
292
+ }
293
+ })
294
+ );
295
+ } else {
296
+ oMessagePage.setDescription(mParameters.description || "");
297
+ }
298
+
299
+ (oFCLControl as any).to(oMessagePage.getId());
300
+ return Promise.resolve(true);
301
+ }
302
+
303
+ /**
304
+ * Initialize the object _oTargetsAggregation that defines for each route the relevant aggregation and pattern.
305
+ *
306
+ * @name sap.fe.templates.RootContainer.controller.Fcl.controller#_initializeTargetAggregation
307
+ * @memberof sap.fe.templates.RootContainer.controller.Fcl.controller
308
+ * @function
309
+ * @param {object} [oAppComponent] Reference to the AppComponent
310
+ */
311
+ _initializeTargetAggregation(oAppComponent: AppComponent) {
312
+ const oManifest = oAppComponent.getManifest() as any,
313
+ oTargets = oManifest["sap.ui5"].routing ? oManifest["sap.ui5"].routing.targets : null;
314
+
315
+ this._oTargetsAggregation = {};
316
+
317
+ if (oTargets) {
318
+ Object.keys(oTargets).forEach((sTargetName: string) => {
319
+ const oTarget = oTargets[sTargetName];
320
+ if (oTarget.controlAggregation) {
321
+ this._oTargetsAggregation[sTargetName] = {
322
+ aggregation: oTarget.controlAggregation,
323
+ pattern: oTarget.contextPattern
324
+ };
325
+ } else {
326
+ this._oTargetsAggregation[sTargetName] = {
327
+ aggregation: "page",
328
+ pattern: null
329
+ };
330
+ }
331
+ });
332
+ }
333
+ }
334
+
335
+ /**
336
+ * Initializes the mapping between a route (identifed as its pattern) and the corresponding targets
337
+ *
338
+ * @name sap.fe.templates.RootContainer.controller.Fcl.controller#_initializeRoutesInformation
339
+ * @memberof sap.fe.templates.RootContainer.controller.Fcl.controller
340
+ * @function
341
+ * @param oAppComponent ref to the AppComponent
342
+ */
343
+
344
+ _initializeRoutesInformation(oAppComponent: AppComponent) {
345
+ const oManifest = oAppComponent.getManifest() as any,
346
+ aRoutes = oManifest["sap.ui5"].routing ? oManifest["sap.ui5"].routing.routes : null;
347
+
348
+ this._oTargetsFromRoutePattern = {};
349
+
350
+ if (aRoutes) {
351
+ aRoutes.forEach((route: any) => {
352
+ this._oTargetsFromRoutePattern[route.pattern] = route.target;
353
+ });
354
+ }
355
+ }
356
+
357
+ getCurrentArgument() {
358
+ return this.sCurrentArguments;
359
+ }
360
+
361
+ getCurrentRouteName() {
362
+ return this.sCurrentRouteName;
363
+ }
364
+
365
+ /**
366
+ * Get FE FCL constant.
367
+ *
368
+ * @memberof sap.fe.templates.RootContainer.controller.Fcl.controller
369
+ * @returns {object}
370
+ */
371
+ getConstants() {
372
+ return CONSTANTS;
373
+ }
374
+
375
+ /**
376
+ * Getter for oTargetsAggregation array.
377
+ *
378
+ * @name sap.fe.templates.RootContainer.controller.Fcl.controller#getTargetAggregation
379
+ * @memberof sap.fe.templates.RootContainer.controller.Fcl.controller
380
+ * @function
381
+ * @returns {Array} The _oTargetsAggregation array
382
+ *
383
+ * @ui5-restricted
384
+ */
385
+ getTargetAggregation() {
386
+ return this._oTargetsAggregation;
387
+ }
388
+
389
+ /**
390
+ * Function triggered by the router RouteMatched event.
391
+ *
392
+ * @name sap.fe.templates.RootContainer.controller.Fcl.controller#onRouteMatched
393
+ * @memberof sap.fe.templates.RootContainer.controller.Fcl.controller
394
+ * @param {*} oEvent
395
+ */
396
+ onRouteMatched(oEvent: any) {
397
+ const sRouteName = oEvent.getParameter("name");
398
+
399
+ // Save the current/previous routes and arguments
400
+ this.sCurrentRouteName = sRouteName;
401
+ this.sCurrentArguments = oEvent.getParameter("arguments");
402
+ }
403
+
404
+ /**
405
+ * This function is triggering the table scroll to the navigated row after each layout change.
406
+ *
407
+ * @name sap.fe.templates.RootContainer.controller.Fcl.controller#scrollToLastSelectedItem
408
+ * @memberof sap.fe.templates.RootContainer.controller.Fcl.controller
409
+ */
410
+
411
+ _scrollTablesToLastNavigatedItems() {
412
+ const aViews = this._getAllVisibleViews();
413
+ //The scrolls are triggered only if the layout is with several columns or when switching the mostRight column in full screen
414
+ if (aViews.length > 1 || aViews[0].getViewData().viewLevel < this._oFCLConfig.maxColumnsCount) {
415
+ let sCurrentViewPath;
416
+ const oAdditionalView = this.getViewForNavigatedRowsComputation();
417
+ if (oAdditionalView && aViews.indexOf(oAdditionalView) === -1) {
418
+ aViews.push(oAdditionalView);
419
+ }
420
+ for (let index = aViews.length - 1; index > 0; index--) {
421
+ const oView = aViews[index],
422
+ oPreviousView = aViews[index - 1];
423
+ if (oView.getBindingContext()) {
424
+ sCurrentViewPath = oView.getBindingContext().getPath();
425
+ oPreviousView.getController()._scrollTablesToRow(sCurrentViewPath);
426
+ }
427
+ }
428
+ }
429
+ }
430
+
431
+ /**
432
+ * Function triggered by the FCL StateChanged event.
433
+ *
434
+ * @name sap.fe.templates.RootContainer.controller.Fcl.controller#onStateChanged
435
+ * @memberof sap.fe.templates.RootContainer.controller.Fcl.controller
436
+ * @param {*} oEvent
437
+ */
438
+ onStateChanged(oEvent: any) {
439
+ const bIsNavigationArrow = oEvent.getParameter("isNavigationArrow");
440
+ if (this.sCurrentArguments !== undefined) {
441
+ if (!this.sCurrentArguments[this.SQUERYKEYNAME]) {
442
+ this.sCurrentArguments[this.SQUERYKEYNAME] = {};
443
+ }
444
+ this.sCurrentArguments[this.SQUERYKEYNAME].layout = oEvent.getParameter("layout");
445
+ }
446
+ this._forceModelContextChangeOnBreadCrumbs(oEvent);
447
+
448
+ // Replace the URL with the new layout if a navigation arrow was used
449
+ if (bIsNavigationArrow) {
450
+ this._oRouterProxy.navTo(this.sCurrentRouteName, this.sCurrentArguments);
451
+ }
452
+ }
453
+
454
+ /**
455
+ * Function to fire ModelContextChange event on all breadcrumbs ( on each ObjectPages).
456
+ *
457
+ * @name sap.fe.templates.RootContainer.controller.Fcl.controller#_forceModelContextChangeOnBreadCrumbs
458
+ * @memberof sap.fe.templates.RootContainer.controller.Fcl.controller
459
+ * @param {*} oEvent
460
+ */
461
+ _forceModelContextChangeOnBreadCrumbs(oEvent: any) {
462
+ //force modelcontextchange on ObjectPages to refresh the breadcrumbs link hrefs
463
+ const oFcl = oEvent.getSource();
464
+ let oPages: any[] = [];
465
+ oPages = oPages.concat(oFcl.getBeginColumnPages()).concat(oFcl.getMidColumnPages()).concat(oFcl.getEndColumnPages());
466
+ oPages.forEach(function (oPage: any) {
467
+ const oView = _getViewFromContainer(oPage);
468
+ const oBreadCrumbs = oView.byId && oView.byId("breadcrumbs");
469
+ if (oBreadCrumbs) {
470
+ oBreadCrumbs.fireModelContextChange();
471
+ }
472
+ });
473
+ }
474
+
475
+ /**
476
+ * Function triggered to update the Share button Visibility.
477
+ *
478
+ * @memberof sap.fe.templates.RootContainer.controller.Fcl.controller
479
+ * @param {string} viewColumn Name of the current column ("beginColumn", "midColumn", "endColumn")
480
+ * @param {string} sLayout The current layout used by the FCL
481
+ * @returns {boolean}
482
+ */
483
+ _updateShareButtonVisibility(viewColumn: string, sLayout: string) {
484
+ let bShowShareIcon;
485
+ switch (sLayout) {
486
+ case "OneColumn":
487
+ bShowShareIcon = viewColumn === "beginColumn";
488
+ break;
489
+ case "MidColumnFullScreen":
490
+ case "ThreeColumnsBeginExpandedEndHidden":
491
+ case "ThreeColumnsMidExpandedEndHidden":
492
+ case "TwoColumnsBeginExpanded":
493
+ case "TwoColumnsMidExpanded":
494
+ bShowShareIcon = viewColumn === "midColumn";
495
+ break;
496
+ case "EndColumnFullScreen":
497
+ case "ThreeColumnsEndExpanded":
498
+ case "ThreeColumnsMidExpanded":
499
+ bShowShareIcon = viewColumn === "endColumn";
500
+ break;
501
+ default:
502
+ bShowShareIcon = false;
503
+ }
504
+ return bShowShareIcon;
505
+ }
506
+
507
+ updateUIStateForView(oView: any, FCLLevel: any) {
508
+ const oUIState = this.getHelper().getCurrentUIState() as any,
509
+ oFclColName = ["beginColumn", "midColumn", "endColumn"],
510
+ sLayout = this.getFclControl().getLayout();
511
+ let viewColumn;
512
+
513
+ if (!oView.getModel("fclhelper")) {
514
+ oView.setModel(this._createHelperModel(), "fclhelper");
515
+ }
516
+ if (FCLLevel >= this._oFCLConfig.maxColumnsCount) {
517
+ // The view is on a level > max number of columns. It's always fullscreen without close/exit buttons
518
+ viewColumn = oFclColName[this._oFCLConfig.maxColumnsCount - 1];
519
+ oUIState.actionButtonsInfo.midColumn.fullScreen = null;
520
+ oUIState.actionButtonsInfo.midColumn.exitFullScreen = null;
521
+ oUIState.actionButtonsInfo.midColumn.closeColumn = null;
522
+ oUIState.actionButtonsInfo.endColumn.exitFullScreen = null;
523
+ oUIState.actionButtonsInfo.endColumn.fullScreen = null;
524
+ oUIState.actionButtonsInfo.endColumn.closeColumn = null;
525
+ } else {
526
+ viewColumn = oFclColName[FCLLevel];
527
+ }
528
+
529
+ if (
530
+ FCLLevel >= this._oFCLConfig.maxColumnsCount ||
531
+ sLayout === "EndColumnFullScreen" ||
532
+ sLayout === "MidColumnFullScreen" ||
533
+ sLayout === "OneColumn"
534
+ ) {
535
+ oView.getModel("fclhelper").setProperty("/breadCrumbIsVisible", true);
536
+ } else {
537
+ oView.getModel("fclhelper").setProperty("/breadCrumbIsVisible", false);
538
+ }
539
+ // Unfortunately, the FCLHelper doesn't provide actionButton values for the first column
540
+ // so we have to add this info manually
541
+ oUIState.actionButtonsInfo.beginColumn = { fullScreen: null, exitFullScreen: null, closeColumn: null };
542
+
543
+ const oActionButtonInfos = Object.assign({}, oUIState.actionButtonsInfo[viewColumn]);
544
+ oActionButtonInfos.switchVisible = oActionButtonInfos.fullScreen !== null || oActionButtonInfos.exitFullScreen !== null;
545
+ oActionButtonInfos.switchIcon = oActionButtonInfos.fullScreen !== null ? "sap-icon://full-screen" : "sap-icon://exit-full-screen";
546
+ oActionButtonInfos.isFullScreen = oActionButtonInfos.fullScreen === null;
547
+
548
+ oView.getModel("fclhelper").setProperty("/actionButtonsInfo", oActionButtonInfos);
549
+
550
+ oView.getModel("fclhelper").setProperty("/showShareIcon", this._updateShareButtonVisibility(viewColumn, sLayout));
551
+ }
552
+
553
+ /**
554
+ * Function triggered by the router BeforeRouteMatched event.
555
+ *
556
+ * @name sap.fe.templates.RootContainer.controller.Fcl.controller#onBeforeRouteMatched
557
+ * @memberof sap.fe.templates.RootContainer.controller.Fcl.controller
558
+ * @param {*} oEvent
559
+ */
560
+ onBeforeRouteMatched(oEvent: any) {
561
+ if (oEvent) {
562
+ const oQueryParams = oEvent.getParameters().arguments[this.SQUERYKEYNAME];
563
+ let sLayout = oQueryParams ? oQueryParams.layout : null;
564
+
565
+ // If there is no layout parameter, query for the default level 0 layout (normally OneColumn)
566
+ if (!sLayout) {
567
+ const oNextUIState = this.getHelper().getNextUIState(0);
568
+ sLayout = oNextUIState.layout;
569
+ }
570
+
571
+ // Check if the layout if compatible with the number of targets
572
+ // This should always be the case for normal navigation, just needed in case
573
+ // the URL has been manually modified
574
+ const aTargets = oEvent.getParameter("config").target;
575
+ sLayout = this._correctLayoutForTargets(sLayout, aTargets);
576
+
577
+ // Update the layout of the FlexibleColumnLayout
578
+ if (sLayout) {
579
+ this.getFclControl().setLayout(sLayout);
580
+ }
581
+ }
582
+ }
583
+
584
+ /**
585
+ * Helper for the FCL Component.
586
+ *
587
+ * @name sap.fe.templates.RootContainer.controller.Fcl.controller#getHelper
588
+ * @memberof sap.fe.templates.RootContainer.controller.Fcl.controller
589
+ * @returns {object} Instance of a semantic helper
590
+ */
591
+ getHelper() {
592
+ return FlexibleColumnLayoutSemanticHelper.getInstanceFor(this.getFclControl(), this._oFCLConfig);
593
+ }
594
+
595
+ /**
596
+ * Calculates the FCL layout for a given FCL level and a target hash.
597
+ *
598
+ * @param iNextFCLLevel FCL level to be navigated to
599
+ * @param sHash The hash to be navigated to
600
+ * @param sProposedLayout The proposed layout
601
+ * @param keepCurrentLayout True if we want to keep the current layout if possible
602
+ * @returns {object}
603
+ */
604
+ calculateLayout(iNextFCLLevel: number, sHash: string, sProposedLayout: string | undefined, keepCurrentLayout: boolean | undefined) {
605
+ // First, ask the FCL helper to calculate the layout if nothing is proposed
606
+ if (!sProposedLayout) {
607
+ sProposedLayout = keepCurrentLayout ? this.getFclControl().getLayout() : this.getHelper().getNextUIState(iNextFCLLevel).layout;
608
+ }
609
+
610
+ // Then change this value if necessary, based on the number of targets
611
+ const oRoute = (this.getRouter() as any).getRouteByHash(sHash + "?layout=" + sProposedLayout);
612
+ const aTargets = this._oTargetsFromRoutePattern[oRoute.getPattern()];
613
+
614
+ return this._correctLayoutForTargets(sProposedLayout, aTargets);
615
+ }
616
+
617
+ /**
618
+ * Checks whether a given FCL layout is compatible with an array of targets.
619
+ *
620
+ * @param {*} sProposedLayout Proposed value for the FCL layout
621
+ * @param {*} aTargets Array of target names used for checking
622
+ * @returns {string} The corrected layout
623
+ */
624
+ _correctLayoutForTargets(sProposedLayout: any, aTargets: any) {
625
+ const allAllowedLayouts: any = {
626
+ "2": ["TwoColumnsMidExpanded", "TwoColumnsBeginExpanded", "MidColumnFullScreen"],
627
+ "3": [
628
+ "ThreeColumnsMidExpanded",
629
+ "ThreeColumnsEndExpanded",
630
+ "ThreeColumnsMidExpandedEndHidden",
631
+ "ThreeColumnsBeginExpandedEndHidden",
632
+ "MidColumnFullScreen",
633
+ "EndColumnFullScreen"
634
+ ]
635
+ };
636
+
637
+ if (aTargets && !Array.isArray(aTargets)) {
638
+ // To support single target as a string in the manifest
639
+ aTargets = [aTargets];
640
+ }
641
+
642
+ if (!aTargets) {
643
+ // Defensive, just in case...
644
+ return sProposedLayout;
645
+ } else if (aTargets.length > 1) {
646
+ // More than 1 target: just simply check from the allowed values
647
+ const aLayouts = allAllowedLayouts[aTargets.length];
648
+ if (aLayouts.indexOf(sProposedLayout) < 0) {
649
+ // The proposed layout isn't compatible with the number of columns
650
+ // --> Ask the helper for the default layout for the number of columns
651
+ sProposedLayout = aLayouts[0]; //this.getHelper().getNextUIState(aTargets.length - 1).layout;
652
+ }
653
+ } else {
654
+ // Only one target
655
+ const sTargetAggregation = this.getTargetAggregation()[aTargets[0]].aggregation || this._oFCLConfig.defaultControlAggregation;
656
+ switch (sTargetAggregation) {
657
+ case "beginColumnPages":
658
+ sProposedLayout = "OneColumn";
659
+ break;
660
+ case "midColumnPages":
661
+ sProposedLayout = "MidColumnFullScreen";
662
+ break;
663
+ case "endColumnPages":
664
+ sProposedLayout = "EndColumnFullScreen";
665
+ break;
666
+ }
667
+ }
668
+
669
+ return sProposedLayout;
670
+ }
671
+
672
+ /**
673
+ * get all visible views in the FCL component.
674
+ * sLayout optional parameter is very specific as part of the calculation of the latest navigated row
675
+ *
676
+ * @param {*} sLayout Layout that was applied just before the current navigation
677
+ * @returns {Array} return views
678
+ */
679
+
680
+ _getAllVisibleViews(sLayout?: any) {
681
+ const aViews = [];
682
+ sLayout = !!sLayout ? sLayout : this.getFclControl().getLayout();
683
+ switch (sLayout) {
684
+ case LayoutType.EndColumnFullScreen:
685
+ if (this.getFclControl().getCurrentEndColumnPage()) {
686
+ aViews.push(_getViewFromContainer(this.getFclControl().getCurrentEndColumnPage()));
687
+ }
688
+ break;
689
+
690
+ case LayoutType.MidColumnFullScreen:
691
+ if (this.getFclControl().getCurrentMidColumnPage()) {
692
+ aViews.push(_getViewFromContainer(this.getFclControl().getCurrentMidColumnPage()));
693
+ }
694
+ break;
695
+
696
+ case LayoutType.OneColumn:
697
+ if (this.getFclControl().getCurrentBeginColumnPage()) {
698
+ aViews.push(_getViewFromContainer(this.getFclControl().getCurrentBeginColumnPage()));
699
+ }
700
+ break;
701
+
702
+ case LayoutType.ThreeColumnsEndExpanded:
703
+ case LayoutType.ThreeColumnsMidExpanded:
704
+ if (this.getFclControl().getCurrentBeginColumnPage()) {
705
+ aViews.push(_getViewFromContainer(this.getFclControl().getCurrentBeginColumnPage()));
706
+ }
707
+ if (this.getFclControl().getCurrentMidColumnPage()) {
708
+ aViews.push(_getViewFromContainer(this.getFclControl().getCurrentMidColumnPage()));
709
+ }
710
+ if (this.getFclControl().getCurrentEndColumnPage()) {
711
+ aViews.push(_getViewFromContainer(this.getFclControl().getCurrentEndColumnPage()));
712
+ }
713
+ break;
714
+
715
+ case LayoutType.TwoColumnsBeginExpanded:
716
+ case LayoutType.TwoColumnsMidExpanded:
717
+ case LayoutType.ThreeColumnsMidExpandedEndHidden:
718
+ case LayoutType.ThreeColumnsBeginExpandedEndHidden:
719
+ if (this.getFclControl().getCurrentBeginColumnPage()) {
720
+ aViews.push(_getViewFromContainer(this.getFclControl().getCurrentBeginColumnPage()));
721
+ }
722
+ if (this.getFclControl().getCurrentMidColumnPage()) {
723
+ aViews.push(_getViewFromContainer(this.getFclControl().getCurrentMidColumnPage()));
724
+ }
725
+ break;
726
+
727
+ default:
728
+ Log.error("Unhandled switch case for " + this.getFclControl().getLayout());
729
+ }
730
+
731
+ return aViews;
732
+ }
733
+
734
+ onContainerReady() {
735
+ // Restore views if neccessary.
736
+ const aViews = this._getAllVisibleViews();
737
+ const aRestorePromises: any[] = [];
738
+ aViews.reduce(function (aPromises: any, oTargetView: any) {
739
+ aPromises.push(KeepAliveHelper.restoreView(oTargetView));
740
+ return aPromises;
741
+ }, aRestorePromises);
742
+ return Promise.all(aRestorePromises);
743
+ }
744
+
745
+ getRightmostContext() {
746
+ let oContext;
747
+ switch (this.getFclControl().getLayout()) {
748
+ case LayoutType.OneColumn:
749
+ if (this.getFclControl().getCurrentBeginColumnPage()) {
750
+ oContext = _getViewFromContainer(this.getFclControl().getCurrentBeginColumnPage()).getBindingContext();
751
+ }
752
+ break;
753
+
754
+ case LayoutType.TwoColumnsBeginExpanded:
755
+ case LayoutType.TwoColumnsMidExpanded:
756
+ if (this.getFclControl().getCurrentMidColumnPage()) {
757
+ oContext = _getViewFromContainer(this.getFclControl().getCurrentMidColumnPage()).getBindingContext();
758
+ }
759
+ break;
760
+
761
+ case LayoutType.ThreeColumnsEndExpanded:
762
+ case LayoutType.ThreeColumnsMidExpanded:
763
+ case LayoutType.ThreeColumnsMidExpandedEndHidden:
764
+ case LayoutType.ThreeColumnsBeginExpandedEndHidden:
765
+ case LayoutType.EndColumnFullScreen:
766
+ if (this.getFclControl().getCurrentEndColumnPage()) {
767
+ oContext = _getViewFromContainer(this.getFclControl().getCurrentEndColumnPage()).getBindingContext();
768
+ }
769
+ break;
770
+
771
+ case LayoutType.MidColumnFullScreen:
772
+ // In this case we need to determine if this mid column fullscreen comes from a 2 or a 3 column layout
773
+ const sLayoutWhenExitFullScreen = (this.getHelper().getCurrentUIState() as any).actionButtonsInfo.midColumn.exitFullScreen;
774
+ if (sLayoutWhenExitFullScreen.indexOf("ThreeColumn") >= 0) {
775
+ // We come from a 3 column layout
776
+ if (this.getFclControl().getCurrentEndColumnPage()) {
777
+ oContext = _getViewFromContainer(this.getFclControl().getCurrentEndColumnPage()).getBindingContext();
778
+ }
779
+ } else {
780
+ // We come from a 2 column layout
781
+ if (this.getFclControl().getCurrentMidColumnPage()) {
782
+ oContext = _getViewFromContainer(this.getFclControl().getCurrentMidColumnPage()).getBindingContext();
783
+ }
784
+ }
785
+ break;
786
+
787
+ default:
788
+ Log.error("Unhandled switch case for " + this.getFclControl().getLayout());
789
+ }
790
+
791
+ return oContext;
792
+ }
793
+ }
794
+
795
+ export default FclController;