@sapui5/sap.fe.core 1.121.2 → 1.123.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 (241) hide show
  1. package/package.json +1 -1
  2. package/src/sap/fe/core/.library +1 -1
  3. package/src/sap/fe/core/ActionRuntime.js +2 -2
  4. package/src/sap/fe/core/ActionRuntime.ts +1 -2
  5. package/src/sap/fe/core/CommonUtils.js +14 -171
  6. package/src/sap/fe/core/CommonUtils.ts +15 -221
  7. package/src/sap/fe/core/PageController.js +13 -1
  8. package/src/sap/fe/core/PageController.ts +16 -0
  9. package/src/sap/fe/core/TemplateComponent.js +6 -1
  10. package/src/sap/fe/core/TemplateComponent.ts +8 -0
  11. package/src/sap/fe/core/UIProvider.js +23 -0
  12. package/src/sap/fe/core/UIProvider.ts +38 -0
  13. package/src/sap/fe/core/buildingBlocks/BuildingBlockBase.js +97 -43
  14. package/src/sap/fe/core/buildingBlocks/BuildingBlockBase.ts +120 -50
  15. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockSupport.js +6 -3
  16. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockSupport.ts +12 -18
  17. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplateProcessor.js +2 -2
  18. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplateProcessor.ts +1 -1
  19. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplatingBase.js +1 -1
  20. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplatingBase.ts +4 -3
  21. package/src/sap/fe/core/buildingBlocks/templating/RuntimeBuildingBlockFragment.js +1 -1
  22. package/src/sap/fe/core/buildingBlocks/templating/RuntimeBuildingBlockFragment.ts +1 -0
  23. package/src/sap/fe/core/controllerextensions/BaseControllerExtension.js +42 -1
  24. package/src/sap/fe/core/controllerextensions/BaseControllerExtension.ts +40 -0
  25. package/src/sap/fe/core/controllerextensions/CollaborativeDraft.js +5 -2
  26. package/src/sap/fe/core/controllerextensions/CollaborativeDraft.ts +5 -3
  27. package/src/sap/fe/core/controllerextensions/EditFlow.js +151 -60
  28. package/src/sap/fe/core/controllerextensions/EditFlow.ts +165 -68
  29. package/src/sap/fe/core/controllerextensions/HookSupport.js +32 -14
  30. package/src/sap/fe/core/controllerextensions/HookSupport.ts +35 -14
  31. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +5 -17
  32. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +0 -12
  33. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +6 -6
  34. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +15 -10
  35. package/src/sap/fe/core/controllerextensions/InternalRouting.js +108 -287
  36. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +117 -309
  37. package/src/sap/fe/core/controllerextensions/KPIManagement.js +2 -2
  38. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +6 -2
  39. package/src/sap/fe/core/controllerextensions/MessageHandler.js +2 -2
  40. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +1 -1
  41. package/src/sap/fe/core/controllerextensions/PageReady.js +6 -6
  42. package/src/sap/fe/core/controllerextensions/PageReady.ts +5 -4
  43. package/src/sap/fe/core/controllerextensions/Paginator.js +17 -110
  44. package/src/sap/fe/core/controllerextensions/Paginator.ts +13 -130
  45. package/src/sap/fe/core/controllerextensions/Placeholder.js +3 -3
  46. package/src/sap/fe/core/controllerextensions/Placeholder.ts +1 -2
  47. package/src/sap/fe/core/controllerextensions/Recommendations.js +36 -31
  48. package/src/sap/fe/core/controllerextensions/Recommendations.ts +32 -37
  49. package/src/sap/fe/core/controllerextensions/Share.js +7 -7
  50. package/src/sap/fe/core/controllerextensions/Share.ts +6 -6
  51. package/src/sap/fe/core/controllerextensions/SideEffects.js +52 -6
  52. package/src/sap/fe/core/controllerextensions/SideEffects.ts +56 -4
  53. package/src/sap/fe/core/controllerextensions/ViewState.js +32 -46
  54. package/src/sap/fe/core/controllerextensions/ViewState.ts +24 -31
  55. package/src/sap/fe/core/controllerextensions/dialog/OperationsDialog.block.js +42 -31
  56. package/src/sap/fe/core/controllerextensions/dialog/OperationsDialog.block.tsx +6 -0
  57. package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.js +168 -276
  58. package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.ts +182 -310
  59. package/src/sap/fe/core/controllerextensions/editFlow/draft.js +3 -3
  60. package/src/sap/fe/core/controllerextensions/editFlow/draft.ts +2 -2
  61. package/src/sap/fe/core/controllerextensions/editFlow/draftDataLossPopup.js +4 -3
  62. package/src/sap/fe/core/controllerextensions/editFlow/draftDataLossPopup.ts +3 -2
  63. package/src/sap/fe/core/controllerextensions/editFlow/operations/facade.js +74 -52
  64. package/src/sap/fe/core/controllerextensions/editFlow/operations/facade.ts +95 -55
  65. package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.js +3 -17
  66. package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.ts +10 -23
  67. package/src/sap/fe/core/controllerextensions/recommendations/Telemetry.js +3 -3
  68. package/src/sap/fe/core/controllerextensions/recommendations/Telemetry.ts +2 -2
  69. package/src/sap/fe/core/controllerextensions/routing/ContextPathHelper.js +225 -0
  70. package/src/sap/fe/core/controllerextensions/routing/ContextPathHelper.ts +241 -0
  71. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DraftDataLossDialog.block.js +69 -48
  72. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DraftDataLossDialog.block.tsx +56 -33
  73. package/src/sap/fe/core/controls/FormElementWrapper.js +8 -11
  74. package/src/sap/fe/core/controls/FormElementWrapper.ts +9 -0
  75. package/src/sap/fe/core/controls/Recommendations/ConfirmRecommendationDialog.block.js +6 -14
  76. package/src/sap/fe/core/controls/Recommendations/ConfirmRecommendationDialog.block.tsx +12 -23
  77. package/src/sap/fe/core/converters/ConverterContext.js +17 -9
  78. package/src/sap/fe/core/converters/ConverterContext.ts +55 -41
  79. package/src/sap/fe/core/converters/ManifestSettings.js +1 -1
  80. package/src/sap/fe/core/converters/ManifestSettings.ts +19 -5
  81. package/src/sap/fe/core/converters/ManifestWrapper.js +14 -4
  82. package/src/sap/fe/core/converters/ManifestWrapper.ts +21 -10
  83. package/src/sap/fe/core/converters/MetaModelConverter.js +402 -383
  84. package/src/sap/fe/core/converters/MetaModelConverter.ts +538 -338
  85. package/src/sap/fe/core/converters/TemplateConverter.js +4 -2
  86. package/src/sap/fe/core/converters/TemplateConverter.ts +18 -13
  87. package/src/sap/fe/core/converters/annotations/DataField.js +30 -28
  88. package/src/sap/fe/core/converters/annotations/DataField.ts +58 -35
  89. package/src/sap/fe/core/converters/common/AnnotationConverter.js +24 -23
  90. package/src/sap/fe/core/converters/controls/Common/Action.js +5 -4
  91. package/src/sap/fe/core/converters/controls/Common/Action.ts +34 -28
  92. package/src/sap/fe/core/converters/controls/Common/Chart.js +37 -33
  93. package/src/sap/fe/core/converters/controls/Common/Chart.ts +64 -46
  94. package/src/sap/fe/core/converters/controls/Common/DataVisualization.js +15 -4
  95. package/src/sap/fe/core/converters/controls/Common/DataVisualization.ts +31 -15
  96. package/src/sap/fe/core/converters/controls/Common/Form.js +6 -4
  97. package/src/sap/fe/core/converters/controls/Common/Form.ts +23 -11
  98. package/src/sap/fe/core/converters/controls/Common/KPI.js +5 -3
  99. package/src/sap/fe/core/converters/controls/Common/KPI.ts +17 -11
  100. package/src/sap/fe/core/converters/controls/Common/Table.js +197 -101
  101. package/src/sap/fe/core/converters/controls/Common/Table.ts +393 -182
  102. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +4 -5
  103. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +38 -27
  104. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +41 -11
  105. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +112 -45
  106. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.js +7 -7
  107. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.ts +18 -12
  108. package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.js +1 -1
  109. package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.ts +5 -4
  110. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +1 -1
  111. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +19 -9
  112. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +64 -63
  113. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +109 -100
  114. package/src/sap/fe/core/converters/helpers/Aggregation.js +12 -11
  115. package/src/sap/fe/core/converters/helpers/Aggregation.ts +35 -30
  116. package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +4 -1
  117. package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +12 -9
  118. package/src/sap/fe/core/converters/helpers/DataFieldHelper.js +1 -1
  119. package/src/sap/fe/core/converters/helpers/DataFieldHelper.ts +1 -1
  120. package/src/sap/fe/core/converters/helpers/ID.js +1 -1
  121. package/src/sap/fe/core/converters/helpers/ID.ts +6 -6
  122. package/src/sap/fe/core/converters/helpers/InsightsHelpers.js +3 -3
  123. package/src/sap/fe/core/converters/helpers/InsightsHelpers.ts +11 -6
  124. package/src/sap/fe/core/converters/helpers/Key.js +2 -2
  125. package/src/sap/fe/core/converters/helpers/Key.ts +4 -4
  126. package/src/sap/fe/core/converters/helpers/SelectionVariantHelper.js +1 -1
  127. package/src/sap/fe/core/converters/helpers/SelectionVariantHelper.ts +2 -2
  128. package/src/sap/fe/core/converters/objectPage/FormMenuActions.js +21 -19
  129. package/src/sap/fe/core/converters/objectPage/FormMenuActions.ts +43 -31
  130. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +1 -1
  131. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +16 -12
  132. package/src/sap/fe/core/converters/templates/ListReportConverter.js +8 -3
  133. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +41 -21
  134. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +5 -3
  135. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +24 -19
  136. package/src/sap/fe/core/designtime/AppComponent.designtime.js +3 -2
  137. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +2 -1
  138. package/src/sap/fe/core/filter/DraftEditState.fragment.xml +1 -1
  139. package/src/sap/fe/core/formatters/CollaborationFormatter.js +4 -6
  140. package/src/sap/fe/core/formatters/CollaborationFormatter.ts +5 -4
  141. package/src/sap/fe/core/formatters/FPMFormatter.js +5 -13
  142. package/src/sap/fe/core/formatters/FPMFormatter.ts +11 -10
  143. package/src/sap/fe/core/formatters/FiscalFormat.js +1 -1
  144. package/src/sap/fe/core/formatters/FiscalFormat.ts +1 -1
  145. package/src/sap/fe/core/formatters/KPIFormatter.js +4 -7
  146. package/src/sap/fe/core/formatters/KPIFormatter.ts +3 -3
  147. package/src/sap/fe/core/formatters/StandardFormatter.js +4 -7
  148. package/src/sap/fe/core/formatters/StandardFormatter.ts +3 -3
  149. package/src/sap/fe/core/formatters/ValueFormatter.js +35 -6
  150. package/src/sap/fe/core/formatters/ValueFormatter.ts +31 -3
  151. package/src/sap/fe/core/fpm/manifest.json +1 -1
  152. package/src/sap/fe/core/helpers/AppStartupHelper.js +54 -33
  153. package/src/sap/fe/core/helpers/AppStartupHelper.ts +62 -41
  154. package/src/sap/fe/core/helpers/BindingToolkit.js +17 -3
  155. package/src/sap/fe/core/helpers/BindingToolkit.ts +28 -6
  156. package/src/sap/fe/core/helpers/ClassSupport.js +32 -13
  157. package/src/sap/fe/core/helpers/ClassSupport.ts +35 -15
  158. package/src/sap/fe/core/helpers/DeleteHelper.js +71 -61
  159. package/src/sap/fe/core/helpers/DeleteHelper.ts +125 -103
  160. package/src/sap/fe/core/helpers/DraftEditState.js +5 -3
  161. package/src/sap/fe/core/helpers/DraftEditState.ts +3 -1
  162. package/src/sap/fe/core/helpers/FPMHelper.js +43 -46
  163. package/src/sap/fe/core/helpers/FPMHelper.ts +50 -56
  164. package/src/sap/fe/core/helpers/MetaModelFunction.js +77 -53
  165. package/src/sap/fe/core/helpers/MetaModelFunction.ts +78 -57
  166. package/src/sap/fe/core/helpers/ModelHelper.js +10 -4
  167. package/src/sap/fe/core/helpers/ModelHelper.ts +12 -6
  168. package/src/sap/fe/core/helpers/PasteHelper.js +194 -7
  169. package/src/sap/fe/core/helpers/PasteHelper.ts +265 -13
  170. package/src/sap/fe/core/helpers/PromiseKeeper.js +66 -0
  171. package/src/sap/fe/core/helpers/PromiseKeeper.ts +56 -0
  172. package/src/sap/fe/core/helpers/SemanticKeyHelper.js +30 -19
  173. package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +34 -22
  174. package/src/sap/fe/core/helpers/StableIdHelper.js +1 -1
  175. package/src/sap/fe/core/helpers/StableIdHelper.ts +7 -2
  176. package/src/sap/fe/core/helpers/StandardRecommendationHelper.js +26 -52
  177. package/src/sap/fe/core/helpers/StandardRecommendationHelper.ts +37 -63
  178. package/src/sap/fe/core/helpers/TitleHelper.js +1 -1
  179. package/src/sap/fe/core/helpers/TitleHelper.ts +17 -14
  180. package/src/sap/fe/core/helpers/TypeGuards.js +27 -3
  181. package/src/sap/fe/core/helpers/TypeGuards.ts +37 -7
  182. package/src/sap/fe/core/jsx-runtime/jsx-xml.js +48 -8
  183. package/src/sap/fe/core/jsx-runtime/jsx-xml.ts +40 -9
  184. package/src/sap/fe/core/library.js +1 -1
  185. package/src/sap/fe/core/messagebundle.properties +5 -2
  186. package/src/sap/fe/core/messagebundle_da.properties +1 -1
  187. package/src/sap/fe/core/messagebundle_en.properties +267 -2
  188. package/src/sap/fe/core/messagebundle_sl.properties +1 -1
  189. package/src/sap/fe/core/operationsHelper.js +2 -1
  190. package/src/sap/fe/core/operationsHelper.ts +1 -0
  191. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +3 -3
  192. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +2 -2
  193. package/src/sap/fe/core/services/NavigationServiceFactory.js +2 -2
  194. package/src/sap/fe/core/services/NavigationServiceFactory.ts +3 -2
  195. package/src/sap/fe/core/services/RoutingServiceFactory.js +27 -14
  196. package/src/sap/fe/core/services/RoutingServiceFactory.ts +27 -14
  197. package/src/sap/fe/core/services/ShellServicesFactory.js +49 -12
  198. package/src/sap/fe/core/services/ShellServicesFactory.ts +62 -13
  199. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +156 -82
  200. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +218 -100
  201. package/src/sap/fe/core/services/TelemetryServiceFactory.js +3 -3
  202. package/src/sap/fe/core/services/TelemetryServiceFactory.ts +6 -6
  203. package/src/sap/fe/core/services/ValueHelpHistoryServiceFactory.js +3 -2
  204. package/src/sap/fe/core/services/ValueHelpHistoryServiceFactory.ts +1 -1
  205. package/src/sap/fe/core/services/collaborativeDraftServiceFactory.js +1 -1
  206. package/src/sap/fe/core/services/collaborativeDraftServiceFactory.ts +2 -2
  207. package/src/sap/fe/core/services/view/TemplatingErrorPage.view.xml +1 -1
  208. package/src/sap/fe/core/templating/CommonFormatters.js +6 -3
  209. package/src/sap/fe/core/templating/CommonFormatters.ts +13 -12
  210. package/src/sap/fe/core/templating/CriticalityFormatters.js +2 -2
  211. package/src/sap/fe/core/templating/CriticalityFormatters.ts +37 -14
  212. package/src/sap/fe/core/templating/DataFieldFormatters.js +12 -11
  213. package/src/sap/fe/core/templating/DataFieldFormatters.ts +35 -24
  214. package/src/sap/fe/core/templating/DataModelPathHelper.js +22 -18
  215. package/src/sap/fe/core/templating/DataModelPathHelper.ts +61 -51
  216. package/src/sap/fe/core/templating/DisplayModeFormatter.js +1 -1
  217. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +8 -3
  218. package/src/sap/fe/core/templating/EntityTypeHelper.js +1 -1
  219. package/src/sap/fe/core/templating/EntityTypeHelper.ts +1 -1
  220. package/src/sap/fe/core/templating/FieldControlHelper.js +3 -3
  221. package/src/sap/fe/core/templating/FieldControlHelper.ts +27 -8
  222. package/src/sap/fe/core/templating/FilterHelper.js +13 -10
  223. package/src/sap/fe/core/templating/FilterHelper.ts +80 -46
  224. package/src/sap/fe/core/templating/FilterTemplating.js +1 -1
  225. package/src/sap/fe/core/templating/FilterTemplating.ts +2 -2
  226. package/src/sap/fe/core/templating/PropertyFormatters.js +6 -8
  227. package/src/sap/fe/core/templating/PropertyFormatters.ts +11 -11
  228. package/src/sap/fe/core/templating/PropertyHelper.js +3 -3
  229. package/src/sap/fe/core/templating/PropertyHelper.ts +4 -4
  230. package/src/sap/fe/core/templating/SemanticObjectHelper.js +157 -13
  231. package/src/sap/fe/core/templating/SemanticObjectHelper.ts +182 -16
  232. package/src/sap/fe/core/templating/UIFormatters.js +23 -22
  233. package/src/sap/fe/core/templating/UIFormatters.ts +94 -66
  234. package/src/sap/fe/core/type/DateTimeWithTimezone.js +1 -1
  235. package/src/sap/fe/core/type/DateTimeWithTimezone.ts +2 -2
  236. package/src/sap/fe/core/type/EDM.js +1 -1
  237. package/src/sap/fe/core/type/EDM.ts +2 -2
  238. package/src/sap/fe/core/type/Email.js +1 -1
  239. package/src/sap/fe/core/type/Email.ts +1 -1
  240. package/src/sap/fe/core/type/FiscalDate.js +2 -2
  241. package/src/sap/fe/core/type/FiscalDate.ts +2 -2
@@ -3,12 +3,12 @@ import type { LineItem } from "@sap-ux/vocabularies-types/vocabularies/UI";
3
3
  import Log from "sap/base/Log";
4
4
  import type ResourceBundle from "sap/base/i18n/ResourceBundle";
5
5
  import deepClone from "sap/base/util/deepClone";
6
- import type { ActionParameterInfo } from "sap/fe/core/ActionRuntime";
7
- import ActionRuntime from "sap/fe/core/ActionRuntime";
8
6
  import type AppComponent from "sap/fe/core/AppComponent";
9
7
  import type { FEView } from "sap/fe/core/BaseController";
10
8
  import CommonUtils from "sap/fe/core/CommonUtils";
11
9
  import type ResourceModel from "sap/fe/core/ResourceModel";
10
+ import type { ExitDialogEvent } from "sap/fe/core/UIProvider";
11
+ import { getCoreUIFactory } from "sap/fe/core/UIProvider";
12
12
  import BusyLocker from "sap/fe/core/controllerextensions/BusyLocker";
13
13
  import type MessageHandler from "sap/fe/core/controllerextensions/MessageHandler";
14
14
  import type { BindContextParameters } from "sap/fe/core/controllerextensions/editFlow/draft";
@@ -18,13 +18,15 @@ import operations from "sap/fe/core/controllerextensions/editFlow/operations";
18
18
  import sticky from "sap/fe/core/controllerextensions/editFlow/sticky";
19
19
  import messageHandling from "sap/fe/core/controllerextensions/messageHandler/messageHandling";
20
20
  import { getInvolvedDataModelObjects } from "sap/fe/core/converters/MetaModelConverter";
21
+ import { isDataFieldForAction } from "sap/fe/core/converters/annotations/DataField";
21
22
  import type { DeleteOption, DeleteParameters } from "sap/fe/core/helpers/DeleteHelper";
22
23
  import deleteHelper from "sap/fe/core/helpers/DeleteHelper";
23
24
  import FPMHelper from "sap/fe/core/helpers/FPMHelper";
25
+ import { getCreatePopupFields } from "sap/fe/core/helpers/MetaModelFunction";
24
26
  import type { InternalModelContext } from "sap/fe/core/helpers/ModelHelper";
25
27
  import ModelHelper from "sap/fe/core/helpers/ModelHelper";
26
- import { getResourceModel } from "sap/fe/core/helpers/ResourceModelHelper";
27
- import { generate } from "sap/fe/core/helpers/StableIdHelper";
28
+ import PromiseKeeper from "sap/fe/core/helpers/PromiseKeeper";
29
+ import toES6Promise from "sap/fe/core/helpers/ToES6Promise";
28
30
  import { isNavigationProperty } from "sap/fe/core/helpers/TypeGuards";
29
31
  import FELibrary from "sap/fe/core/library";
30
32
  import Button from "sap/m/Button";
@@ -36,31 +38,20 @@ import Popover from "sap/m/Popover";
36
38
  import Text from "sap/m/Text";
37
39
  import VBox from "sap/m/VBox";
38
40
  import type Event from "sap/ui/base/Event";
39
- import type ManagedObject from "sap/ui/base/ManagedObject";
40
41
  import type Control from "sap/ui/core/Control";
41
- import Fragment from "sap/ui/core/Fragment";
42
42
  import Library from "sap/ui/core/Lib";
43
43
  import Messaging from "sap/ui/core/Messaging";
44
- import XMLTemplateProcessor from "sap/ui/core/XMLTemplateProcessor";
45
44
  import coreLibrary from "sap/ui/core/library";
46
45
  import type Message from "sap/ui/core/message/Message";
47
46
  import type View from "sap/ui/core/mvc/View";
48
- import XMLPreprocessor from "sap/ui/core/util/XMLPreprocessor";
49
- import type FormElement from "sap/ui/layout/form/FormElement";
50
- import type Field from "sap/ui/mdc/Field";
51
- import type MultiValueField from "sap/ui/mdc/MultiValueField";
52
47
  import type MultiValueFieldItem from "sap/ui/mdc/field/MultiValueFieldItem";
53
48
  import type Binding from "sap/ui/model/Binding";
54
49
  import type Context from "sap/ui/model/Context";
55
- import JSONModel from "sap/ui/model/json/JSONModel";
56
50
  import type ODataV4Context from "sap/ui/model/odata/v4/Context";
57
51
  import type ODataListBinding from "sap/ui/model/odata/v4/ODataListBinding";
58
52
  import type { ODataListBinding$CreateCompletedEvent } from "sap/ui/model/odata/v4/ODataListBinding";
59
53
  import type ODataMetaModel from "sap/ui/model/odata/v4/ODataMetaModel";
60
54
  import type ODataModel from "sap/ui/model/odata/v4/ODataModel";
61
- import { isDataFieldForAction } from "../../converters/annotations/DataField";
62
- import { getNonComputedVisibleFields, getRequiredPropertiesFromInsertRestrictions } from "../../helpers/MetaModelFunction";
63
- import toES6Promise from "../../helpers/ToES6Promise";
64
55
 
65
56
  const CreationMode = FELibrary.CreationMode;
66
57
  const ProgrammingModel = FELibrary.ProgrammingModel;
@@ -222,12 +213,42 @@ class TransactionHelper {
222
213
  const dataForCreation = initialData ?? {};
223
214
 
224
215
  if (this.isListBindingHierarchical(listBinding)) {
216
+ let listBindingForCreation: ODataListBinding;
225
217
  if (options.parentContext?.isExpanded() === false) {
226
218
  // If the parent context already has children and is collapsed, we expand it first
227
219
  await listBinding.expand(options.parentContext);
228
220
  }
229
- Object.assign(dataForCreation, { "@$ui5.node.parent": options.parentContext });
230
- return listBinding.create(dataForCreation, true);
221
+
222
+ if (listBinding.isRelative()) {
223
+ Object.assign(dataForCreation, { "@$ui5.node.parent": options.parentContext });
224
+ listBindingForCreation = listBinding;
225
+ } else {
226
+ // Absolute binding: creation from the ListReport
227
+ // We use a temporary flat listBinding for the creation, to avoid adding the new context in the table (we don't want to display it until it's saved)
228
+ const model = listBinding.getModel();
229
+ const metaModel = model.getMetaModel();
230
+ listBindingForCreation = model.bindList(listBinding.getPath(), undefined, undefined, undefined, {
231
+ $$groupId: listBinding.getGroupId(),
232
+ $$updateGroupId: listBinding.getUpdateGroupId()
233
+ });
234
+
235
+ // Add the parent path in the initial data if a parent is provided
236
+ if (options.parentContext) {
237
+ const objectPath = getInvolvedDataModelObjects(metaModel.getMetaContext(listBinding.getPath()));
238
+ const hierarchyQualifier = (listBinding.getAggregation() as { hierarchyQualifier: string }).hierarchyQualifier;
239
+ const parentNavigation =
240
+ objectPath.targetEntityType.annotations.Aggregation?.[`RecursiveHierarchy#${hierarchyQualifier}`]
241
+ ?.ParentNavigationProperty.value;
242
+ if (!parentNavigation) {
243
+ throw new Error(`Cannot find parent navigation property for ${listBinding.getPath()}`);
244
+ }
245
+ const parentBindingData: Record<string, string> = {};
246
+ parentBindingData[`${parentNavigation}@odata.bind`] = options.parentContext.getPath().replace(/^\//, ""); // Remove leading "/" from the path
247
+ Object.assign(dataForCreation, parentBindingData);
248
+ }
249
+ }
250
+
251
+ return listBindingForCreation.create(dataForCreation, true);
231
252
  } else {
232
253
  return listBinding.create(dataForCreation, true, options.createAtEnd, options.createInactive);
233
254
  }
@@ -237,9 +258,9 @@ class TransactionHelper {
237
258
  const metaModel = listBinding.getModel().getMetaModel();
238
259
  const metaPath = metaModel.getMetaPath(listBinding.getHeaderContext()!.getPath());
239
260
 
240
- const nonComputedVisibleFields = getNonComputedVisibleFields(metaModel, metaPath, appComponent);
261
+ const nonComputedVisibleFields = getCreatePopupFields(metaModel, metaPath, appComponent);
241
262
  // Do not consider fields for which we provide some initial data
242
- return nonComputedVisibleFields.filter((fieldName) => {
263
+ return nonComputedVisibleFields.filter((fieldName: string) => {
243
264
  return !(fieldName in (createData ?? {}));
244
265
  });
245
266
  }
@@ -442,25 +463,24 @@ class TransactionHelper {
442
463
  ? this.getCreationParameters(mainListBinding, initialData, appComponent)
443
464
  : [];
444
465
  if (nonComputedVisibleKeyFields.length > 0) {
445
- const onKeyFieldResult = await this._launchDialogWithKeyFields(
466
+ newDocumentContext = await this.createWithDialog(
446
467
  mainListBinding,
447
468
  nonComputedVisibleKeyFields,
448
- model,
449
469
  parameters,
450
470
  appComponent,
451
471
  messageHandler
452
472
  );
453
- newDocumentContext = onKeyFieldResult.newContext;
454
473
  } else {
455
474
  newDocumentContext = await this.createDocumentContext(mainListBinding, parameters);
456
475
  if (!parameters.inactive) {
457
- await this.onAfterCreateCompletion(mainListBinding, newDocumentContext, parameters);
476
+ await this.waitForCreateCompletion(newDocumentContext, parameters.keepTransientContextOnFailed === true);
458
477
  }
459
478
  }
460
479
  return newDocumentContext;
461
480
  } catch (error: unknown) {
462
- Log.error("Error while creating the new document", error as string);
463
- throw error;
481
+ const msg = typeof error === "string" ? error : (error as Error).message ?? error;
482
+ Log.error("Error while creating the new document", msg);
483
+ throw msg;
464
484
  }
465
485
  }
466
486
  }
@@ -951,6 +971,7 @@ class TransactionHelper {
951
971
  * @param mParameters.internalModelContext
952
972
  * @param mParameters.groupId
953
973
  * @param mParameters.defaultValuesExtensionFunction
974
+ * @param [mParameters.ignoreETag] If specified, the action is called without ETag handling
954
975
  * @param oView Contains the object of the current view
955
976
  * @param appComponent The appComponent
956
977
  * @param messageHandler The message handler extension
@@ -979,6 +1000,7 @@ class TransactionHelper {
979
1000
  internalModelContext?: InternalModelContext | null;
980
1001
  groupId?: string;
981
1002
  defaultValuesExtensionFunction?: string;
1003
+ ignoreETag?: boolean;
982
1004
  },
983
1005
  oView: View | null,
984
1006
  appComponent: AppComponent,
@@ -1046,7 +1068,8 @@ class TransactionHelper {
1046
1068
  defaultValuesExtensionFunction: mParameters.defaultValuesExtensionFunction,
1047
1069
  selectedItems: mParameters.contexts as ODataV4Context[],
1048
1070
  disableStrictHandling,
1049
- groupId: mParameters.groupId
1071
+ groupId: mParameters.groupId,
1072
+ ignoreETag: mParameters.ignoreETag
1050
1073
  });
1051
1074
  } else {
1052
1075
  oResult = await operations.callActionImport(sActionName, oModel, appComponent, {
@@ -1055,6 +1078,7 @@ class TransactionHelper {
1055
1078
  skipParameterDialog: mParameters.skipParameterDialog,
1056
1079
  bindingParameters: mBindingParameters,
1057
1080
  entitySetName: mParameters.entitySetName,
1081
+ additionalSideEffect: mSideEffectsParameters,
1058
1082
  onSubmitted: () => {
1059
1083
  this.busyLock(appComponent);
1060
1084
  },
@@ -1065,7 +1089,8 @@ class TransactionHelper {
1065
1089
  internalModelContext: mParameters.internalModelContext,
1066
1090
  operationAvailableMap: mParameters.operationAvailableMap,
1067
1091
  messageHandler: messageHandler,
1068
- bObjectPage: mParameters.bObjectPage
1092
+ bObjectPage: mParameters.bObjectPage,
1093
+ ignoreETag: mParameters.ignoreETag
1069
1094
  });
1070
1095
  }
1071
1096
 
@@ -1191,11 +1216,10 @@ class TransactionHelper {
1191
1216
  });
1192
1217
  }
1193
1218
 
1194
- async _launchDialogWithKeyFields(
1195
- oListBinding: ODataListBinding,
1196
- mFields: string[],
1197
- oModel: ODataModel,
1198
- mParameters: {
1219
+ async createWithDialog(
1220
+ listBinding: ODataListBinding,
1221
+ fieldNames: string[],
1222
+ parameters: {
1199
1223
  parentControl?: Control;
1200
1224
  data?: Record<string, unknown>;
1201
1225
  bIsCreateDialog?: boolean;
@@ -1208,307 +1232,155 @@ class TransactionHelper {
1208
1232
  },
1209
1233
  appComponent: AppComponent,
1210
1234
  messageHandler: MessageHandler
1211
- ): Promise<{ newContext?: ODataV4Context }> {
1212
- let oDialog: Dialog;
1213
- const oParentControl = mParameters.parentControl;
1235
+ ): Promise<ODataV4Context> {
1236
+ const model = listBinding.getModel() as ODataModel;
1237
+ const metaModel = model.getMetaModel();
1238
+ const listMetaPath = metaModel.getMetaPath(listBinding.getResolvedPath()!);
1214
1239
 
1215
- // Crate a fake (transient) listBinding and context, just for the binding context of the dialog
1216
- const oTransientListBinding = oModel.bindList(oListBinding.getPath(), oListBinding.getContext(), [], [], {
1240
+ // Create a fake (transient) listBinding and context, just for the binding context of the dialog
1241
+ const transientListBinding = model.bindList(listBinding.getPath(), listBinding.getContext(), undefined, undefined, {
1217
1242
  $$updateGroupId: "submitLater"
1218
1243
  });
1219
- oTransientListBinding.refreshInternal = function (): void {
1244
+ transientListBinding.refreshInternal = function (): void {
1220
1245
  /* */
1221
1246
  };
1222
- const oTransientContext = oTransientListBinding.create(mParameters.data, true);
1223
-
1224
- return new Promise<{ newContext?: ODataV4Context }>(async (resolve, reject) => {
1225
- const sFragmentName = "sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog";
1226
- const oFragment = XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment"),
1227
- resourceModel = getResourceModel(oParentControl!),
1228
- oMetaModel = oModel.getMetaModel(),
1229
- aImmutableFields: Context[] = [],
1230
- sPath = (oListBinding.isRelative() ? oListBinding.getResolvedPath() : oListBinding.getPath()) as string,
1231
- oEntitySetContext = oMetaModel.createBindingContext(sPath) as Context,
1232
- sMetaPath = oMetaModel.getMetaPath(sPath);
1233
- for (const i in mFields) {
1234
- aImmutableFields.push(oMetaModel.createBindingContext(`${sMetaPath}/${mFields[i]}`)!);
1247
+ const transientContext = transientListBinding.create(parameters.data, true);
1248
+ const fieldMetaContexts = fieldNames.map((name) => {
1249
+ return metaModel.createBindingContext(`${listMetaPath}/${name}`) as Context;
1250
+ });
1251
+
1252
+ const createDialog = getCoreUIFactory().newCreateDialog(transientContext, fieldNames, appComponent, parameters.parentControl);
1253
+
1254
+ try {
1255
+ await CommonUtils.setUserDefaults(
1256
+ appComponent,
1257
+ fieldMetaContexts,
1258
+ transientContext,
1259
+ false,
1260
+ parameters.createAction,
1261
+ parameters.data
1262
+ );
1263
+ createDialog.openDialog();
1264
+ } catch (e) {
1265
+ await messageHandler.showMessages();
1266
+ throw e;
1267
+ }
1268
+
1269
+ const resultPromiseKeeper = new PromiseKeeper<ODataV4Context>();
1270
+
1271
+ const onExitDialog = async (event: ExitDialogEvent): Promise<void> => {
1272
+ if (!event.getParameter("accept")) {
1273
+ // User has cancelled creation: destry the transient list binding and close the dialog
1274
+ transientListBinding.destroy();
1275
+ createDialog.closeDialog();
1276
+ resultPromiseKeeper.reject(FELibrary.Constants.CancelActionDialog);
1277
+ return;
1235
1278
  }
1236
- const oImmutableCtxModel = new JSONModel(aImmutableFields);
1237
- const oImmutableCtx = oImmutableCtxModel.createBindingContext("/");
1238
- const aRequiredProperties = getRequiredPropertiesFromInsertRestrictions(sMetaPath, oMetaModel);
1239
- const oRequiredPropertyPathsCtxModel = new JSONModel(aRequiredProperties);
1240
- const oRequiredPropertyPathsCtx = oRequiredPropertyPathsCtxModel.createBindingContext("/");
1241
- const oNewFragment = await XMLPreprocessor.process(
1242
- oFragment,
1243
- { name: sFragmentName },
1244
- {
1245
- bindingContexts: {
1246
- entitySet: oEntitySetContext,
1247
- fields: oImmutableCtx,
1248
- requiredProperties: oRequiredPropertyPathsCtx
1249
- },
1250
- models: {
1251
- entitySet: oEntitySetContext.getModel(),
1252
- fields: oImmutableCtx.getModel(),
1253
- metaModel: oMetaModel,
1254
- requiredProperties: oRequiredPropertyPathsCtxModel
1279
+
1280
+ createDialog.setBusy(true);
1281
+ parameters.bIsCreateDialog = true;
1282
+ try {
1283
+ const transientData = transientContext.getObject();
1284
+ let createData: Record<string, unknown> = {};
1285
+ Object.keys(transientData).forEach((propertyPath) => {
1286
+ const oProperty = metaModel.getObject(`${listMetaPath}/${propertyPath}`);
1287
+ // Ensure navigation properties are not part of the payload, as deep create not supported
1288
+ // And remove any property starting by @$ui5 as they are not property created by filling the form
1289
+ if (oProperty && oProperty.$kind !== "NavigationProperty" && !propertyPath?.startsWith("@$ui5")) {
1290
+ createData[propertyPath] = transientData[propertyPath];
1255
1291
  }
1256
- }
1257
- );
1258
- const _removeMessagesForActionParamter = (messageControlId: string): void => {
1259
- const allMessages = Messaging.getMessageModel().getData();
1260
- // also remove messages assigned to inner controls, but avoid removing messages for different paramters (with name being substring of another parameter name)
1261
- const relevantMessages = allMessages.filter((msg: Message) =>
1262
- msg.getControlIds().some((controlId: string) => controlId.includes(messageControlId))
1263
- );
1264
- Messaging.removeMessages(relevantMessages);
1265
- };
1266
- let actionParameterInfos: ActionParameterInfo[];
1267
-
1268
- const oController = {
1269
- /*
1270
- fired on focus out from field or on selecting a value from the valuehelp.
1271
- the create button (Continue) is always enabled.
1272
- liveChange is not fired when value is added from valuehelp.
1273
- value validation is done for create button.
1274
- */
1275
- handleChange: async (event: Event<{ id: string; promise: Promise<string> }>): Promise<void> => {
1276
- const fieldId = event.getParameter("id");
1277
- const field = event.getSource();
1278
- const actionParameterInfo = actionParameterInfos.find(
1279
- (actionParameterInfo) => actionParameterInfo.field === field
1280
- ) as ActionParameterInfo;
1281
- _removeMessagesForActionParamter(fieldId);
1282
- actionParameterInfo.validationPromise = event.getParameter("promise");
1292
+ });
1293
+
1294
+ if (parameters.beforeCreateCallBack) {
1295
+ //beforeCreateCallBack expects createParameters of type any[]
1296
+ const createDataAsArray = Object.entries(createData).map(([key, value]) => ({ [key]: value }));
1283
1297
  try {
1284
- actionParameterInfo.value = await actionParameterInfo.validationPromise;
1285
- actionParameterInfo.hasError = false;
1298
+ await toES6Promise(
1299
+ parameters.beforeCreateCallBack({
1300
+ contextPath: listBinding.getPath(),
1301
+ createParameters: createDataAsArray
1302
+ })
1303
+ );
1286
1304
  } catch (error) {
1287
- delete actionParameterInfo.value;
1288
- actionParameterInfo.hasError = true;
1305
+ Log.error("Error while creating the new document", error as string);
1306
+ throw FELibrary.Constants.OnBeforeCreateFailed;
1289
1307
  }
1290
- },
1291
- /*
1292
- fired on key press. the create button the create button (Continue) is always enabled.
1293
- liveChange is not fired when value is added from valuehelp.
1294
- value validation is done for create button.
1295
- */
1296
- handleLiveChange: (event: Event<{ id: string }>): void => {
1297
- const fieldId = event.getParameter("id");
1298
- _removeMessagesForActionParamter(fieldId);
1308
+ createData = createDataAsArray.reduce((result, currentObject) => {
1309
+ return { ...result, ...currentObject };
1310
+ }, {});
1299
1311
  }
1300
- };
1301
-
1302
- const oDialogContent: Control = (await Fragment.load({
1303
- definition: oNewFragment as unknown as string,
1304
- controller: oController
1305
- })) as Control;
1306
- let oResult: { error: string } | { response: { newContext?: ODataV4Context } };
1307
- let isDialogConfirmed = false;
1308
- oDialog = new Dialog(generate(["CreateDialog", sMetaPath]), {
1309
- title: resourceModel.getText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE"),
1310
- content: [oDialogContent],
1311
- contentWidth: "20rem",
1312
- beginButton: new Button({
1313
- text: resourceModel.getText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE_BUTTON"),
1314
- type: "Emphasized",
1315
-
1316
- press: async (_Event: unknown): Promise<void> => {
1317
- /* Validation of mandatory and value state for action parameters */
1318
- if (!(await ActionRuntime.validateProperties(actionParameterInfos, resourceModel))) {
1319
- return;
1320
- }
1321
-
1322
- BusyLocker.lock(oDialog);
1323
- mParameters.bIsCreateDialog = true;
1324
- try {
1325
- const transientData = oTransientContext.getObject();
1326
- let createData: Record<string, unknown> = {};
1327
- Object.keys(transientData).forEach(function (sPropertyPath: string) {
1328
- const oProperty = oMetaModel.getObject(`${sMetaPath}/${sPropertyPath}`);
1329
- // ensure navigation properties are not part of the payload, deep create not supported
1330
- if (oProperty && oProperty.$kind === "NavigationProperty") {
1331
- return;
1332
- }
1333
- // Remove any property starting by @$ui5 as they are not property created by filling the form
1334
- if (sPropertyPath?.startsWith("@$ui5")) {
1335
- return;
1336
- }
1337
- createData[sPropertyPath] = transientData[sPropertyPath];
1338
- });
1339
- if (mParameters.beforeCreateCallBack) {
1340
- //beforeCreateCallBack expects createParameters of type any[]
1341
- const parameters = Object.entries(createData).map(([key, value]) => ({ [key]: value }));
1342
- try {
1343
- await toES6Promise(
1344
- mParameters.beforeCreateCallBack({
1345
- contextPath: oListBinding && oListBinding.getPath(),
1346
- createParameters: parameters
1347
- })
1348
- );
1349
- } catch (error) {
1350
- Log.error("Error while creating the new document", error as string);
1351
- throw FELibrary.Constants.OnBeforeCreateFailed;
1352
- }
1353
- createData = parameters.reduce((result, currentObject) => {
1354
- return { ...result, ...currentObject };
1355
- }, {});
1356
- }
1357
- if (Object.keys(createData).length > 0) {
1358
- appComponent.getModel("ui").setProperty(UiModelConstants.DocumentModified, true);
1359
- }
1360
- const oNewDocumentContext = await this.createContext(oListBinding, createData, {
1361
- createAtEnd: !!mParameters.createAtEnd,
1362
- createInactive: !!mParameters.inactive,
1363
- parentContext: mParameters.parentContext
1364
- });
1365
-
1366
- const oPromise = this.onAfterCreateCompletion(oListBinding, oNewDocumentContext, mParameters);
1367
- const promiseResponse = await oPromise;
1368
- if (!promiseResponse || !promiseResponse.bKeepDialogOpen) {
1369
- const oResponse: { newContext?: ODataV4Context } = promiseResponse ?? {};
1370
- oDialog.setBindingContext(null as unknown as ODataV4Context);
1371
- oResponse.newContext = oNewDocumentContext;
1372
- isDialogConfirmed = true;
1373
- oResult = { response: oResponse };
1374
- oDialog.close();
1375
- }
1376
- } catch (oError: unknown) {
1377
- // in case of creation failed, dialog should stay open - to achieve the same, nothing has to be done (like in case of success with bKeepDialogOpen)
1378
- if (oError !== FELibrary.Constants.CreationFailed && oError != FELibrary.Constants.OnBeforeCreateFailed) {
1379
- // other errors are not expected
1380
- oResult = { error: oError as string };
1381
- oDialog.close();
1382
- }
1383
- } finally {
1384
- BusyLocker.unlock(oDialog);
1385
- messageHandler.showMessages();
1386
- }
1387
- }
1388
- }),
1389
- endButton: new Button({
1390
- text: resourceModel.getText("C_COMMON_ACTION_PARAMETER_DIALOG_CANCEL"),
1391
- press: function (): void {
1392
- oResult = { error: FELibrary.Constants.CancelActionDialog };
1393
- oDialog.close();
1394
- }
1395
- }),
1396
- beforeClose: function (): void {
1397
- /* When the dialog is cancelled, messages need to be removed in case the same action should be executed again */
1398
- for (const actionParameterInfo of actionParameterInfos) {
1399
- const fieldId = actionParameterInfo.field.getId();
1400
- _removeMessagesForActionParamter(fieldId);
1401
- }
1402
- // show footer as per UX guidelines when dialog is not open
1403
- (oDialog.getBindingContext("internal") as InternalModelContext)?.setProperty("isCreateDialogOpen", false);
1404
- oDialog.destroy();
1405
- oTransientListBinding.destroy();
1406
- //rejected/resolved the promis returned by _launchDialogWithKeyFields
1407
- //as soon as the dialog is closed. Without waiting for the dialog's
1408
- //animation to finish
1409
- if (isDialogConfirmed) {
1410
- resolve((oResult as { response: { newContext?: ODataV4Context } }).response);
1411
- } else {
1412
- reject((oResult as { error: string })?.error ?? FELibrary.Constants.CancelActionDialog);
1413
- }
1312
+ if (Object.keys(createData).length > 0) {
1313
+ appComponent.getModel("ui").setProperty(UiModelConstants.DocumentModified, true);
1414
1314
  }
1415
- });
1416
- const aFormElements = (
1417
- (oDialogContent?.getAggregation("form") as ManagedObject).getAggregation("formContainers") as ManagedObject[]
1418
- )[0].getAggregation("formElements") as FormElement[];
1315
+ const newContext = await this.createContext(listBinding, createData, {
1316
+ createAtEnd: parameters.createAtEnd,
1317
+ createInactive: parameters.inactive,
1318
+ parentContext: parameters.parentContext
1319
+ });
1419
1320
 
1420
- if (oParentControl && oParentControl.addDependent) {
1421
- // if there is a parent control specified add the dialog as dependent
1422
- oParentControl.addDependent(oDialog);
1321
+ const creationSuccess = await this.waitForCreateCompletion(newContext, parameters.keepTransientContextOnFailed === true);
1322
+ if (creationSuccess) {
1323
+ transientListBinding.destroy();
1324
+ createDialog.closeDialog();
1325
+ resultPromiseKeeper.resolve(newContext);
1326
+ }
1327
+ } catch (error: unknown) {
1328
+ // in case of creation failed, dialog should stay open - to achieve the same, nothing has to be done (like in case of success with bKeepDialogOpen)
1329
+ if (error !== FELibrary.Constants.CreationFailed && error != FELibrary.Constants.OnBeforeCreateFailed) {
1330
+ // other errors are not expected
1331
+ transientListBinding.destroy();
1332
+ createDialog.closeDialog();
1333
+ resultPromiseKeeper.reject(error as string | Error);
1334
+ }
1335
+ } finally {
1336
+ createDialog.setBusy(false);
1337
+ messageHandler.showMessages();
1423
1338
  }
1339
+ };
1424
1340
 
1425
- oDialog.setBindingContext(oTransientContext);
1341
+ createDialog.attachExitDialog({}, onExitDialog);
1426
1342
 
1427
- try {
1428
- await CommonUtils.setUserDefaults(
1429
- appComponent,
1430
- aImmutableFields,
1431
- oTransientContext,
1432
- false,
1433
- mParameters.createAction,
1434
- mParameters.data
1435
- );
1436
- actionParameterInfos = aFormElements.map((parameterField): ActionParameterInfo => {
1437
- const field: Field | MultiValueField = parameterField.getFields()[0] as Field | MultiValueField;
1438
- const isMultiValue = field.isA<MultiValueField>("sap.ui.mdc.MultiValueField");
1439
- return {
1440
- parameter: parameterField,
1441
- isMultiValue: isMultiValue,
1442
- field: field,
1443
- value: isMultiValue ? field.getItems() : field.getValue(),
1444
- validationPromise: undefined,
1445
- hasError: false
1446
- };
1447
- });
1448
- // footer must not be visible when the dialog is open as per UX guidelines
1449
- (oDialog.getBindingContext("internal") as InternalModelContext).setProperty("isCreateDialogOpen", true);
1450
- oDialog.open();
1451
- } catch (oError: unknown) {
1452
- await messageHandler.showMessages();
1453
- throw oError;
1454
- }
1455
- });
1343
+ return resultPromiseKeeper.promise;
1456
1344
  }
1457
1345
 
1458
- async onAfterCreateCompletion(
1459
- oListBinding: ODataListBinding,
1460
- oNewDocumentContext: ODataV4Context,
1461
- mParameters: {
1462
- keepTransientContextOnFailed?: boolean;
1463
- }
1464
- ): Promise<{ bKeepDialogOpen: boolean; newContext?: ODataV4Context } | void> {
1465
- let fnResolve: Function;
1466
- const oPromise = new Promise<boolean>((resolve) => {
1467
- fnResolve = resolve;
1468
- });
1469
-
1470
- const fnCreateCompleted = (oEvent: ODataListBinding$CreateCompletedEvent): void => {
1471
- const oContext = oEvent.getParameter("context"),
1472
- bSuccess = oEvent.getParameter("success");
1473
- if (oContext === oNewDocumentContext) {
1474
- oListBinding.detachCreateCompleted(fnCreateCompleted, this);
1475
- fnResolve(bSuccess);
1346
+ /**
1347
+ * Waits for the creation of a context to be finished.
1348
+ *
1349
+ * @param newContext The context being created
1350
+ * @param keepTransientContextOnFailed
1351
+ * @returns True if the creation was successful
1352
+ */
1353
+ async waitForCreateCompletion(newContext: ODataV4Context, keepTransientContextOnFailed: boolean): Promise<boolean> {
1354
+ const promiseKeeper = new PromiseKeeper<boolean>();
1355
+ const parentListBinding = newContext.getBinding() as ODataListBinding;
1356
+
1357
+ const onCreateCompleted = (event: ODataListBinding$CreateCompletedEvent): void => {
1358
+ const createdContext = event.getParameter("context");
1359
+ const success = event.getParameter("success");
1360
+ if (createdContext === newContext) {
1361
+ parentListBinding.detachCreateCompleted(onCreateCompleted);
1362
+ promiseKeeper.resolve(success === true);
1476
1363
  }
1477
1364
  };
1478
- const fnSafeContextCreated = (): void => {
1479
- (oNewDocumentContext.created() ?? Promise.resolve())
1480
- .then(undefined, function () {
1481
- Log.trace("transient creation context deleted");
1482
- })
1483
- .catch(function (contextError: unknown) {
1365
+
1366
+ parentListBinding.attachCreateCompleted(onCreateCompleted);
1367
+
1368
+ const creationSuccessful = await promiseKeeper.promise;
1369
+ if (!creationSuccessful) {
1370
+ if (!keepTransientContextOnFailed) {
1371
+ // Cancel the pending POST and delete the context in the listBinding
1372
+ (newContext.created() ?? Promise.resolve()).catch(function (contextError: unknown) {
1484
1373
  Log.trace("transient creation context deletion error", contextError as string);
1485
1374
  });
1486
- };
1487
-
1488
- oListBinding.attachCreateCompleted(fnCreateCompleted, this);
1489
-
1490
- return oPromise.then(
1491
- async (
1492
- bSuccess: boolean
1493
- ): Promise<{
1494
- bKeepDialogOpen: boolean;
1495
- newContext?: ODataV4Context;
1496
- } | void> => {
1497
- if (!bSuccess) {
1498
- if (!mParameters.keepTransientContextOnFailed) {
1499
- // Cancel the pending POST and delete the context in the listBinding
1500
- fnSafeContextCreated(); // To avoid a 'request cancelled' error in the console
1501
- oListBinding.resetChanges();
1502
- oListBinding.getModel().resetChanges(oListBinding.getUpdateGroupId());
1503
-
1504
- throw FELibrary.Constants.CreationFailed;
1505
- }
1506
- return { bKeepDialogOpen: true };
1507
- } else {
1508
- return oNewDocumentContext.created();
1509
- }
1375
+ parentListBinding.resetChanges();
1376
+ parentListBinding.getModel().resetChanges(parentListBinding.getUpdateGroupId());
1377
+ throw FELibrary.Constants.CreationFailed;
1510
1378
  }
1511
- );
1379
+ return false;
1380
+ } else {
1381
+ await newContext.created();
1382
+ return true;
1383
+ }
1512
1384
  }
1513
1385
 
1514
1386
  /**