@sapui5/sap.fe.templates 1.143.0 → 1.145.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 (113) hide show
  1. package/package.json +1 -1
  2. package/src/sap/fe/templates/.library +1 -1
  3. package/src/sap/fe/templates/AnalyticalListPage/manifest.json +1 -1
  4. package/src/sap/fe/templates/ListReport/Component.js +2 -2
  5. package/src/sap/fe/templates/ListReport/Component.ts +2 -2
  6. package/src/sap/fe/templates/ListReport/ExtensionAPI.js +1 -1
  7. package/src/sap/fe/templates/ListReport/ExtensionAPI.ts +1 -1
  8. package/src/sap/fe/templates/ListReport/LRMessageStrip.js +2 -2
  9. package/src/sap/fe/templates/ListReport/LRMessageStrip.ts +2 -2
  10. package/src/sap/fe/templates/ListReport/ListReport.view.xml +1 -1
  11. package/src/sap/fe/templates/ListReport/ListReportController.controller.js +19 -34
  12. package/src/sap/fe/templates/ListReport/ListReportController.controller.ts +19 -33
  13. package/src/sap/fe/templates/ListReport/controls/MultipleModeControl.js +22 -19
  14. package/src/sap/fe/templates/ListReport/controls/MultipleModeControl.ts +23 -20
  15. package/src/sap/fe/templates/ListReport/manifest.json +1 -1
  16. package/src/sap/fe/templates/ListReport/overrides/MessageHandler.js +5 -2
  17. package/src/sap/fe/templates/ListReport/overrides/MessageHandler.ts +4 -2
  18. package/src/sap/fe/templates/ListReport/overrides/Share.js +1 -1
  19. package/src/sap/fe/templates/ListReport/overrides/Share.ts +1 -1
  20. package/src/sap/fe/templates/ListReport/overrides/ViewState.js +2 -3
  21. package/src/sap/fe/templates/ListReport/overrides/ViewState.ts +1 -2
  22. package/src/sap/fe/templates/ListReport/view/fragments/CollectionVisualization.fragment.xml +32 -0
  23. package/src/sap/fe/templates/ListReport/view/fragments/MacroChart.fragment.xml +1 -0
  24. package/src/sap/fe/templates/ListReport/view/fragments/Table.fragment.xml +8 -6
  25. package/src/sap/fe/templates/ObjectPage/Component.js +33 -23
  26. package/src/sap/fe/templates/ObjectPage/Component.ts +34 -25
  27. package/src/sap/fe/templates/ObjectPage/ExtensionAPI.js +74 -3
  28. package/src/sap/fe/templates/ObjectPage/ExtensionAPI.ts +84 -4
  29. package/src/sap/fe/templates/ObjectPage/ObjectPage.view.xml +4 -1
  30. package/src/sap/fe/templates/ObjectPage/ObjectPageController.controller.js +149 -70
  31. package/src/sap/fe/templates/ObjectPage/ObjectPageController.controller.ts +173 -93
  32. package/src/sap/fe/templates/ObjectPage/ObjectPageTemplating.js +2 -71
  33. package/src/sap/fe/templates/ObjectPage/ObjectPageTemplating.ts +0 -74
  34. package/src/sap/fe/templates/ObjectPage/card/actions/HeaderActions.js +6 -7
  35. package/src/sap/fe/templates/ObjectPage/card/actions/HeaderActions.ts +5 -6
  36. package/src/sap/fe/templates/ObjectPage/components/DraftToggle.js +107 -34
  37. package/src/sap/fe/templates/ObjectPage/components/DraftToggle.tsx +117 -42
  38. package/src/sap/fe/templates/ObjectPage/controls/StashableHBox.js +36 -30
  39. package/src/sap/fe/templates/ObjectPage/controls/StashableHBox.ts +31 -26
  40. package/src/sap/fe/templates/ObjectPage/controls/SubSectionBlock.js +10 -1
  41. package/src/sap/fe/templates/ObjectPage/controls/SubSectionBlock.ts +15 -0
  42. package/src/sap/fe/templates/ObjectPage/designtime/ObjectPage.designtime.helper.js +22 -3
  43. package/src/sap/fe/templates/ObjectPage/designtime/ObjectPage.designtime.helper.ts +30 -1
  44. package/src/sap/fe/templates/ObjectPage/designtime/ObjectPage.designtime.js +5 -2
  45. package/src/sap/fe/templates/ObjectPage/designtime/ObjectPage.designtime.ts +7 -0
  46. package/src/sap/fe/templates/ObjectPage/manifest.json +6 -1
  47. package/src/sap/fe/templates/ObjectPage/overrides/CollaborationManager.js +2 -1
  48. package/src/sap/fe/templates/ObjectPage/overrides/CollaborationManager.ts +1 -0
  49. package/src/sap/fe/templates/ObjectPage/view/fragments/ExpandedHeading.fragment.xml +45 -7
  50. package/src/sap/fe/templates/ObjectPage/view/fragments/HeaderContent.fragment.xml +9 -14
  51. package/src/sap/fe/templates/ObjectPage/view/fragments/HeaderFacet.fragment.xml +1 -0
  52. package/src/sap/fe/templates/ObjectPage/view/fragments/HeaderFacetCustomContainer.fragment.xml +1 -0
  53. package/src/sap/fe/templates/ObjectPage/view/fragments/Heading.fragment.xml +36 -6
  54. package/src/sap/fe/templates/ObjectPage/view/fragments/ObjectPageHeaderAddress.fragment.xml +1 -1
  55. package/src/sap/fe/templates/ObjectPage/view/fragments/ObjectPageHeaderContact.fragment.xml +1 -1
  56. package/src/sap/fe/templates/ObjectPage/view/fragments/ObjectPageHeaderForm.fragment.xml +0 -1
  57. package/src/sap/fe/templates/ObjectPage/view/fragments/Section.fragment.xml +1 -0
  58. package/src/sap/fe/templates/ObjectPage/view/fragments/SectionContent.fragment.xml +86 -43
  59. package/src/sap/fe/templates/ObjectPage/view/fragments/SectionCustomSection.fragment.xml +6 -1
  60. package/src/sap/fe/templates/ObjectPage/view/fragments/SectionFormContent.fragment.xml +4 -3
  61. package/src/sap/fe/templates/ObjectPage/view/fragments/SectionMoreFormContent.fragment.xml +4 -3
  62. package/src/sap/fe/templates/ObjectPage/view/fragments/Table.fragment.xml +9 -7
  63. package/src/sap/fe/templates/library.js +1 -1
  64. package/src/sap/fe/templates/messagebundle.properties +21 -0
  65. package/src/sap/fe/templates/messagebundle_ar.properties +15 -1
  66. package/src/sap/fe/templates/messagebundle_bg.properties +14 -0
  67. package/src/sap/fe/templates/messagebundle_ca.properties +14 -0
  68. package/src/sap/fe/templates/messagebundle_cnr.properties +15 -1
  69. package/src/sap/fe/templates/messagebundle_cs.properties +14 -0
  70. package/src/sap/fe/templates/messagebundle_cy.properties +14 -0
  71. package/src/sap/fe/templates/messagebundle_da.properties +14 -0
  72. package/src/sap/fe/templates/messagebundle_de.properties +14 -0
  73. package/src/sap/fe/templates/messagebundle_el.properties +14 -0
  74. package/src/sap/fe/templates/messagebundle_en.properties +14 -0
  75. package/src/sap/fe/templates/messagebundle_en_GB.properties +14 -0
  76. package/src/sap/fe/templates/messagebundle_en_US_saprigi.properties +14 -0
  77. package/src/sap/fe/templates/messagebundle_es.properties +14 -0
  78. package/src/sap/fe/templates/messagebundle_es_MX.properties +14 -0
  79. package/src/sap/fe/templates/messagebundle_et.properties +14 -0
  80. package/src/sap/fe/templates/messagebundle_fi.properties +14 -0
  81. package/src/sap/fe/templates/messagebundle_fr.properties +14 -0
  82. package/src/sap/fe/templates/messagebundle_fr_CA.properties +17 -3
  83. package/src/sap/fe/templates/messagebundle_hi.properties +14 -0
  84. package/src/sap/fe/templates/messagebundle_hr.properties +14 -0
  85. package/src/sap/fe/templates/messagebundle_hu.properties +14 -0
  86. package/src/sap/fe/templates/messagebundle_id.properties +14 -0
  87. package/src/sap/fe/templates/messagebundle_it.properties +15 -1
  88. package/src/sap/fe/templates/messagebundle_iw.properties +15 -1
  89. package/src/sap/fe/templates/messagebundle_ja.properties +15 -1
  90. package/src/sap/fe/templates/messagebundle_kk.properties +14 -0
  91. package/src/sap/fe/templates/messagebundle_ko.properties +15 -1
  92. package/src/sap/fe/templates/messagebundle_lt.properties +16 -2
  93. package/src/sap/fe/templates/messagebundle_lv.properties +14 -0
  94. package/src/sap/fe/templates/messagebundle_mk.properties +14 -0
  95. package/src/sap/fe/templates/messagebundle_ms.properties +14 -0
  96. package/src/sap/fe/templates/messagebundle_nl.properties +14 -0
  97. package/src/sap/fe/templates/messagebundle_no.properties +14 -0
  98. package/src/sap/fe/templates/messagebundle_pl.properties +14 -0
  99. package/src/sap/fe/templates/messagebundle_pt.properties +14 -0
  100. package/src/sap/fe/templates/messagebundle_pt_PT.properties +14 -0
  101. package/src/sap/fe/templates/messagebundle_ro.properties +14 -0
  102. package/src/sap/fe/templates/messagebundle_ru.properties +14 -0
  103. package/src/sap/fe/templates/messagebundle_sh.properties +15 -1
  104. package/src/sap/fe/templates/messagebundle_sk.properties +14 -0
  105. package/src/sap/fe/templates/messagebundle_sl.properties +17 -3
  106. package/src/sap/fe/templates/messagebundle_sr.properties +15 -1
  107. package/src/sap/fe/templates/messagebundle_sv.properties +14 -0
  108. package/src/sap/fe/templates/messagebundle_th.properties +14 -0
  109. package/src/sap/fe/templates/messagebundle_tr.properties +14 -0
  110. package/src/sap/fe/templates/messagebundle_uk.properties +14 -0
  111. package/src/sap/fe/templates/messagebundle_vi.properties +16 -2
  112. package/src/sap/fe/templates/messagebundle_zh_CN.properties +14 -0
  113. package/src/sap/fe/templates/messagebundle_zh_TW.properties +14 -0
@@ -27,19 +27,20 @@ import { RecommendationDialogDecision } from "sap/fe/core/controls/Recommendatio
27
27
  import type { HiddenDraft, MicroChartManifestConfiguration } from "sap/fe/core/converters/ManifestSettings";
28
28
  import type { InternalModelContext } from "sap/fe/core/helpers/ModelHelper";
29
29
  import ModelHelper from "sap/fe/core/helpers/ModelHelper";
30
- import { getResourceModel } from "sap/fe/core/helpers/ResourceModelHelper";
31
30
  import FELibrary from "sap/fe/core/library";
32
31
  import { type WrappedCard } from "sap/fe/core/services/CollaborationManagerServiceFactory";
33
32
  import type ChartBlock from "sap/fe/macros/Chart";
34
33
  import CommonHelper from "sap/fe/macros/CommonHelper";
35
34
  import type MacroAPI from "sap/fe/macros/MacroAPI";
36
35
  import type MultiValueFieldBlock from "sap/fe/macros/MultiValueField";
36
+ import type TableAPI from "sap/fe/macros/Table";
37
37
  import type EasyFillButton from "sap/fe/macros/ai/EasyFillButton";
38
38
  import type SummarizationButton from "sap/fe/macros/ai/SummarizationButton";
39
+ import type SubSection from "sap/fe/macros/controls/section/SubSection";
39
40
  import type FormAPI from "sap/fe/macros/form/FormAPI";
40
41
  import type MessageButton from "sap/fe/macros/messages/MessageButton";
41
42
  import type ShareAPI from "sap/fe/macros/share/ShareAPI";
42
- import type TableAPI from "sap/fe/macros/table/TableAPI";
43
+ import type TableCreationOptions from "sap/fe/macros/table/TableCreationOptions";
43
44
  import TableHelper from "sap/fe/macros/table/TableHelper";
44
45
  import TableUtils from "sap/fe/macros/table/Utils";
45
46
  import SelectionVariant from "sap/fe/navigation/SelectionVariant";
@@ -51,7 +52,6 @@ import TableScroller from "sap/fe/templates/TableScroller";
51
52
  import type Button from "sap/m/Button";
52
53
  import type InputBase from "sap/m/InputBase";
53
54
  import InstanceManager from "sap/m/InstanceManager";
54
- import MessageBox from "sap/m/MessageBox";
55
55
  import type NavContainer from "sap/m/NavContainer";
56
56
  import type Popover from "sap/m/Popover";
57
57
  import type ToolbarSpacer from "sap/m/ToolbarSpacer";
@@ -180,7 +180,9 @@ class ObjectPageController extends PageController {
180
180
 
181
181
  private messageBinding?: Binding;
182
182
 
183
- private isFirstBinding = true;
183
+ private waitForVisibilityBindings!: Promise<unknown>[];
184
+
185
+ private subSections?: { fe: SubSection[]; others: ObjectPageSubSection[] };
184
186
 
185
187
  @publicExtension()
186
188
  @finalExtension()
@@ -219,10 +221,15 @@ class ObjectPageController extends PageController {
219
221
  );
220
222
  oInternalModelContext?.setProperty("batchGroups", this._getBatchGroupsForView());
221
223
  oInternalModelContext?.setProperty("errorNavigationSectionFlag", false);
222
- if (oObjectPage.getEnableLazyLoading()) {
223
- //Attaching the event to make the subsection context binding active when it is visible.
224
+
225
+ if (this.getDisableObjectPageRequestOptimization()) {
224
226
  oObjectPage.attachEvent("subSectionEnteredViewPort", this._handleSubSectionEnteredViewPort.bind(this));
227
+ } else {
228
+ this._getAllSubSections().forEach((subSection) => {
229
+ subSection.attachEvent("subSectionEnteredViewPort", this._handleSubSectionEnteredViewPort.bind(this));
230
+ });
225
231
  }
232
+
226
233
  this.messageButton = this.getView().byId("fe::FooterBar::MessageButton") as MessageButton;
227
234
  this.messageBinding = Messaging.getMessageModel().bindList("/");
228
235
  this.messageBinding?.attachChange(this._fnShowOPMessage, this);
@@ -301,9 +308,7 @@ class ObjectPageController extends PageController {
301
308
  return;
302
309
  }
303
310
  const tableType = table.isA<Table>("sap.ui.mdc.Table") && (table.getType() as TableTypeBase);
304
- const tableAPI = table.getParent()?.isA<TableAPI>("sap.fe.macros.table.TableAPI")
305
- ? (table.getParent() as TableAPI)
306
- : undefined;
311
+ const tableAPI = table.getParent()?.isA<TableAPI>("sap.fe.macros.Table") ? (table.getParent() as TableAPI) : undefined;
307
312
  if (
308
313
  tableType &&
309
314
  (tableType?.isA("sap.ui.mdc.table.GridTableType") || tableType?.isA("sap.ui.mdc.table.TreeTableType")) &&
@@ -337,7 +342,7 @@ class ObjectPageController extends PageController {
337
342
  // control from the custom data of the place holder panel
338
343
  if (control.isA("sap.m.Panel") && control.data("FullScreenTablePlaceHolder")) {
339
344
  return control.data("tableAPIreference");
340
- } else if (control.isA("sap.fe.macros.table.TableAPI")) {
345
+ } else if (control.isA("sap.fe.macros.Table")) {
341
346
  return control as TableAPI;
342
347
  }
343
348
  };
@@ -443,31 +448,10 @@ class ObjectPageController extends PageController {
443
448
  //Set the Binding for Paginators using ListBinding ID
444
449
  this._initializePagination(oContext, oInternalModel, mParameters?.listBinding);
445
450
 
446
- const firstSubSectionVisibilityBinding = this._getfirstSubSectionVisibilityBinding();
447
-
448
- if (
449
- this.useLazyLoaderOptimizations() &&
450
- oObjectPage.getEnableLazyLoading() &&
451
- firstSubSectionVisibilityBinding &&
452
- this.isFirstBinding
453
- ) {
454
- // if lazy loading is enabled and at least one subsection has a visibility binding
455
- oObjectPage.setVisible(false); // The objectPage Visibility is set to false to prevent the lazy loader to compute the sections
456
- firstSubSectionVisibilityBinding.attachEventOnce("change", async () => {
457
- const MDCTablePromises = this._getAllBlocks().map(async (block) =>
458
- block.getVisible() && block.getContent?.()?.isA<TableAPI>("sap.fe.macros.table.TableAPI")
459
- ? (block.getContent() as TableAPI).getContent().initialized()
460
- : null
461
- );
462
- await Promise.all(MDCTablePromises);
463
- oObjectPage.setVisible(true); // Visibility is restored once the visibility bindings of the sections are resolved, allowing lazy loading to properly process them
464
- this.isFirstBinding = false;
465
- });
466
- }
451
+ this._disableBlocksBindings(oObjectPage);
467
452
 
468
- if (oObjectPage.getEnableLazyLoading()) {
469
- this._disableBlocksBindings(oObjectPage);
470
- }
453
+ this.subSections = this.disconnectSubSectionVisibilityObservers(oObjectPage);
454
+ this.waitForVisibilityBindings = this.waitForAllSubSectionVisibilityBindingsResolved();
471
455
 
472
456
  if (this.placeholder.isPlaceholderEnabled() && mParameters.showPlaceholder) {
473
457
  const oView = this.getView();
@@ -479,11 +463,39 @@ class ObjectPageController extends PageController {
479
463
  }
480
464
  }
481
465
 
482
- private useLazyLoaderOptimizations(): boolean {
483
- if (new URLSearchParams(window.location.search).get("sap-ui-xx-lazyloader-optimizations") === "true") {
484
- return true;
466
+ /**
467
+ * Disconnect the visibility observers of all FE subsections.
468
+ * @param objectPageLayout
469
+ * @returns The subsections information or undefined if optimization is disabled
470
+ */
471
+ disconnectSubSectionVisibilityObservers(
472
+ objectPageLayout: ObjectPageLayout
473
+ ): { fe: SubSection[]; others: ObjectPageSubSection[] } | undefined {
474
+ if (!this.getDisableObjectPageRequestOptimization()) {
475
+ objectPageLayout.setVisible(false);
476
+ const subSectionsInfo: {
477
+ fe: SubSection[];
478
+ others: ObjectPageSubSection[];
479
+ } = { fe: [], others: [] };
480
+ this._getAllSubSections().forEach((subSection) => {
481
+ if (subSection.isA<SubSection>("sap.fe.macros.controls.section.SubSection")) {
482
+ subSectionsInfo.fe.push(subSection);
483
+ } else {
484
+ subSectionsInfo.others.push(subSection);
485
+ }
486
+ });
487
+ subSectionsInfo.fe.forEach((subSection) => subSection.disconnectVisibilityObserver());
488
+ return subSectionsInfo;
485
489
  }
486
- return false;
490
+ return undefined;
491
+ }
492
+
493
+ /**
494
+ * Get the loading strategy for the object page.
495
+ * @returns The loading strategy for the object page.
496
+ */
497
+ getDisableObjectPageRequestOptimization(): boolean {
498
+ return this._getObjectPageLayoutControl().data("disableObjectPageRequestOptimization") === "true";
487
499
  }
488
500
 
489
501
  private getFirstEditableInput(): UI5Element | undefined {
@@ -541,9 +553,9 @@ class ObjectPageController extends PageController {
541
553
  // In IconTabBar mode keep the second section bound if there is an editable header and we are switching to display mode
542
554
 
543
555
  const disableBindingContextCondition =
544
- (!this.useLazyLoaderOptimizations() &&
556
+ (this.getDisableObjectPageRequestOptimization() &&
545
557
  (iSkip < 1 || (bUseIconTabBar && (iSection > 1 || (iSection === 1 && !bEditableHeader && !bIsInEditMode))))) ||
546
- (this.useLazyLoaderOptimizations() &&
558
+ (!this.getDisableObjectPageRequestOptimization() &&
547
559
  ((!bUseIconTabBar && firstVisibilityBinding) || //if some subsections have visibility binding and we are not in IconTabBar mode
548
560
  (!bUseIconTabBar && !firstVisibilityBinding && iSkip < 1) || // if no subsection has visibility binding and we are not in IconTabBar mode
549
561
  (bUseIconTabBar && (iSection > 1 || (iSection === 1 && !bEditableHeader && !bIsInEditMode)))));
@@ -629,7 +641,7 @@ class ObjectPageController extends PageController {
629
641
  * Set the initial focus in edit mode.
630
642
  * @param aSubSections Object page sub sections
631
643
  */
632
- _updateFocusInEditMode(aSubSections: ObjectPageSubSection[]): void {
644
+ _updateFocusInEditMode(aSubSections: ObjectPageSubSection[], fromTabNavigation = false): void {
633
645
  setTimeout(
634
646
  function (this: ObjectPageController): void {
635
647
  // We set the focus in a timeeout, otherwise the focus sometimes goes to the TabBar
@@ -656,13 +668,13 @@ class ObjectPageController extends PageController {
656
668
  oFieldToFocus.focus(focusInfo);
657
669
  }
658
670
  }.bind(this),
659
- 0 //300
671
+ fromTabNavigation ? 300 : 0
660
672
  );
661
673
  }
662
674
 
663
675
  /**
664
676
  * Get the first sub-section with a visibility bound to the model of the view.
665
- * Sections with Bindings on internal models only are ignored.
677
+ * Sections with bindings on internal models only are ignored.
666
678
  * @returns The visibility binding of the first sub-section or undefined if not found.
667
679
  */
668
680
  _getfirstSubSectionVisibilityBinding(): Binding | undefined {
@@ -678,8 +690,26 @@ class ObjectPageController extends PageController {
678
690
  ?.getBinding("visible");
679
691
  }
680
692
 
693
+ /**
694
+ * Wait for all subsection visibility bindings to be resolved.
695
+ * This method listens for the 'visibilityChanged' event . The change event is fired even if the values are not changed but just resolved.
696
+ * @returns An array of promises that resolve when each visibility binding is resolved.
697
+ */
698
+ waitForAllSubSectionVisibilityBindingsResolved(): Promise<unknown>[] {
699
+ return this._getAllSubSections()
700
+ .filter(
701
+ (subSection) => subSection.isA<SubSection>("sap.fe.macros.controls.section.SubSection") && subSection.getBinding("visible")
702
+ ) //filtering on FE subsections with visibility binding)
703
+ .map(async (subSection) => {
704
+ return new Promise((resolve) => subSection.attachEventOnce("visibilityChanged", resolve));
705
+ });
706
+ }
707
+
681
708
  _handleSubSectionEnteredViewPort(oEvent: UI5Event<{ subSection: ObjectPageSubSection }>): void {
682
709
  const oSubSection = oEvent.getParameter("subSection");
710
+ if (oSubSection.isA<SubSection>("sap.fe.macros.controls.section.SubSection")) {
711
+ oSubSection.handleSubSectionCreated(this.getView());
712
+ }
683
713
  const blocks = oSubSection.getBlocks() as SubSectionBlock[];
684
714
  blocks.forEach((block) => block.setBindingContext(undefined));
685
715
  oSubSection.getMoreBlocks().forEach((subBlock) => subBlock.setBindingContext(undefined));
@@ -834,6 +864,12 @@ class ObjectPageController extends PageController {
834
864
  if (bindingContext) {
835
865
  oModel = bindingContext.getModel();
836
866
 
867
+ // Store navigation parameters in internal model for access by controller extensions
868
+ const internalModelContext = this.getView().getBindingContext("internal") as InternalModelContext;
869
+ if (mParameters) {
870
+ internalModelContext?.setProperty("navigationParameters", mParameters);
871
+ }
872
+
837
873
  // Compute Edit Mode
838
874
  oFinalUIState = this.editFlow.computeModelsForEditMode(bindingContext);
839
875
 
@@ -859,7 +895,9 @@ class ObjectPageController extends PageController {
859
895
  });
860
896
 
861
897
  // should be called only after binding is ready hence calling it in onAfterBinding
862
- (oObjectPage as unknown as { _triggerVisibleSubSectionsEvents: Function })._triggerVisibleSubSectionsEvents();
898
+ if (this.getDisableObjectPageRequestOptimization()) {
899
+ (oObjectPage as unknown as { _triggerVisibleSubSectionsEvents: Function })._triggerVisibleSubSectionsEvents();
900
+ }
863
901
 
864
902
  //To Compute the Edit Binding of the subObject page using root object page, create a context for draft root and update the edit button in sub OP using the context
865
903
  ActionRuntime.updateEditButtonVisibilityAndEnablement(this.getView());
@@ -880,6 +918,45 @@ class ObjectPageController extends PageController {
880
918
 
881
919
  const applyAppState = this.getAppComponent().getAppStateHandler().applyAppState(view);
882
920
  this.pageReady.waitFor(applyAppState);
921
+
922
+ this.reconnectSubSectionVisibilityObservers(this.subSections, oObjectPage, applyAppState);
923
+ }
924
+
925
+ /**
926
+ * Reconnect the visibility observers of all FE subsections after the subsection visibility bindings are resolved and the app state is applied.
927
+ * This function wait for the appSate to be applied before reconnecting the observers and the scrolling to the selected section if it changed during the appState application.
928
+ * @param subSectionInfo Subsections information retrieved during disconnection
929
+ * @param objectPageLayout Object Page Layout control
930
+ * @param waitForApplyAppstate Promise that resolves when the app state is applied
931
+ * @returns A promise that resolves to true if the observers were reconnected, false otherwise
932
+ */
933
+ async reconnectSubSectionVisibilityObservers(
934
+ subSectionInfo: { fe: SubSection[]; others: ObjectPageSubSection[] } | undefined,
935
+ objectPageLayout: ObjectPageLayout,
936
+ waitForApplyAppstate: Promise<unknown>
937
+ ): Promise<boolean> {
938
+ if (!this.getDisableObjectPageRequestOptimization() && subSectionInfo) {
939
+ await Promise.all(this.waitForVisibilityBindings)
940
+ .then(async () => {
941
+ objectPageLayout.setVisible(true);
942
+ try {
943
+ //waiting for the app state to be applied bto ensure focusing on the correct section if required
944
+ await waitForApplyAppstate;
945
+ } catch {
946
+ Log.warning("Error while applying app state");
947
+ }
948
+ subSectionInfo.fe.forEach((subSection) => subSection.observeCurrentSection());
949
+ subSectionInfo.others
950
+ .filter((subsection) => subsection.getVisible())
951
+ .forEach((subSection) => subSection.fireEvent("subSectionEnteredViewPort", { subSection: subSection }));
952
+ return;
953
+ })
954
+ .catch((e: unknown) => {
955
+ Log.error("Error while applying app state", e as string);
956
+ });
957
+ return true;
958
+ }
959
+ return false;
883
960
  }
884
961
 
885
962
  /**
@@ -887,14 +964,16 @@ class ObjectPageController extends PageController {
887
964
  * @param cards Array of cards to be updated
888
965
  */
889
966
  async _updateAvailableCards(cards: WrappedCard[]): Promise<void> {
890
- await this.collaborationManager.collectAvailableCards(cards);
891
- if (cards.length > 0) {
892
- const cardObject = this.collaborationManager.updateCards(cards);
893
- const parentAppId = this.getAppComponent().getId();
894
- this.getAppComponent()
895
- .getCollaborationManagerService()
896
- .addCardsToCollaborationManager(cardObject, parentAppId, this.getView().getId());
897
- this.getAppComponent().getCollaborationManagerService().shareAvailableCards();
967
+ const collaborationManagerService = this.getAppComponent().getCollaborationManagerService();
968
+ // Only collect cards when consumers are connected to the cards channel
969
+ if (collaborationManagerService.hasCollaborationManagerConnected()) {
970
+ await this.collaborationManager.collectAvailableCards(cards);
971
+ if (cards.length > 0) {
972
+ const cardObject = this.collaborationManager.updateCards(cards);
973
+ const parentAppId = this.getAppComponent().getId();
974
+ collaborationManagerService.addCardsToCollaborationManager(cardObject, parentAppId, this.getView().getId());
975
+ collaborationManagerService.shareAvailableCards();
976
+ }
898
977
  }
899
978
  }
900
979
 
@@ -1136,10 +1215,7 @@ class ObjectPageController extends PageController {
1136
1215
  });
1137
1216
  }
1138
1217
 
1139
- _showMessagePopover(err?: string, oRet?: unknown): unknown {
1140
- if (err) {
1141
- Log.error(err);
1142
- }
1218
+ _showMessagePopover(): void {
1143
1219
  const isEditMode = CommonUtils.getIsEditable(this.getView());
1144
1220
  const rootViewController = this.getAppComponent().getRootViewController();
1145
1221
  const currentPageView = rootViewController.isFclEnabled()
@@ -1158,7 +1234,6 @@ class ObjectPageController extends PageController {
1158
1234
  }, 0);
1159
1235
  }
1160
1236
  }
1161
- return oRet;
1162
1237
  }
1163
1238
 
1164
1239
  async _editDocument(): Promise<void | Context> {
@@ -1264,14 +1339,16 @@ class ObjectPageController extends PageController {
1264
1339
  * If data has been provided on the creation rows, the related documents are created
1265
1340
  * before saving the draft version.
1266
1341
  * @param skipBindingToView Indicates if the binding to the view should be skipped
1342
+ * @param useSaveAndLeave Indicates if the save is triggered from a save and leave action
1267
1343
  * @returns Promise
1268
1344
  */
1269
- async _saveDocument(skipBindingToView?: boolean): Promise<void> {
1345
+ async _saveDocument(skipBindingToView?: boolean, useSaveAndLeave?: boolean): Promise<void> {
1270
1346
  const context = this.getView().getBindingContext();
1271
1347
  const model = this.getView().getModel("ui"),
1272
1348
  awaitCreateDocuments: Promise<void | ODataListBinding>[] = [];
1273
1349
  // indicates if we are creating a new row in the OP
1274
1350
  let executeSideEffectsOnError = false;
1351
+ let messagePopoverErr: string | undefined;
1275
1352
  BusyLocker.lock(model);
1276
1353
  try {
1277
1354
  if (this.collaborativeDraft.isCollaborationEnabled()) {
@@ -1296,6 +1373,7 @@ class ObjectPageController extends PageController {
1296
1373
  this._findTables().forEach((table: Table) => {
1297
1374
  const creationRow = table.getCreationRow();
1298
1375
  const tableBinding = this._getTableBinding(table);
1376
+
1299
1377
  const contextKeys = Object.keys((creationRow?.getBindingContext() as ODataV4Context | undefined)?.getObject() || {});
1300
1378
  if (contextKeys.filter((key) => !key.startsWith("@$ui5.")).length) {
1301
1379
  executeSideEffectsOnError = true;
@@ -1304,7 +1382,10 @@ class ObjectPageController extends PageController {
1304
1382
  .createDocument(tableBinding, {
1305
1383
  creationMode: table.data("creationMode"),
1306
1384
  creationRow: creationRow,
1307
- createAtEnd: table.data("createAtEnd") === "true",
1385
+ createAtEnd:
1386
+ (
1387
+ (table.getParent() as TableAPI).getAggregation("creationMode") as TableCreationOptions | undefined
1388
+ )?.getProperty("createAtEnd") === true,
1308
1389
  skipSideEffects: true // the skipSideEffects is a parameter created when we click the save key. If we press this key, we don't execute the handleSideEffects funciton to avoid batch redundancy
1309
1390
  })
1310
1391
  .then(() => tableBinding)
@@ -1327,7 +1408,8 @@ class ObjectPageController extends PageController {
1327
1408
  bindings: bindings as unknown as ODataListBinding[],
1328
1409
  mergePatchDraft: this.mergePatchDraft,
1329
1410
  skipBindingToView,
1330
- isStandardSave
1411
+ isStandardSave,
1412
+ useSaveAndLeave
1331
1413
  });
1332
1414
  } catch (error: unknown) {
1333
1415
  // If the saveDocument in editFlow returns errors we need
@@ -1335,7 +1417,7 @@ class ObjectPageController extends PageController {
1335
1417
  // dataloss logic does not perform the follow up function
1336
1418
  // like e.g. a back navigation hence we return a promise and reject it
1337
1419
  if (error !== RecommendationDialogDecision.Continue) {
1338
- this._showMessagePopover(error as string);
1420
+ messagePopoverErr = (error as string) ?? "";
1339
1421
  }
1340
1422
  throw error;
1341
1423
  }
@@ -1343,6 +1425,12 @@ class ObjectPageController extends PageController {
1343
1425
  if (BusyLocker.isLocked(model)) {
1344
1426
  BusyLocker.unlock(model);
1345
1427
  }
1428
+ if (messagePopoverErr !== undefined) {
1429
+ if (messagePopoverErr.length) {
1430
+ Log.error(messagePopoverErr);
1431
+ }
1432
+ this._showMessagePopover();
1433
+ }
1346
1434
  }
1347
1435
  }
1348
1436
 
@@ -1444,7 +1532,7 @@ class ObjectPageController extends PageController {
1444
1532
  if (oElement && oElement.isA && oElement.isA("sap.m.Panel") && oElement.data("FullScreenTablePlaceHolder")) {
1445
1533
  oElement = oElement.data("tableAPIreference");
1446
1534
  }
1447
- if (oElement && oElement.isA && oElement.isA<TableAPI>("sap.fe.macros.table.TableAPI")) {
1535
+ if (oElement && oElement.isA && oElement.isA<TableAPI>("sap.fe.macros.Table")) {
1448
1536
  const oSubElement = oElement.getContent instanceof Function ? oElement.getContent() : undefined;
1449
1537
  if (oSubElement && oSubElement.isA && oSubElement.isA<Table>("sap.ui.mdc.Table")) {
1450
1538
  aControls.push(oSubElement);
@@ -1914,6 +2002,10 @@ class ObjectPageController extends PageController {
1914
2002
  this.messageButton.fireModelContextChange();
1915
2003
  },
1916
2004
 
2005
+ onTableBindingUpdated(this: ObjectPageController): void {
2006
+ this.messageButton.fireModelContextChange();
2007
+ },
2008
+
1917
2009
  async onCallAction(
1918
2010
  oView: FEView,
1919
2011
  sActionName: string,
@@ -1944,8 +2036,13 @@ class ObjectPageController extends PageController {
1944
2036
 
1945
2037
  return oController.editFlow
1946
2038
  .invokeAction(sActionName, mParameters)
1947
- .then(oController._showMessagePopover.bind(oController, undefined))
1948
- .catch(oController._showMessagePopover.bind(oController));
2039
+ .then((res) => {
2040
+ oController._showMessagePopover();
2041
+ return res;
2042
+ })
2043
+ .catch(() => {
2044
+ oController._showMessagePopover();
2045
+ });
1949
2046
  },
1950
2047
  onDataPointTitlePressed(
1951
2048
  oController: ObjectPageController,
@@ -2027,7 +2124,7 @@ class ObjectPageController extends PageController {
2027
2124
  oInternalModelContext.getProperty("errorNavigationSectionFlag") === false
2028
2125
  ) {
2029
2126
  const oSubSection = oEvent.getParameter("subSection");
2030
- this._updateFocusInEditMode([oSubSection]);
2127
+ this._updateFocusInEditMode([oSubSection], true);
2031
2128
  }
2032
2129
  },
2033
2130
  onVariantSelected: function (this: ObjectPageController): void {
@@ -2041,35 +2138,18 @@ class ObjectPageController extends PageController {
2041
2138
  },
2042
2139
  navigateToSubSection: function (oController: ObjectPageController, vDetailConfig: string | object): void {
2043
2140
  const oDetailConfig = typeof vDetailConfig === "string" ? JSON.parse(vDetailConfig) : vDetailConfig;
2044
- const oObjectPage = oController.getView().byId("fe::ObjectPage") as ObjectPageLayout;
2045
- let oSection;
2046
- let oSubSection;
2047
- if (oDetailConfig.sectionId) {
2048
- oSection = oController.getView().byId(oDetailConfig.sectionId) as ObjectPageSection;
2049
- oSubSection = (
2050
- oDetailConfig.subSectionId
2051
- ? oController.getView().byId(oDetailConfig.subSectionId)
2052
- : oSection && oSection.getSubSections() && oSection.getSubSections()[0]
2053
- ) as ObjectPageSubSection;
2054
- } else if (oDetailConfig.subSectionId) {
2055
- oSubSection = oController.getView().byId(oDetailConfig.subSectionId) as ObjectPageSubSection;
2056
- oSection = oSubSection && (oSubSection.getParent() as ObjectPageSection);
2057
- }
2058
- if (!oSection || !oSubSection || !oSection.getVisible() || !oSubSection.getVisible()) {
2059
- const sTitle = getResourceModel(oController).getText(
2060
- "C_ROUTING_NAVIGATION_DISABLED_TITLE",
2061
- undefined,
2062
- oController.getView().getViewData().entitySet
2063
- );
2064
- Log.error(sTitle);
2065
- MessageBox.error(sTitle);
2141
+
2142
+ // Determine the target ID based on input type
2143
+ let targetId: string | undefined;
2144
+ if (typeof oDetailConfig === "string") {
2145
+ targetId = oDetailConfig;
2066
2146
  } else {
2067
- oObjectPage.setSelectedSection(oSubSection.getId());
2068
- // trigger iapp state change
2069
- oObjectPage.fireNavigate({
2070
- section: oSection,
2071
- subSection: oSubSection
2072
- });
2147
+ // Priority: subSectionId > sectionId
2148
+ targetId = oDetailConfig.subSectionId ?? oDetailConfig.sectionId;
2149
+ }
2150
+
2151
+ if (targetId) {
2152
+ oController.getExtensionAPI().navigateToSubSection(targetId);
2073
2153
  }
2074
2154
  },
2075
2155