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