@sapui5/sap.fe.templates 1.107.1 → 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 (50) 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 +11 -0
  8. package/src/sap/fe/templates/ListReport/ListReportController.controller.js +76 -21
  9. package/src/sap/fe/templates/ListReport/ListReportController.controller.ts +58 -13
  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 +3 -6
  13. package/src/sap/fe/templates/ListReport/overrides/IntentBasedNavigation.ts +1 -5
  14. package/src/sap/fe/templates/ListReport/overrides/Share.js +9 -3
  15. package/src/sap/fe/templates/ListReport/overrides/Share.ts +7 -1
  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/ObjectPage.view.xml +32 -21
  22. package/src/sap/fe/templates/ObjectPage/ObjectPageController.controller.js +247 -32
  23. package/src/sap/fe/templates/ObjectPage/ObjectPageController.controller.ts +171 -19
  24. package/src/sap/fe/templates/ObjectPage/ObjectPageTemplating.js +48 -6
  25. package/src/sap/fe/templates/ObjectPage/ObjectPageTemplating.ts +59 -4
  26. package/src/sap/fe/templates/ObjectPage/designtime/StashableHBox.designtime.js +1 -1
  27. package/src/sap/fe/templates/ObjectPage/designtime/StashableHBox.designtime.ts +1 -2
  28. package/src/sap/fe/templates/ObjectPage/designtime/StashableVBox.designtime.js +1 -1
  29. package/src/sap/fe/templates/ObjectPage/designtime/StashableVBox.designtime.ts +1 -2
  30. package/src/sap/fe/templates/ObjectPage/flexibility/ScrollableHeaderContainer.flexibility.js +33 -0
  31. package/src/sap/fe/templates/ObjectPage/flexibility/ScrollableHeaderContainer.flexibility.ts +23 -0
  32. package/src/sap/fe/templates/ObjectPage/manifest.json +8 -0
  33. package/src/sap/fe/templates/ObjectPage/overrides/Share.js +9 -2
  34. package/src/sap/fe/templates/ObjectPage/overrides/Share.ts +7 -0
  35. package/src/sap/fe/templates/ObjectPage/overrides/ViewState.js +7 -1
  36. package/src/sap/fe/templates/ObjectPage/overrides/ViewState.ts +5 -0
  37. package/src/sap/fe/templates/ObjectPage/view/fragments/Actions.fragment.xml +8 -2
  38. package/src/sap/fe/templates/ObjectPage/view/fragments/HeaderContent.fragment.xml +38 -23
  39. package/src/sap/fe/templates/ObjectPage/view/fragments/MacroChart.fragment.xml +1 -0
  40. package/src/sap/fe/templates/ObjectPage/view/fragments/Table.fragment.xml +1 -0
  41. package/src/sap/fe/templates/library.js +1 -1
  42. package/src/sap/fe/templates/messagebundle_lt.properties +1 -1
  43. package/src/sap/fe/templates/RootContainer/controller/Fcl.controller.js +0 -899
  44. package/src/sap/fe/templates/RootContainer/controller/Fcl.controller.ts +0 -830
  45. package/src/sap/fe/templates/RootContainer/controller/NavContainer.controller.js +0 -207
  46. package/src/sap/fe/templates/RootContainer/controller/NavContainer.controller.ts +0 -177
  47. package/src/sap/fe/templates/RootContainer/controller/RootContainerBaseController.js +0 -575
  48. package/src/sap/fe/templates/RootContainer/controller/RootContainerBaseController.ts +0 -492
  49. package/src/sap/fe/templates/RootContainer/view/Fcl.view.xml +0 -16
  50. package/src/sap/fe/templates/RootContainer/view/NavContainer.view.xml +0 -9
@@ -4,7 +4,7 @@ import merge from "sap/base/util/merge";
4
4
  import ActionRuntime from "sap/fe/core/ActionRuntime";
5
5
  import CommonUtils from "sap/fe/core/CommonUtils";
6
6
  import BusyLocker from "sap/fe/core/controllerextensions/BusyLocker";
7
- import { connect } from "sap/fe/core/controllerextensions/collaboration/ActivitySync";
7
+ import { connect, disconnect, isConnected } from "sap/fe/core/controllerextensions/collaboration/ActivitySync";
8
8
  import { openManageDialog, showUserDetails } from "sap/fe/core/controllerextensions/collaboration/Manage";
9
9
  import EditFlow from "sap/fe/core/controllerextensions/EditFlow";
10
10
  import draft from "sap/fe/core/controllerextensions/editFlow/draft";
@@ -19,10 +19,13 @@ import Paginator from "sap/fe/core/controllerextensions/Paginator";
19
19
  import Placeholder from "sap/fe/core/controllerextensions/Placeholder";
20
20
  import Share from "sap/fe/core/controllerextensions/Share";
21
21
  import ViewState from "sap/fe/core/controllerextensions/ViewState";
22
+ import * as MetaModelConverter from "sap/fe/core/converters/MetaModelConverter";
22
23
  import { defineUI5Class, extensible, finalExtension, publicExtension, usingExtension } from "sap/fe/core/helpers/ClassSupport";
23
24
  import type { InternalModelContext } from "sap/fe/core/helpers/ModelHelper";
24
25
  import ModelHelper from "sap/fe/core/helpers/ModelHelper";
25
26
  import PageController from "sap/fe/core/PageController";
27
+ import type RootContainerBaseController from "sap/fe/core/rootView/RootViewBaseController";
28
+ import RootViewBaseController from "sap/fe/core/rootView/RootViewBaseController";
26
29
  import ChartRuntime from "sap/fe/macros/chart/ChartRuntime";
27
30
  import CommonHelper from "sap/fe/macros/CommonHelper";
28
31
  import DelegateUtil from "sap/fe/macros/DelegateUtil";
@@ -30,7 +33,6 @@ import TableUtils from "sap/fe/macros/table/Utils";
30
33
  import SelectionVariant from "sap/fe/navigation/SelectionVariant";
31
34
  import type { default as ObjectPageExtensionAPI } from "sap/fe/templates/ObjectPage/ExtensionAPI";
32
35
  import { default as ExtensionAPI } from "sap/fe/templates/ObjectPage/ExtensionAPI";
33
- import type RootContainerBaseController from "sap/fe/templates/RootContainer/controller/RootContainerBaseController";
34
36
  import EditFlowOverrides from "sap/fe/templates/RootContainer/overrides/EditFlow";
35
37
  import TableScroller from "sap/fe/templates/TableScroller";
36
38
  import InstanceManager from "sap/m/InstanceManager";
@@ -40,6 +42,7 @@ import type Popover from "sap/m/Popover";
40
42
  import Core from "sap/ui/core/Core";
41
43
  import Message from "sap/ui/core/message/Message";
42
44
  import OverrideExecution from "sap/ui/core/mvc/OverrideExecution";
45
+ import type View from "sap/ui/core/mvc/View";
43
46
  import type Binding from "sap/ui/model/Binding";
44
47
  import type JSONModel from "sap/ui/model/json/JSONModel";
45
48
  import type Context from "sap/ui/model/odata/v4/Context";
@@ -52,6 +55,7 @@ import type ObjectPageDynamicHeaderTitle from "sap/uxap/ObjectPageDynamicHeaderT
52
55
  import type ObjectPageLayout from "sap/uxap/ObjectPageLayout";
53
56
  import type ObjectPageSection from "sap/uxap/ObjectPageSection";
54
57
  import type ObjectPageSubSection from "sap/uxap/ObjectPageSubSection";
58
+ import type { ODataContextBindingEx, V4Context } from "types/extension_types";
55
59
  import IntentBasedNavigationOverride from "./overrides/IntentBasedNavigation";
56
60
  import InternalRoutingOverride from "./overrides/InternalRouting";
57
61
  import MessageHandlerOverride from "./overrides/MessageHandler";
@@ -172,6 +176,9 @@ class ObjectPageController extends PageController {
172
176
  if (oContext && oContext.isKeepAlive()) {
173
177
  oContext.setKeepAlive(false);
174
178
  }
179
+ if (isConnected(this.getView())) {
180
+ disconnect(this.getView()); // Cleanup collaboration connection when leaving the app
181
+ }
175
182
  }
176
183
 
177
184
  /**
@@ -342,12 +349,13 @@ class ObjectPageController extends PageController {
342
349
  // Due to the left alignment of the Draft switch and the collaborative draft avatar controls
343
350
  // there is a ToolbarSpacer in the actions aggregation which we need to exclude here!
344
351
  // Due to the ACC report, we also need not to check for the InvisibleText elements
345
- return (
346
- !oAction.isA("sap.ui.core.InvisibleText") &&
347
- !oAction.isA("sap.m.ToolbarSpacer") &&
348
- oAction.getVisible() &&
349
- oAction.getEnabled()
350
- );
352
+ if (oAction.isA("sap.fe.macros.ShareAPI")) {
353
+ // since ShareAPI does not have a disable property
354
+ // hence there is no need to check if it is disbaled or not
355
+ return oAction.getVisible();
356
+ } else if (!oAction.isA("sap.ui.core.InvisibleText") && !oAction.isA("sap.m.ToolbarSpacer")) {
357
+ return oAction.getVisible() && oAction.getEnabled();
358
+ }
351
359
  });
352
360
  }
353
361
  return oFirstClickableElement;
@@ -583,6 +591,8 @@ class ObjectPageController extends PageController {
583
591
  .then(() => {
584
592
  if (this.getView().getModel("ui").getProperty("/isEditable")) {
585
593
  connect(this.getView());
594
+ } else if (isConnected(this.getView())) {
595
+ disconnect(this.getView()); // Cleanup collaboration connection in case we switch to another element (e.g. in FCL)
586
596
  }
587
597
  })
588
598
  .catch(function (oError: any) {
@@ -798,6 +808,74 @@ class ObjectPageController extends PageController {
798
808
  BusyLocker.unlock(oModel);
799
809
  });
800
810
  }
811
+ /**
812
+ * Gets the context of the DraftRoot path.
813
+ * If a view has been created with the draft Root Path, this method returns its bindingContext.
814
+ * Where no view is found a new created context is returned.
815
+ * The new created context request the key of the entity in order to get the Etag of this entity.
816
+ *
817
+ * @function
818
+ * @name getDraftRootPath
819
+ * @returns Returns a Promise
820
+ */
821
+ async getDraftRootContext(): Promise<V4Context | undefined> {
822
+ const view = this.getView();
823
+ const context = view.getBindingContext() as V4Context;
824
+ if (context) {
825
+ const draftRootContextPath = ModelHelper.getDraftRootPath(context);
826
+ let simpleDraftRootContext: V4Context;
827
+ if (draftRootContextPath) {
828
+ // Check if a view matches with the draft root path
829
+ const existingBindingContextOnPage = (this.getAppComponent().getRootViewController() as RootViewBaseController)
830
+ .getInstancedViews()
831
+ .find((pageView: View) => pageView.getBindingContext()?.getPath() === draftRootContextPath)
832
+ ?.getBindingContext() as V4Context;
833
+ if (existingBindingContextOnPage) {
834
+ return existingBindingContextOnPage;
835
+ }
836
+ const internalModel = view.getModel("internal") as JSONModel;
837
+ simpleDraftRootContext = internalModel.getProperty("/simpleDraftRootContext");
838
+ if (simpleDraftRootContext?.getPath() === draftRootContextPath) {
839
+ return simpleDraftRootContext;
840
+ }
841
+ const model = context.getModel();
842
+ const metaModel = model.getMetaModel();
843
+ const sEntityPath = metaModel.getMetaPath(draftRootContextPath);
844
+ const mDataModel = MetaModelConverter.getInvolvedDataModelObjects(metaModel.getContext(sEntityPath));
845
+ simpleDraftRootContext = model.bindContext(draftRootContextPath).getBoundContext();
846
+ await simpleDraftRootContext.requestProperty(mDataModel.targetEntityType.keys[0]?.name);
847
+ // Store this new created context to use it on the next iterations
848
+ internalModel.setProperty("/simpleDraftRootContext", simpleDraftRootContext);
849
+ return simpleDraftRootContext;
850
+ }
851
+ return undefined;
852
+ }
853
+ return undefined;
854
+ }
855
+
856
+ async _validateDocument(): Promise<void | any[] | ODataContextBindingEx> {
857
+ const control = Core.byId(Core.getCurrentFocusedControlId());
858
+ const context = control?.getBindingContext() as V4Context;
859
+ if (context && !context.isTransient()) {
860
+ // Wait for the pending changes before starting this validation
861
+ await this._editFlow.syncTask();
862
+ const appComponent = this.getAppComponent();
863
+ const sideEffectsService = appComponent.getSideEffectsService();
864
+ const entityType = sideEffectsService.getEntityTypeFromContext(context);
865
+ const globalSideEffects = entityType ? sideEffectsService.getGlobalODataEntitySideEffects(entityType) : [];
866
+ // If there is at least one global SideEffects for the related entity, execute it/them
867
+ if (globalSideEffects.length) {
868
+ return Promise.all(globalSideEffects.map((sideEffects) => this._sideEffects.requestSideEffects(sideEffects, context)));
869
+ } else {
870
+ const draftRootContext = await this.getDraftRootContext();
871
+ //Execute the draftValidation if there is no globalSideEffects
872
+ if (draftRootContext) {
873
+ return draft.executeDraftValidation(draftRootContext, appComponent);
874
+ }
875
+ }
876
+ }
877
+ return undefined;
878
+ }
801
879
 
802
880
  async _saveDocument(oContext: any) {
803
881
  const oModel = this.getView().getModel("ui"),
@@ -881,10 +959,20 @@ class ObjectPageController extends PageController {
881
959
  }
882
960
  }
883
961
 
884
- _findTableInSubSection(aParentElement: any, aSubsection: any, aTables: any) {
962
+ _findControlInSubSection(aParentElement: any, aSubsection: any, aControls: any, bIsChart?: boolean) {
885
963
  const aSubSectionTables = [];
886
964
  for (let element = 0; element < aParentElement.length; element++) {
887
965
  let oElement = aParentElement[element].getContent instanceof Function && aParentElement[element].getContent();
966
+ if (bIsChart) {
967
+ if (oElement && oElement.mAggregations && oElement.getAggregation("items")) {
968
+ const aItems = oElement.getAggregation("items");
969
+ aItems.forEach(function (oItem: any) {
970
+ if (oItem.isA("sap.fe.macros.chart.ChartAPI")) {
971
+ oElement = oItem;
972
+ }
973
+ });
974
+ }
975
+ }
888
976
  if (oElement && oElement.isA && oElement.isA("sap.ui.layout.DynamicSideContent")) {
889
977
  oElement = oElement.getMainContent instanceof Function && oElement.getMainContent();
890
978
  if (oElement && oElement.length > 0) {
@@ -898,12 +986,22 @@ class ObjectPageController extends PageController {
898
986
  }
899
987
  }
900
988
  if (oElement && oElement.isA && oElement.isA("sap.ui.mdc.Table")) {
901
- aTables.push(oElement);
989
+ aControls.push(oElement);
902
990
  aSubSectionTables.push({
903
991
  "table": oElement,
904
992
  "gridTable": oElement.getType().isA("sap.ui.mdc.table.GridTableType")
905
993
  });
906
994
  }
995
+
996
+ if (oElement && oElement.isA && oElement.isA("sap.fe.macros.chart.ChartAPI")) {
997
+ oElement = oElement.getContent instanceof Function && oElement.getContent();
998
+ if (oElement && oElement.length > 0) {
999
+ oElement = oElement[0];
1000
+ }
1001
+ }
1002
+ if (oElement && oElement.isA && oElement.isA("sap.ui.mdc.Chart")) {
1003
+ aControls.push(oElement);
1004
+ }
907
1005
  }
908
1006
  if (
909
1007
  aSubSectionTables.length === 1 &&
@@ -913,13 +1011,6 @@ class ObjectPageController extends PageController {
913
1011
  ) {
914
1012
  //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
915
1013
  aSubsection.addStyleClass("sapUxAPObjectPageSubSectionFitContainer");
916
- } else if (aSubSectionTables && !aSubsection.hasStyleClass("sapUxAPObjectPageSubSectionFitContainer")) {
917
- aSubSectionTables.forEach(function (oTable: { table: any; gridTable: any }) {
918
- if (oTable.gridTable) {
919
- //Resetting the row count to default value in case we have a combination of forms and tables or multiple tables in a subsection
920
- oTable.table.getType().setRowCount(null);
921
- }
922
- });
923
1014
  }
924
1015
  }
925
1016
 
@@ -944,12 +1035,22 @@ class ObjectPageController extends PageController {
944
1035
  const aSubSections = this._getAllSubSections();
945
1036
  const aTables: any[] = [];
946
1037
  for (let subSection = 0; subSection < aSubSections.length; subSection++) {
947
- this._findTableInSubSection(aSubSections[subSection].getBlocks(), aSubSections[subSection], aTables);
948
- this._findTableInSubSection(aSubSections[subSection].getMoreBlocks(), aSubSections[subSection], aTables);
1038
+ this._findControlInSubSection(aSubSections[subSection].getBlocks(), aSubSections[subSection], aTables);
1039
+ this._findControlInSubSection(aSubSections[subSection].getMoreBlocks(), aSubSections[subSection], aTables);
949
1040
  }
950
1041
  return aTables;
951
1042
  }
952
1043
 
1044
+ _findCharts() {
1045
+ const aSubSections = this._getAllSubSections();
1046
+ const aCharts: any[] = [];
1047
+ for (let subSection = 0; subSection < aSubSections.length; subSection++) {
1048
+ this._findControlInSubSection(aSubSections[subSection].getBlocks(), aSubSections[subSection], aCharts, true);
1049
+ this._findControlInSubSection(aSubSections[subSection].getMoreBlocks(), aSubSections[subSection], aCharts, true);
1050
+ }
1051
+ return aCharts;
1052
+ }
1053
+
953
1054
  _closeSideContent() {
954
1055
  this._getAllBlocks().forEach(function (oBlock: any) {
955
1056
  const oContent = oBlock.getContent instanceof Function && oBlock.getContent();
@@ -1230,6 +1331,54 @@ class ObjectPageController extends PageController {
1230
1331
  }
1231
1332
 
1232
1333
  handlers = {
1334
+ /**
1335
+ * Invokes the page primary action on press of Ctrl+Enter.
1336
+ *
1337
+ * @param oController The page controller
1338
+ * @param oView
1339
+ * @param oContext Context for which the action is called
1340
+ * @param sActionName The name of the action to be called
1341
+ * @param [mParameters] Contains the following attributes:
1342
+ * @param [mParameters.contexts] Mandatory for a bound action, either one context or an array with contexts for which the action is called
1343
+ * @param [mParameters.model] Mandatory for an unbound action; an instance of an OData V4 model
1344
+ * @param [mConditions] Contains the following attributes:
1345
+ * @param [mConditions.positiveActionVisible] The visibility of sematic positive action
1346
+ * @param [mConditions.positiveActionEnabled] The enablement of semantic positive action
1347
+ * @param [mConditions.editActionVisible] The Edit button visibility
1348
+ * @param [mConditions.editActionEnabled] The enablement of Edit button
1349
+ * @ui5-restricted
1350
+ * @final
1351
+ */
1352
+ onPrimaryAction(
1353
+ oController: ObjectPageController,
1354
+ oView: View,
1355
+ oContext: Context,
1356
+ sActionName: string,
1357
+ mParameters: unknown,
1358
+ mConditions: {
1359
+ positiveActionVisible: boolean;
1360
+ positiveActionEnabled: boolean;
1361
+ editActionVisible: boolean;
1362
+ editActionEnabled: boolean;
1363
+ }
1364
+ ) {
1365
+ const iViewLevel = (oController.getView().getViewData() as any).viewLevel,
1366
+ oObjectPage = oController._getObjectPageLayoutControl();
1367
+ if (mConditions.positiveActionVisible) {
1368
+ if (mConditions.positiveActionEnabled) {
1369
+ oController.handlers.onCallAction(oView, sActionName, mParameters);
1370
+ }
1371
+ } else if (mConditions.editActionVisible && iViewLevel === 1) {
1372
+ if (mConditions.editActionEnabled) {
1373
+ oController._editDocument(oContext);
1374
+ }
1375
+ } else if (iViewLevel === 1 && oObjectPage.getModel("ui").getProperty("/isEditable")) {
1376
+ oController._saveDocument(oContext);
1377
+ } else if (oObjectPage.getModel("ui").getProperty("/isEditable")) {
1378
+ oController._applyDocument(oContext);
1379
+ }
1380
+ },
1381
+
1233
1382
  onTableContextChange(this: ObjectPageController, oEvent: any) {
1234
1383
  const oSource = oEvent.getSource();
1235
1384
  let oTable: any;
@@ -1428,6 +1577,9 @@ class ObjectPageController extends PageController {
1428
1577
  },
1429
1578
  onChartSelectionChanged: function (oEvent: any) {
1430
1579
  ChartRuntime.fnUpdateChart(oEvent);
1580
+ },
1581
+ onStateChange(this: ObjectPageController) {
1582
+ this.getExtensionAPI().updateAppState();
1431
1583
  }
1432
1584
  };
1433
1585
  }