@sapui5/sap.fe.templates 1.145.1 → 1.147.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 (127) hide show
  1. package/package.json +1 -1
  2. package/src/sap/fe/templates/.library +2 -2
  3. package/src/sap/fe/templates/AnalyticalListPage/Component.js +1 -1
  4. package/src/sap/fe/templates/AnalyticalListPage/chart/FEChartDelegate.js +1 -1
  5. package/src/sap/fe/templates/AnalyticalListPage/manifest.json +1 -1
  6. package/src/sap/fe/templates/ListComponent.js +1 -1
  7. package/src/sap/fe/templates/ListReport/Component.js +1 -1
  8. package/src/sap/fe/templates/ListReport/ExtendPageDefinition.js +1 -1
  9. package/src/sap/fe/templates/ListReport/ExtensionAPI.js +2 -2
  10. package/src/sap/fe/templates/ListReport/ExtensionAPI.ts +1 -1
  11. package/src/sap/fe/templates/ListReport/LRMessageStrip.js +1 -1
  12. package/src/sap/fe/templates/ListReport/ListReport.view.xml +53 -10
  13. package/src/sap/fe/templates/ListReport/ListReportController.controller.js +78 -10
  14. package/src/sap/fe/templates/ListReport/ListReportController.controller.ts +92 -10
  15. package/src/sap/fe/templates/ListReport/ListReportTemplating.js +40 -4
  16. package/src/sap/fe/templates/ListReport/ListReportTemplating.ts +35 -1
  17. package/src/sap/fe/templates/ListReport/controls/MultipleModeControl.js +1 -1
  18. package/src/sap/fe/templates/ListReport/designtime/ListReport.designtime.helper.js +1 -1
  19. package/src/sap/fe/templates/ListReport/designtime/ListReport.designtime.js +1 -1
  20. package/src/sap/fe/templates/ListReport/manifest.json +1 -1
  21. package/src/sap/fe/templates/ListReport/overrides/IntentBasedNavigation.js +1 -1
  22. package/src/sap/fe/templates/ListReport/overrides/MessageHandler.js +4 -3
  23. package/src/sap/fe/templates/ListReport/overrides/MessageHandler.ts +2 -1
  24. package/src/sap/fe/templates/ListReport/overrides/Share.js +1 -1
  25. package/src/sap/fe/templates/ListReport/overrides/SideEffects.js +1 -1
  26. package/src/sap/fe/templates/ListReport/overrides/ViewState.js +1 -1
  27. package/src/sap/fe/templates/ListReport/view/fragments/MultipleMode.block.js +1 -1
  28. package/src/sap/fe/templates/ObjectPage/Component.js +1 -1
  29. package/src/sap/fe/templates/ObjectPage/ExtendPageDefinition.js +1 -1
  30. package/src/sap/fe/templates/ObjectPage/ExtensionAPI.js +26 -5
  31. package/src/sap/fe/templates/ObjectPage/ExtensionAPI.ts +26 -3
  32. package/src/sap/fe/templates/ObjectPage/ObjectPage.view.xml +5 -1
  33. package/src/sap/fe/templates/ObjectPage/ObjectPageController.controller.js +90 -30
  34. package/src/sap/fe/templates/ObjectPage/ObjectPageController.controller.ts +111 -33
  35. package/src/sap/fe/templates/ObjectPage/ObjectPageTemplating.js +25 -14
  36. package/src/sap/fe/templates/ObjectPage/ObjectPageTemplating.ts +32 -27
  37. package/src/sap/fe/templates/ObjectPage/card/AdaptiveCardContent.js +1 -1
  38. package/src/sap/fe/templates/ObjectPage/card/BaseCardContentProvider.js +1 -1
  39. package/src/sap/fe/templates/ObjectPage/card/Generator.js +1 -1
  40. package/src/sap/fe/templates/ObjectPage/card/actions/HeaderActions.js +1 -1
  41. package/src/sap/fe/templates/ObjectPage/card/facets/HeaderContent.js +1 -1
  42. package/src/sap/fe/templates/ObjectPage/card/facets/HeaderTitle.js +1 -1
  43. package/src/sap/fe/templates/ObjectPage/components/CollaborationDiscardDialog.js +1 -1
  44. package/src/sap/fe/templates/ObjectPage/components/CollaborationDraft.js +1 -1
  45. package/src/sap/fe/templates/ObjectPage/components/DraftToggle.js +1 -1
  46. package/src/sap/fe/templates/ObjectPage/controls/StashableHBox.js +1 -1
  47. package/src/sap/fe/templates/ObjectPage/controls/StashableVBox.js +1 -1
  48. package/src/sap/fe/templates/ObjectPage/controls/SubSectionBlock.js +1 -1
  49. package/src/sap/fe/templates/ObjectPage/designtime/FlexBox.designtime.js +1 -1
  50. package/src/sap/fe/templates/ObjectPage/designtime/ObjectPage.designtime.helper.js +1 -1
  51. package/src/sap/fe/templates/ObjectPage/designtime/ObjectPage.designtime.js +1 -1
  52. package/src/sap/fe/templates/ObjectPage/designtime/StashableHBox.designtime.js +1 -1
  53. package/src/sap/fe/templates/ObjectPage/designtime/StashableVBox.designtime.js +1 -1
  54. package/src/sap/fe/templates/ObjectPage/flexibility/ScrollableHeaderContainer.flexibility.js +1 -1
  55. package/src/sap/fe/templates/ObjectPage/flexibility/StashControlAndDisconnect.js +1 -1
  56. package/src/sap/fe/templates/ObjectPage/flexibility/StashableHBox.flexibility.js +1 -1
  57. package/src/sap/fe/templates/ObjectPage/flexibility/StashableVBox.flexibility.js +1 -1
  58. package/src/sap/fe/templates/ObjectPage/flexibility/UnstashControlAndConnect.js +1 -1
  59. package/src/sap/fe/templates/ObjectPage/manifest.json +2 -2
  60. package/src/sap/fe/templates/ObjectPage/overrides/CollaborationManager.js +1 -1
  61. package/src/sap/fe/templates/ObjectPage/overrides/IntentBasedNavigation.js +1 -1
  62. package/src/sap/fe/templates/ObjectPage/overrides/InternalRouting.js +1 -1
  63. package/src/sap/fe/templates/ObjectPage/overrides/MessageHandler.js +1 -1
  64. package/src/sap/fe/templates/ObjectPage/overrides/Paginator.js +1 -1
  65. package/src/sap/fe/templates/ObjectPage/overrides/Share.js +3 -3
  66. package/src/sap/fe/templates/ObjectPage/overrides/Share.ts +1 -1
  67. package/src/sap/fe/templates/ObjectPage/overrides/ViewState.js +1 -1
  68. package/src/sap/fe/templates/ObjectPage/view/fragments/Actions.fragment.xml +12 -2
  69. package/src/sap/fe/templates/ObjectPage/view/fragments/EmphasizedFirstHeaderAction.fragment.xml +181 -0
  70. package/src/sap/fe/templates/ObjectPage/view/fragments/Section.fragment.xml +2 -0
  71. package/src/sap/fe/templates/ObjectPage/view/fragments/SectionContent.fragment.xml +18 -12
  72. package/src/sap/fe/templates/ObjectPage/view/fragments/SectionFormContent.fragment.xml +2 -0
  73. package/src/sap/fe/templates/ObjectPage/view/fragments/SectionMoreFormContent.fragment.xml +2 -0
  74. package/src/sap/fe/templates/ObjectPage/view/fragments/TransportSelection.js +1 -1
  75. package/src/sap/fe/templates/TableScroller.js +1 -1
  76. package/src/sap/fe/templates/library.js +2 -2
  77. package/src/sap/fe/templates/messagebundle.properties +1 -1
  78. package/src/sap/fe/templates/messagebundle_ar.properties +1 -1
  79. package/src/sap/fe/templates/messagebundle_bg.properties +1 -1
  80. package/src/sap/fe/templates/messagebundle_ca.properties +1 -1
  81. package/src/sap/fe/templates/messagebundle_cnr.properties +1 -1
  82. package/src/sap/fe/templates/messagebundle_cs.properties +1 -1
  83. package/src/sap/fe/templates/messagebundle_cy.properties +1 -1
  84. package/src/sap/fe/templates/messagebundle_da.properties +1 -1
  85. package/src/sap/fe/templates/messagebundle_de.properties +8 -8
  86. package/src/sap/fe/templates/messagebundle_el.properties +1 -1
  87. package/src/sap/fe/templates/messagebundle_en.properties +1 -1
  88. package/src/sap/fe/templates/messagebundle_en_GB.properties +1 -1
  89. package/src/sap/fe/templates/messagebundle_en_US_saprigi.properties +1 -1
  90. package/src/sap/fe/templates/messagebundle_es.properties +3 -3
  91. package/src/sap/fe/templates/messagebundle_es_MX.properties +1 -1
  92. package/src/sap/fe/templates/messagebundle_et.properties +1 -1
  93. package/src/sap/fe/templates/messagebundle_fi.properties +1 -1
  94. package/src/sap/fe/templates/messagebundle_fr.properties +1 -1
  95. package/src/sap/fe/templates/messagebundle_fr_CA.properties +1 -1
  96. package/src/sap/fe/templates/messagebundle_hi.properties +1 -1
  97. package/src/sap/fe/templates/messagebundle_hr.properties +1 -1
  98. package/src/sap/fe/templates/messagebundle_hu.properties +1 -1
  99. package/src/sap/fe/templates/messagebundle_id.properties +1 -1
  100. package/src/sap/fe/templates/messagebundle_it.properties +1 -1
  101. package/src/sap/fe/templates/messagebundle_iw.properties +2 -2
  102. package/src/sap/fe/templates/messagebundle_ja.properties +1 -1
  103. package/src/sap/fe/templates/messagebundle_kk.properties +1 -1
  104. package/src/sap/fe/templates/messagebundle_ko.properties +1 -1
  105. package/src/sap/fe/templates/messagebundle_lt.properties +1 -1
  106. package/src/sap/fe/templates/messagebundle_lv.properties +1 -1
  107. package/src/sap/fe/templates/messagebundle_mk.properties +1 -1
  108. package/src/sap/fe/templates/messagebundle_ms.properties +1 -1
  109. package/src/sap/fe/templates/messagebundle_nl.properties +1 -1
  110. package/src/sap/fe/templates/messagebundle_no.properties +1 -1
  111. package/src/sap/fe/templates/messagebundle_pl.properties +1 -1
  112. package/src/sap/fe/templates/messagebundle_pt.properties +1 -1
  113. package/src/sap/fe/templates/messagebundle_pt_PT.properties +1 -1
  114. package/src/sap/fe/templates/messagebundle_ro.properties +1 -1
  115. package/src/sap/fe/templates/messagebundle_ru.properties +1 -1
  116. package/src/sap/fe/templates/messagebundle_sh.properties +1 -1
  117. package/src/sap/fe/templates/messagebundle_sk.properties +1 -1
  118. package/src/sap/fe/templates/messagebundle_sl.properties +1 -1
  119. package/src/sap/fe/templates/messagebundle_sr.properties +1 -1
  120. package/src/sap/fe/templates/messagebundle_sv.properties +1 -1
  121. package/src/sap/fe/templates/messagebundle_th.properties +1 -1
  122. package/src/sap/fe/templates/messagebundle_tr.properties +1 -1
  123. package/src/sap/fe/templates/messagebundle_uk.properties +3 -3
  124. package/src/sap/fe/templates/messagebundle_vi.properties +1 -1
  125. package/src/sap/fe/templates/messagebundle_zh_CN.properties +1 -1
  126. package/src/sap/fe/templates/messagebundle_zh_TW.properties +1 -1
  127. package/src/sap/fe/templates/types/sap.fe.templates-auto-ext.d.js +1 -1
@@ -52,13 +52,16 @@ import TableScroller from "sap/fe/templates/TableScroller";
52
52
  import type Button from "sap/m/Button";
53
53
  import type InputBase from "sap/m/InputBase";
54
54
  import InstanceManager from "sap/m/InstanceManager";
55
+ import type MenuButton from "sap/m/MenuButton";
55
56
  import type NavContainer from "sap/m/NavContainer";
56
57
  import type Popover from "sap/m/Popover";
57
58
  import type ToolbarSpacer from "sap/m/ToolbarSpacer";
58
59
  import Device from "sap/ui/Device";
59
60
  import type UI5Event from "sap/ui/base/Event";
61
+ import type ManagedObject from "sap/ui/base/ManagedObject";
60
62
  import type { CommandExecution$ExecuteEvent } from "sap/ui/core/CommandExecution";
61
63
  import type Control from "sap/ui/core/Control";
64
+ import type CustomData from "sap/ui/core/CustomData";
62
65
  import UI5Element from "sap/ui/core/Element";
63
66
  import type InvisibleText from "sap/ui/core/InvisibleText";
64
67
  import Library from "sap/ui/core/Lib";
@@ -184,6 +187,39 @@ class ObjectPageController extends PageController {
184
187
 
185
188
  private subSections?: { fe: SubSection[]; others: ObjectPageSubSection[] };
186
189
 
190
+ private previousBindingContextPath?: string;
191
+
192
+ /**
193
+ * Returns controls (Button / MenuButton) that are marked as "primary action".
194
+ * The marker is set by the converters when an action is emphasized (annotation-based) or
195
+ * configured as primaryAction (custom action defined in the manifest).
196
+ * @param root Root control to start the search from
197
+ * @param onlyActionable If true, only actionable (enabled) candidates are returned
198
+ * @returns An array of controls that are candidates for primary action shortcuts
199
+ */
200
+ private _getPrimaryActionShortcutCandidates(root: ManagedObject, onlyActionable = false): Array<Button | MenuButton> {
201
+ return root.findAggregatedObjects(true, (object: ManagedObject) => {
202
+ const isButton = object.isA("sap.m.Button");
203
+ const isMenuButton = object.isA("sap.m.MenuButton");
204
+ if (!isButton && !isMenuButton) {
205
+ return false;
206
+ }
207
+ const ctrl = object as Button | MenuButton;
208
+ const flag = ctrl
209
+ .getCustomData()
210
+ .find((customData: CustomData) => customData.getKey() === "fePrimaryActionShortcut")
211
+ ?.getValue();
212
+ if (flag !== true && flag !== "true") {
213
+ return false;
214
+ }
215
+ if (!ctrl.getVisible()) {
216
+ return false;
217
+ }
218
+ // For focus placement we must ignore disabled candidates.
219
+ return onlyActionable ? ctrl.getEnabled() : true;
220
+ }) as Array<Button | MenuButton>;
221
+ }
222
+
187
223
  @publicExtension()
188
224
  @finalExtension()
189
225
  getExtensionAPI(sId?: string): ExtensionAPI {
@@ -296,12 +332,13 @@ class ObjectPageController extends PageController {
296
332
  }
297
333
 
298
334
  /**
299
- * Find the last visible subsection and add the sapUxAPObjectPageSubSectionFitContainer CSS class if it contains only a GridTable or a TreeTable.
335
+ * Add the sapUxAPObjectPageSubSectionFitContainer CSS class to every visible subsection that contains only a single GridTable or TreeTable.
336
+ * This makes the table fill the full height of its container so that the scrollbar appears on the table itself rather than on the page.
300
337
  * @param subSections The sub sections to look for
301
338
  */
302
339
  private checkSectionsForNonResponsiveTable(subSections: ObjectPageSubSection[]): void {
303
- const changeClassForTables = (event: Event, lastVisibleSubSection: ObjectPageSubSection): void => {
304
- const blocks = [...lastVisibleSubSection.getBlocks(), ...lastVisibleSubSection.getMoreBlocks()];
340
+ const changeClassForTables = (event: Event, visibleSubSection: ObjectPageSubSection): void => {
341
+ const blocks = [...visibleSubSection.getBlocks(), ...visibleSubSection.getMoreBlocks()];
305
342
  if (blocks.length === 1) {
306
343
  const table = this.searchTableInBlock(blocks[0] as SubSectionBlock);
307
344
  if (!table) {
@@ -315,17 +352,15 @@ class ObjectPageController extends PageController {
315
352
  tableAPI?.getTableDefinition().control.rowCountMode === "Auto"
316
353
  ) {
317
354
  //In case there is only a single table in a subSection we fit that to the whole page so that the scrollbar comes only on table and not on page
318
- lastVisibleSubSection.addStyleClass("sapUxAPObjectPageSubSectionFitContainer");
319
- lastVisibleSubSection.detachEvent("modelContextChange", changeClassForTables, this);
355
+ visibleSubSection.addStyleClass("sapUxAPObjectPageSubSectionFitContainer");
356
+ visibleSubSection.detachEvent("modelContextChange", changeClassForTables, this);
320
357
  }
321
358
  }
322
359
  };
323
- for (let subSectionIndex = subSections.length - 1; subSectionIndex >= 0; subSectionIndex--) {
324
- if (subSections[subSectionIndex].getVisible()) {
325
- const lastVisibleSubSection = subSections[subSectionIndex];
360
+ for (const subSection of subSections) {
361
+ if (subSection.getVisible()) {
326
362
  // We need to attach this event in order to manage the Object Page Lazy Loading mechanism
327
- lastVisibleSubSection.attachEvent("modelContextChange", lastVisibleSubSection, changeClassForTables, this);
328
- break;
363
+ subSection.attachEvent("modelContextChange", subSection, changeClassForTables, this);
329
364
  }
330
365
  }
331
366
  }
@@ -395,6 +430,7 @@ class ObjectPageController extends PageController {
395
430
 
396
431
  _onBeforeBinding(oContext: ODataV4Context, mParameters: BindingParams = {}): void {
397
432
  // TODO: we should check how this comes together with the transaction helper, same to the change in the afterBinding
433
+ this.previousBindingContextPath = this.getView().getBindingContext()?.getPath();
398
434
  const aTables = this._findTables(),
399
435
  oObjectPage = this._getObjectPageLayoutControl(),
400
436
  oInternalModelContext = this.getView().getBindingContext("internal") as InternalModelContext,
@@ -504,12 +540,21 @@ class ObjectPageController extends PageController {
504
540
  }
505
541
 
506
542
  /**
507
- * Get the first clickable element in the header of the object page.
543
+ * Get the first clickable element in the object page.
508
544
  * @private
509
545
  * @param objectPage Object Page Layout control
510
- * @returns The first clickable element found in the header
546
+ * @returns The first clickable element found
511
547
  */
512
548
  private getFirstClickableElement(objectPage: ObjectPageLayout): UI5Element | undefined {
549
+ // In display mode, if a visible primary action with the emphasis exists in the footer, it must be the first clickable element on the page.
550
+ const footer = objectPage.getFooter();
551
+ const footerPrimaryAction = footer
552
+ ? this._getPrimaryActionShortcutCandidates(footer as unknown as ManagedObject, true)[0]
553
+ : undefined;
554
+ if (footerPrimaryAction) {
555
+ return footerPrimaryAction;
556
+ }
557
+ // Fallback: first visible & enabled header action (Edit, etc.)
513
558
  let firstClickableElement;
514
559
  const actions = objectPage.getHeaderTitle() && (objectPage.getHeaderTitle() as ObjectPageDynamicHeaderTitle).getActions();
515
560
  if (actions?.length) {
@@ -551,23 +596,22 @@ class ObjectPageController extends PageController {
551
596
  const aSubSections = oSection.getSubSections();
552
597
  for (let iSubSection = 0; iSubSection < aSubSections.length; iSubSection++, iSkip--) {
553
598
  // In IconTabBar mode keep the second section bound if there is an editable header and we are switching to display mode
554
-
599
+ const oSubSection = aSubSections[iSubSection];
555
600
  const disableBindingContextCondition =
556
601
  (this.getDisableObjectPageRequestOptimization() &&
557
602
  (iSkip < 1 || (bUseIconTabBar && (iSection > 1 || (iSection === 1 && !bEditableHeader && !bIsInEditMode))))) ||
558
603
  (!this.getDisableObjectPageRequestOptimization() &&
559
- ((!bUseIconTabBar && firstVisibilityBinding) || //if some subsections have visibility binding and we are not in IconTabBar mode
604
+ ((!bUseIconTabBar && (iSkip < 1 || oSubSection.getBinding("visible"))) || //if we are not in IconTabBar mode, all section with index >=3 or with visibility binding should be disconnected
560
605
  (!bUseIconTabBar && !firstVisibilityBinding && iSkip < 1) || // if no subsection has visibility binding and we are not in IconTabBar mode
561
606
  (bUseIconTabBar && (iSection > 1 || (iSection === 1 && !bEditableHeader && !bIsInEditMode)))));
562
607
  if (disableBindingContextCondition) {
563
- const oSubSection = aSubSections[iSubSection];
564
608
  // SubSection's binding is enabled.
565
609
  oSubSection.setBindingContext(undefined);
566
610
  const blocks = oSubSection.getBlocks();
567
611
  // SubSection's contents binding is disabled.
568
612
  blocks.forEach((block) => {
569
613
  if (block.isA<SubSectionBlock>("sap.fe.templates.ObjectPage.controls.SubSectionBlock")) {
570
- block.content.setBindingContext(null);
614
+ block.content.setBindingContext?.(null);
571
615
  } else {
572
616
  block.setBindingContext(null);
573
617
  }
@@ -719,7 +763,7 @@ class ObjectPageController extends PageController {
719
763
  const blocks = oSubSection.getBlocks();
720
764
  blocks.forEach((block) => {
721
765
  if (block.isA<SubSectionBlock>("sap.fe.templates.ObjectPage.controls.SubSectionBlock")) {
722
- block.content.setBindingContext(undefined);
766
+ block.content.setBindingContext?.(undefined);
723
767
  } else {
724
768
  block.setBindingContext(undefined);
725
769
  }
@@ -773,11 +817,14 @@ class ObjectPageController extends PageController {
773
817
  }
774
818
 
775
819
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
776
- _onAfterBinding(inputBindingContext: Context | undefined, mParameters: BindingParams | undefined): void {
820
+ _onAfterBinding(inputBindingContext: ODataV4Context | undefined, mParameters: BindingParams | undefined): void {
777
821
  const view = this.getView();
778
822
  const viewLevel = view?.getViewData()?.viewLevel;
779
823
  const oObjectPage = this._getObjectPageLayoutControl();
780
824
  const aTables = this._findTables();
825
+ if ([NavigationReason.EditFlowAction, NavigationReason.RowPress].includes(mParameters?.reason as NavigationReason)) {
826
+ this.editFlow.storeSiblingContextData(inputBindingContext);
827
+ }
781
828
 
782
829
  this._sideEffects.clearFieldGroupsValidity();
783
830
 
@@ -931,7 +978,12 @@ class ObjectPageController extends PageController {
931
978
  const applyAppState = this.getAppComponent().getAppStateHandler().applyAppState(view);
932
979
  this.pageReady.waitFor(applyAppState);
933
980
 
934
- this.reconnectSubSectionVisibilityObservers(this.subSections, oObjectPage, applyAppState);
981
+ this.reconnectSubSectionVisibilityObservers(
982
+ this.subSections,
983
+ oObjectPage,
984
+ applyAppState,
985
+ this.previousBindingContextPath !== this.getView().getBindingContext()?.getPath()
986
+ );
935
987
  }
936
988
 
937
989
  /**
@@ -940,15 +992,17 @@ class ObjectPageController extends PageController {
940
992
  * @param subSectionInfo Subsections information retrieved during disconnection
941
993
  * @param objectPageLayout Object Page Layout control
942
994
  * @param waitForApplyAppstate Promise that resolves when the app state is applied
995
+ * @param waitForVisibilityBindings Boolean indicating whether to wait for visibility bindings to be resolved before reconnecting observers
943
996
  * @returns A promise that resolves to true if the observers were reconnected, false otherwise
944
997
  */
945
998
  async reconnectSubSectionVisibilityObservers(
946
999
  subSectionInfo: { fe: SubSection[]; others: ObjectPageSubSection[] } | undefined,
947
1000
  objectPageLayout: ObjectPageLayout,
948
- waitForApplyAppstate: Promise<unknown>
1001
+ waitForApplyAppstate: Promise<unknown>,
1002
+ waitForVisibilityBindings = true
949
1003
  ): Promise<boolean> {
950
1004
  if (!this.getDisableObjectPageRequestOptimization() && subSectionInfo) {
951
- await Promise.all(this.waitForVisibilityBindings)
1005
+ await Promise.all(waitForVisibilityBindings ? this.waitForVisibilityBindings : [])
952
1006
  .then(async () => {
953
1007
  objectPageLayout.setVisible(true);
954
1008
  try {
@@ -1180,7 +1234,9 @@ class ObjectPageController extends PageController {
1180
1234
  if (!oObjectPageContext || pathsToResolve.length === 0) {
1181
1235
  return Promise.resolve(build());
1182
1236
  }
1183
- await Promise.all(pathsToResolve.map(async (p) => (oObjectPageContext as ODataV4Context).requestObject(p).catch(() => undefined)));
1237
+ await Promise.all(
1238
+ pathsToResolve.map(async (p) => (oObjectPageContext as ODataV4Context).requestProperty(p).catch(() => undefined))
1239
+ );
1184
1240
  return build();
1185
1241
  }
1186
1242
 
@@ -1404,10 +1460,11 @@ class ObjectPageController extends PageController {
1404
1460
  );
1405
1461
  }
1406
1462
  });
1407
- const isSkipBindingToView = skipBindingToView as unknown as CommandExecution$ExecuteEvent;
1408
- const isStandardSave =
1409
- isSkipBindingToView && typeof isSkipBindingToView == "object" && isSkipBindingToView.getSource().getCommand() === "Save";
1410
-
1463
+ let isStandardSave: boolean | undefined;
1464
+ if (skipBindingToView && typeof skipBindingToView === "object") {
1465
+ const command = (skipBindingToView as CommandExecution$ExecuteEvent)?.getSource?.()?.getCommand?.();
1466
+ isStandardSave = command === "Save";
1467
+ }
1411
1468
  const bindings = await Promise.all(awaitCreateDocuments);
1412
1469
  // We need to either reject or resolve a promise here and return it since this save
1413
1470
  // function is not only called when pressing the save button in the footer, but also
@@ -1431,7 +1488,6 @@ class ObjectPageController extends PageController {
1431
1488
  if (error !== RecommendationDialogDecision.Continue) {
1432
1489
  messagePopoverErr = (error as string) ?? "";
1433
1490
  }
1434
- throw error;
1435
1491
  }
1436
1492
  } finally {
1437
1493
  if (BusyLocker.isLocked(model)) {
@@ -1951,8 +2007,27 @@ class ObjectPageController extends PageController {
1951
2007
  }
1952
2008
  ): void {
1953
2009
  /**
1954
- * Invokes the page primary action on press of Ctrl+Enter.
2010
+ * Invokes the page primary action when the user presses Ctrl+Enter (Cmd+Enter on macOS).
1955
2011
  */
2012
+
2013
+ const primaryCandidate = oController._getPrimaryActionShortcutCandidates(oView)[0];
2014
+
2015
+ /* By design, there must be at most one candidate due to the "single emphasis per page" rule.
2016
+ If a primary-enter target is found, it must fully take over Ctrl/Cmd+Enter.*/
2017
+
2018
+ if (primaryCandidate) {
2019
+ if (!primaryCandidate.getEnabled()) {
2020
+ // Take over Ctrl/Cmd+Enter, but do not trigger anything when the primary action is disabled.
2021
+ return;
2022
+ }
2023
+ if (primaryCandidate.isA("sap.m.Button")) {
2024
+ (primaryCandidate as Button).firePress();
2025
+ }
2026
+ if ((primaryCandidate as MenuButton).isA("sap.m.MenuButton")) {
2027
+ (primaryCandidate as MenuButton).fireDefaultAction();
2028
+ }
2029
+ return;
2030
+ }
1956
2031
  const iViewLevel = oController.getView().getViewData().viewLevel;
1957
2032
  if (mConditions.positiveActionVisible) {
1958
2033
  if (mConditions.positiveActionEnabled) {
@@ -1980,7 +2055,7 @@ class ObjectPageController extends PageController {
1980
2055
  const tableAPI = event.getSource();
1981
2056
  const table = tableAPI.content;
1982
2057
  const currentActionPromise = this.editFlow.getCurrentActionPromise();
1983
- const tableContexts = this._getTableBinding(table)?.getCurrentContexts();
2058
+ const tableContexts = this._getTableBinding(table)?.getAllCurrentContexts();
1984
2059
 
1985
2060
  if (currentActionPromise && tableContexts?.length) {
1986
2061
  try {
@@ -1988,10 +2063,13 @@ class ObjectPageController extends PageController {
1988
2063
  if (actionResponse?.controlId === table.getId()) {
1989
2064
  const actionData = actionResponse.oData;
1990
2065
  const keys = actionResponse.keys;
1991
- const newItem = tableContexts.findIndex((tableContext: Context) => {
1992
- const tableData = tableContext.getObject();
1993
- return keys.every((key: string) => tableData[key] === actionData[key]);
1994
- });
2066
+ const newItem =
2067
+ tableContexts
2068
+ .find((tableContext: Context) => {
2069
+ const tableData = tableContext.getObject();
2070
+ return keys.every((key: string) => tableData[key] === actionData[key]);
2071
+ })
2072
+ ?.getIndex() ?? -1;
1995
2073
  if (newItem !== -1) {
1996
2074
  const dialog = InstanceManager.getOpenDialogs().find((dialog) => dialog.data("FullScreenDialog") !== true);
1997
2075
  if (dialog) {