@sapui5/sap.fe.core 1.136.10 → 1.136.12

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 (60) hide show
  1. package/package.json +1 -1
  2. package/src/sap/fe/core/.library +1 -1
  3. package/src/sap/fe/core/AppStateHandler.js +3 -2
  4. package/src/sap/fe/core/AppStateHandler.ts +4 -1
  5. package/src/sap/fe/core/PageController.controller.js +10 -0
  6. package/src/sap/fe/core/PageController.controller.ts +3 -0
  7. package/src/sap/fe/core/TemplateComponent.js +1 -1
  8. package/src/sap/fe/core/TemplateComponent.ts +1 -3
  9. package/src/sap/fe/core/controllerextensions/EditFlow.js +62 -20
  10. package/src/sap/fe/core/controllerextensions/EditFlow.ts +98 -38
  11. package/src/sap/fe/core/controllerextensions/InternalRouting.js +29 -16
  12. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +42 -18
  13. package/src/sap/fe/core/controllerextensions/MessageHandler.js +1 -1
  14. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +1 -0
  15. package/src/sap/fe/core/controllerextensions/Routing.js +6 -2
  16. package/src/sap/fe/core/controllerextensions/Routing.ts +4 -1
  17. package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.js +8 -1
  18. package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.ts +8 -0
  19. package/src/sap/fe/core/controllerextensions/editFlow/operations/ODataOperation.js +2 -1
  20. package/src/sap/fe/core/controllerextensions/editFlow/operations/ODataOperation.ts +1 -0
  21. package/src/sap/fe/core/controllerextensions/routing/RouterProxy.js +11 -9
  22. package/src/sap/fe/core/controllerextensions/routing/RouterProxy.ts +22 -9
  23. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DraftDataLossDialog.js +2 -1
  24. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DraftDataLossDialog.tsx +1 -0
  25. package/src/sap/fe/core/controls/Recommendations/ConfirmRecommendationDialog.js +29 -1
  26. package/src/sap/fe/core/controls/Recommendations/ConfirmRecommendationDialog.tsx +32 -0
  27. package/src/sap/fe/core/converters/controls/Common/Action.js +17 -2
  28. package/src/sap/fe/core/converters/controls/Common/Action.ts +23 -2
  29. package/src/sap/fe/core/converters/controls/Common/Table.js +54 -46
  30. package/src/sap/fe/core/converters/controls/Common/Table.ts +65 -45
  31. package/src/sap/fe/core/converters/controls/Common/table/Columns.js +26 -6
  32. package/src/sap/fe/core/converters/controls/Common/table/Columns.ts +32 -10
  33. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +14 -19
  34. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +17 -28
  35. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +5 -2
  36. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +7 -1
  37. package/src/sap/fe/core/designtime/AnnotationBasedChanges.js +8 -3
  38. package/src/sap/fe/core/designtime/AnnotationBasedChanges.ts +7 -2
  39. package/src/sap/fe/core/formatters/FPMFormatter.js +2 -2
  40. package/src/sap/fe/core/formatters/FPMFormatter.ts +1 -1
  41. package/src/sap/fe/core/fpm/manifest.json +1 -1
  42. package/src/sap/fe/core/helpers/AppStartupHelper.js +75 -18
  43. package/src/sap/fe/core/helpers/AppStartupHelper.ts +79 -25
  44. package/src/sap/fe/core/helpers/MetaModelFunction.js +10 -3
  45. package/src/sap/fe/core/helpers/MetaModelFunction.ts +9 -3
  46. package/src/sap/fe/core/library.js +1 -1
  47. package/src/sap/fe/core/messagebundle_da.properties +1 -1
  48. package/src/sap/fe/core/messagebundle_es.properties +1 -1
  49. package/src/sap/fe/core/messagebundle_fr.properties +1 -1
  50. package/src/sap/fe/core/messagebundle_ko.properties +4 -4
  51. package/src/sap/fe/core/messagebundle_no.properties +2 -2
  52. package/src/sap/fe/core/messagebundle_uk.properties +2 -2
  53. package/src/sap/fe/core/messagebundle_vi.properties +4 -4
  54. package/src/sap/fe/core/rootView/Fcl.controller.js +1 -1
  55. package/src/sap/fe/core/rootView/Fcl.controller.ts +6 -1
  56. package/src/sap/fe/core/services/CollaborationManagerServiceFactory.js +17 -29
  57. package/src/sap/fe/core/services/CollaborationManagerServiceFactory.ts +23 -26
  58. package/src/sap/fe/core/services/RoutingServiceFactory.js +11 -5
  59. package/src/sap/fe/core/services/RoutingServiceFactory.ts +16 -7
  60. package/ui5.yaml +1 -0
@@ -70,7 +70,7 @@ import type { MetaModelEntityType } from "types/metamodel_types";
70
70
  import ActionRuntime from "../ActionRuntime";
71
71
  import { ConfirmRecommendationDialog, RecommendationDialogDecision } from "../controls/Recommendations/ConfirmRecommendationDialog";
72
72
  import { CreationMode, type BaseManifestSettings } from "../converters/ManifestSettings";
73
- import { isFulfilled } from "../helpers/TypeGuards";
73
+ import { isFulfilled, isRejected } from "../helpers/TypeGuards";
74
74
  import draftDataLossPopup from "./editFlow/draftDataLossPopup";
75
75
  import type { OperationResult } from "./editFlow/operations/ODataOperation";
76
76
  import NavigationReason from "./routing/NavigationReason";
@@ -103,6 +103,7 @@ type InternalCreateParameters = {
103
103
  skipSideEffects?: boolean;
104
104
  selectedContexts?: ODataV4Context[];
105
105
  creationDialogFields?: string[];
106
+ requestAtLeast?: string[];
106
107
  };
107
108
 
108
109
  /**
@@ -525,6 +526,7 @@ class EditFlow extends BaseControllerExtension {
525
526
  * @param mInParameters.selectedContexts The contexts that are selected in the table initiating the creation. Used in case of a TreeTable to determine the parent context of the created document
526
527
  * @param mInParameters.singleDraftForCreate When enabled, an extra request checks if any drafts exist that were never saved. If unsaved drafts are found, the newest one is opened. If no unsaved drafts are found, a new entity is created
527
528
  * @param mInParameters.creationDialogFields Defines the list of properties that are displayed in the creation dialog when the creation mode is set to 'CreationDialog'.<br/>The value is a comma-separated list of property names
529
+ * @param mInParameters.requestAtLeast PRIVATE - Defines the list of properties that should be requested when creating the new document to avoid additional requests later on.<br/>The value is an array of property names
528
530
  * @returns Promise resolves once the object has been created
529
531
  * @public
530
532
  * @since 1.90.0
@@ -549,6 +551,7 @@ class EditFlow extends BaseControllerExtension {
549
551
  selectedContexts?: ODataV4Context[];
550
552
  singleDraftForCreate?: boolean;
551
553
  creationDialogFields?: string[];
554
+ requestAtLeast?: string[];
552
555
  }
553
556
  ): Promise<void> {
554
557
  let oDataListBinding!: ODataListBinding;
@@ -657,13 +660,17 @@ class EditFlow extends BaseControllerExtension {
657
660
  case CreationMode.External:
658
661
  return this.createExternalDocument(vListBinding, parameters.outbound);
659
662
  case CreationMode.Deferred:
660
- return this.createDeferredDocument(oDataListBinding, parentContext, parameters.data);
663
+ return this.createDeferredDocument(
664
+ { parentContext, data: parameters.data, requestAtLeast: parameters.requestAtLeast },
665
+ oDataListBinding
666
+ );
661
667
  case CreationMode.CreationRow:
662
668
  return parameters.creationRow
663
669
  ? this.createCreateRowDocument({
664
670
  creationRow: parameters.creationRow,
665
671
  skipSideEffects: parameters.skipSideEffects,
666
- createAtEnd: parameters.createAtEnd
672
+ createAtEnd: parameters.createAtEnd,
673
+ requestAtLeast: parameters.requestAtLeast
667
674
  })
668
675
  : undefined;
669
676
  case CreationMode.Inline:
@@ -674,7 +681,8 @@ class EditFlow extends BaseControllerExtension {
674
681
  createAtEnd: parameters.createAtEnd,
675
682
  skipSideEffects: parameters.skipSideEffects,
676
683
  parentContext,
677
- data: parameters.data
684
+ data: parameters.data,
685
+ requestAtLeast: parameters.requestAtLeast
678
686
  },
679
687
  oDataListBinding
680
688
  );
@@ -690,7 +698,8 @@ class EditFlow extends BaseControllerExtension {
690
698
  skipSideEffects: parameters.skipSideEffects,
691
699
  parentContext,
692
700
  data: parameters.data,
693
- creationDialogFields: parameters.creationDialogFields
701
+ creationDialogFields: parameters.creationDialogFields,
702
+ requestAtLeast: parameters.requestAtLeast
694
703
  },
695
704
  oDataListBinding
696
705
  );
@@ -718,6 +727,7 @@ class EditFlow extends BaseControllerExtension {
718
727
  bFromDeferred: parameters.bFromDeferred,
719
728
  skipSideEffects: parameters.skipSideEffects,
720
729
  createAction: parameters.createAction,
730
+ requestAtLeast: parameters.requestAtLeast,
721
731
  parentContext
722
732
  },
723
733
  oDataListBinding
@@ -728,16 +738,30 @@ class EditFlow extends BaseControllerExtension {
728
738
  }
729
739
 
730
740
  /**
731
- *Executes the mandatory configuration after the document has been created.
741
+ * Executes the mandatory configuration after the document has been created.
732
742
  * @param prerequisite Promise of the document creation and the following navigation
733
743
  * @param listBinding ODataListBinding where the document is created
734
744
  * @returns Promise resolves once the configuration is done
735
745
  */
736
- async postDocumentCreation(prerequisite: Promise<[Context, unknown]>, listBinding: ODataListBinding): Promise<void> {
746
+ async postDocumentCreation(
747
+ prerequisite: Promise<[PromiseSettledResult<Context>, PromiseSettledResult<unknown>]>,
748
+ listBinding: ODataListBinding
749
+ ): Promise<void> {
737
750
  const programmingModel: string = this.getProgrammingModel(listBinding);
738
751
  const model = listBinding.getModel();
739
- const params = await prerequisite;
740
- const newDocumentContext = params[0];
752
+ const results = await prerequisite;
753
+
754
+ // Check if creation or navigation failed and throw the respective error
755
+ const creation = results[0];
756
+ if (isRejected(creation)) {
757
+ throw creation.reason;
758
+ }
759
+ const navigation = results[1];
760
+ if (isRejected(navigation)) {
761
+ throw navigation.reason;
762
+ }
763
+
764
+ const newDocumentContext = creation.value;
741
765
  this._setStickySessionInternalProperties(programmingModel, model);
742
766
  await this.base.editFlow.onAfterCreate({ context: newDocumentContext });
743
767
  this.setEditMode(EditMode.Editable); // The createMode flag will be set in computeModelsForEditMode
@@ -785,12 +809,14 @@ class EditFlow extends BaseControllerExtension {
785
809
  * @param parameters.createAtEnd The new document is created at the end.
786
810
  * @param parameters.creationRow The creation row
787
811
  * @param parameters.skipSideEffects The sideEffects are requested
812
+ * @param parameters.requestAtLeast Defines the list of properties that should be requested when creating the new document to avoid additional requests later on.
788
813
  * @returns Promise resolves once the document has been created
789
814
  */
790
815
  async createCreateRowDocument(parameters: {
791
816
  createAtEnd?: boolean;
792
817
  creationRow: CreationRow;
793
818
  skipSideEffects?: boolean;
819
+ requestAtLeast?: string[];
794
820
  }): Promise<void> {
795
821
  let creation: Promise<Context>;
796
822
  const appComponent = this.getAppComponent();
@@ -855,7 +881,8 @@ class EditFlow extends BaseControllerExtension {
855
881
  beforeCreateCallBack: this.base.editFlow.onBeforeCreate,
856
882
  skipParameterDialog: appComponent.getStartupMode() === StartupMode.AutoCreate, // In case the application was called with preferredMode=autoCreateWith, we want to skip the action parameter dialog
857
883
  createAtEnd: parameters.createAtEnd,
858
- creationMode: CreationMode.CreationRow
884
+ creationMode: CreationMode.CreationRow,
885
+ requestAtLeast: parameters.requestAtLeast
859
886
  },
860
887
  appComponent,
861
888
  this._getResourceModel(),
@@ -878,7 +905,7 @@ class EditFlow extends BaseControllerExtension {
878
905
  Log.trace("transient fast creation context deleted");
879
906
  });
880
907
  navigation = creationRowContext.delete("$direct");
881
- return await this.postDocumentCreation(Promise.all([creation, navigation]), listBinding);
908
+ return await this.postDocumentCreation(Promise.allSettled([creation, navigation]), listBinding);
882
909
  } catch (error: unknown) {
883
910
  // Reset busy indicator after a validation error
884
911
  if (BusyLocker.isLocked(this.base.getView().getModel("ui"))) {
@@ -898,6 +925,7 @@ class EditFlow extends BaseControllerExtension {
898
925
  * @param parameters.parentContext Parent context (for TreeTable)
899
926
  * @param parameters.data Intial data for creation
900
927
  * @param parameters.creationDialogFields Fields to be displayed in the creation dialog
928
+ * @param parameters.requestAtLeast Defines the list of properties that should be requested when creating the new document to avoid additional requests later on.
901
929
  * @param listBinding ODataListBinding where the document is created
902
930
  * @returns Promise resolves once the document has been created
903
931
  */
@@ -910,6 +938,7 @@ class EditFlow extends BaseControllerExtension {
910
938
  parentContext?: ODataV4Context;
911
939
  data?: object;
912
940
  creationDialogFields?: string[];
941
+ requestAtLeast?: string[];
913
942
  },
914
943
  listBinding: ODataListBinding
915
944
  ): Promise<void> {
@@ -965,7 +994,8 @@ class EditFlow extends BaseControllerExtension {
965
994
  creationMode: parameters.creationMode,
966
995
  parentContext: parameters.parentContext,
967
996
  data: parameters.data as Record<string, unknown>,
968
- creationDialogFields: parameters.creationDialogFields
997
+ creationDialogFields: parameters.creationDialogFields,
998
+ requestAtLeast: parameters.requestAtLeast
969
999
  },
970
1000
  this.getAppComponent(),
971
1001
  this._getResourceModel(),
@@ -976,7 +1006,7 @@ class EditFlow extends BaseControllerExtension {
976
1006
  if (!parameters.skipSideEffects) {
977
1007
  this.handleSideEffects(listBinding, creation);
978
1008
  }
979
- return this.postDocumentCreation(Promise.all([creation, this.syncTask(creation)]), listBinding);
1009
+ return this.postDocumentCreation(Promise.allSettled([creation, this.syncTask(creation)]), listBinding);
980
1010
  }
981
1011
 
982
1012
  /**
@@ -1093,16 +1123,27 @@ class EditFlow extends BaseControllerExtension {
1093
1123
 
1094
1124
  /**
1095
1125
  * Creates a deferred document.
1126
+ * @param parameters Contains the following attributes:
1127
+ * @param parameters.data Data to save on the new document
1128
+ * @param parameters.parentContext
1129
+ * @param parameters.requestAtLeast Defines the list of properties that should be requested when creating the new document to avoid additional requests later on.
1096
1130
  * @param listBinding ODataListBinding where the document has to be created
1097
- * @param parentContext Optional parent context when creating a node in TreeTable
1098
- * @param data
1099
1131
  * @returns Promise resolves once the navigation is done
1100
1132
  */
1101
- async createDeferredDocument(listBinding: ODataListBinding, parentContext?: ODataV4Context, data?: object): Promise<void> {
1133
+ async createDeferredDocument(
1134
+ parameters: { data?: object; parentContext?: ODataV4Context; requestAtLeast?: string[] },
1135
+ listBinding: ODataListBinding
1136
+ ): Promise<void> {
1102
1137
  const lockObject = this.getGlobalUIModel();
1103
1138
  BusyLocker.lock(lockObject);
1104
1139
  await this.getInternalRouting().navigateForwardToContext(listBinding, {
1105
- createOnNavigateParameters: { mode: "Deferred", parentContext, listBinding, data },
1140
+ createOnNavigateParameters: {
1141
+ mode: "Deferred",
1142
+ parentContext: parameters.parentContext,
1143
+ listBinding,
1144
+ data: parameters.data,
1145
+ requestAtLeast: parameters.requestAtLeast
1146
+ },
1106
1147
  editable: true,
1107
1148
  forceFocus: true
1108
1149
  });
@@ -1118,6 +1159,7 @@ class EditFlow extends BaseControllerExtension {
1118
1159
  * @param parameters.data Data to save on the new document
1119
1160
  * @param parameters.skipSideEffects The sideEffects are requested
1120
1161
  * @param parameters.parentContext
1162
+ * @param parameters.requestAtLeast Defines the list of properties that should be requested when creating the new document to avoid additional requests later on.
1121
1163
  * @param listBinding ODataListBinding where the document is created
1122
1164
  * @returns Promise resolves once the document has been created
1123
1165
  */
@@ -1129,6 +1171,7 @@ class EditFlow extends BaseControllerExtension {
1129
1171
  data?: Record<string, unknown>;
1130
1172
  skipSideEffects?: boolean;
1131
1173
  parentContext?: ODataV4Context;
1174
+ requestAtLeast?: string[];
1132
1175
  },
1133
1176
  listBinding: ODataListBinding
1134
1177
  ): Promise<void> {
@@ -1145,7 +1188,8 @@ class EditFlow extends BaseControllerExtension {
1145
1188
  ...{
1146
1189
  parentControl: this.getView(),
1147
1190
  beforeCreateCallBack: this.base.editFlow.onBeforeCreate,
1148
- skipParameterDialog: this.getAppComponent().getStartupMode() === StartupMode.AutoCreate // In case the application was called with preferredMode=autoCreateWith, we want to skip the action parameter dialog
1191
+ skipParameterDialog: this.getAppComponent().getStartupMode() === StartupMode.AutoCreate, // In case the application was called with preferredMode=autoCreateWith, we want to skip the action parameter dialog
1192
+ requestAtLeast: this._isFclEnabled() ? parameters.requestAtLeast : undefined // For fullscreen, we don't need to request extra properties as the table will be refreshed when navigating back with the DirtyState
1149
1193
  }
1150
1194
  },
1151
1195
  this.getAppComponent(),
@@ -1176,31 +1220,47 @@ class EditFlow extends BaseControllerExtension {
1176
1220
  forceFocus: true
1177
1221
  });
1178
1222
  } else {
1179
- navigation = creation.then(async (newDocumentContext) => {
1180
- if (!newDocumentContext) {
1181
- const coreResourceBundle = Library.getResourceBundleFor("sap.fe.core")!;
1223
+ const coreResourceBundle = Library.getResourceBundleFor("sap.fe.core")!;
1224
+ navigation = creation
1225
+ .then(async (newDocumentContext) => {
1226
+ if (!newDocumentContext) {
1227
+ return routingListener.navigateToMessagePage(coreResourceBundle.getText("C_COMMON_SAPFE_DATA_RECEIVED_ERROR"), {
1228
+ title: coreResourceBundle.getText("C_COMMON_SAPFE_ERROR"),
1229
+ description: coreResourceBundle.getText("C_EDITFLOW_SAPFE_CREATION_FAILED_DESCRIPTION")
1230
+ });
1231
+ } else {
1232
+ // In case the Sync creation was triggered for a deferred creation, we don't navigate forward
1233
+ // as we're already on the corresponding ObjectPage
1234
+ const navParameters: RoutingNavigationParameters = {
1235
+ editable: true,
1236
+ forceFocus: true,
1237
+ transient:
1238
+ this.getProgrammingModel(listBinding) == ProgrammingModel.Sticky || parameters.createAction
1239
+ ? true
1240
+ : undefined
1241
+ };
1242
+
1243
+ return parameters.bFromDeferred
1244
+ ? routingListener.navigateToContext(newDocumentContext, navParameters)
1245
+ : routingListener.navigateForwardToContext(newDocumentContext, navParameters);
1246
+ }
1247
+ })
1248
+ .catch(async (error: unknown) => {
1249
+ if (typeof error === "string" && error === Constants.CancelActionDialog) {
1250
+ // Creation has been cancelled by the user => no error message page
1251
+ throw error;
1252
+ }
1253
+ Log.error("Creation error: ", error as string);
1254
+ // Navigate to error message page in case of an error during creation or navigation
1182
1255
  return routingListener.navigateToMessagePage(coreResourceBundle.getText("C_COMMON_SAPFE_DATA_RECEIVED_ERROR"), {
1183
1256
  title: coreResourceBundle.getText("C_COMMON_SAPFE_ERROR"),
1184
- description: coreResourceBundle.getText("C_EDITFLOW_SAPFE_CREATION_FAILED_DESCRIPTION")
1257
+ description: coreResourceBundle.getText("C_EDITFLOW_SAPFE_CREATION_FAILED_DESCRIPTION"),
1258
+ showMessagePageOnCreateFailure: true
1185
1259
  });
1186
- } else {
1187
- // In case the Sync creation was triggered for a deferred creation, we don't navigate forward
1188
- // as we're already on the corresponding ObjectPage
1189
- const navParameters: RoutingNavigationParameters = {
1190
- editable: true,
1191
- forceFocus: true,
1192
- transient:
1193
- this.getProgrammingModel(listBinding) == ProgrammingModel.Sticky || parameters.createAction ? true : undefined
1194
- };
1195
-
1196
- return parameters.bFromDeferred
1197
- ? routingListener.navigateToContext(newDocumentContext, navParameters)
1198
- : routingListener.navigateForwardToContext(newDocumentContext, navParameters);
1199
- }
1200
- });
1260
+ });
1201
1261
  }
1202
1262
  try {
1203
- await this.postDocumentCreation(Promise.all([creation, navigation]), listBinding);
1263
+ await this.postDocumentCreation(Promise.allSettled([creation, navigation]), listBinding);
1204
1264
  } catch (error: unknown) {
1205
1265
  // TODO: currently, the only errors handled here are raised as string - should be changed to Error objects
1206
1266
  // creation has been cancelled by user or failed in backend => in case we have navigated to transient context before, navigate back