@sapui5/sap.fe.core 1.97.0 → 1.100.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 (306) hide show
  1. package/package.json +7 -4
  2. package/src/sap/fe/core/.library +1 -1
  3. package/src/sap/fe/core/AnnotationHelper.js +309 -405
  4. package/src/sap/fe/core/AnnotationHelper.ts +315 -0
  5. package/src/sap/fe/core/AppComponent.js +389 -397
  6. package/src/sap/fe/core/AppComponent.ts +403 -0
  7. package/src/sap/fe/core/AppStateHandler.js +198 -181
  8. package/src/sap/fe/core/AppStateHandler.ts +171 -0
  9. package/src/sap/fe/core/BaseController.js +83 -58
  10. package/src/sap/fe/core/BaseController.ts +68 -0
  11. package/src/sap/fe/core/BusyLocker.js +105 -121
  12. package/src/sap/fe/core/BusyLocker.ts +98 -0
  13. package/src/sap/fe/core/CommonUtils.js +2164 -2379
  14. package/src/sap/fe/core/CommonUtils.ts +2177 -0
  15. package/src/sap/fe/core/ExtensionAPI.js +279 -266
  16. package/src/sap/fe/core/ExtensionAPI.ts +250 -0
  17. package/src/sap/fe/core/PageController.js +218 -125
  18. package/src/sap/fe/core/PageController.ts +129 -0
  19. package/src/sap/fe/core/RouterProxy.js +924 -807
  20. package/src/sap/fe/core/RouterProxy.ts +840 -0
  21. package/src/sap/fe/core/Synchronization.js +41 -35
  22. package/src/sap/fe/core/Synchronization.ts +29 -0
  23. package/src/sap/fe/core/TemplateComponent.js +173 -155
  24. package/src/sap/fe/core/TemplateComponent.ts +173 -0
  25. package/src/sap/fe/core/TemplateModel.js +79 -54
  26. package/src/sap/fe/core/TemplateModel.ts +63 -0
  27. package/src/sap/fe/core/TransactionHelper.js +1560 -1579
  28. package/src/sap/fe/core/TransactionHelper.ts +1717 -0
  29. package/src/sap/fe/core/actions/collaboration/ActivitySync.js +392 -0
  30. package/src/sap/fe/core/actions/collaboration/ActivitySync.ts +355 -0
  31. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.js +136 -0
  32. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.ts +119 -0
  33. package/src/sap/fe/core/actions/collaboration/Manage.js +262 -0
  34. package/src/sap/fe/core/actions/collaboration/Manage.ts +244 -0
  35. package/src/sap/fe/core/actions/collaboration/ManageDialog.fragment.xml +103 -0
  36. package/src/sap/fe/core/actions/collaboration/UserDetails.fragment.xml +13 -0
  37. package/src/sap/fe/core/actions/draft.js +521 -581
  38. package/src/sap/fe/core/actions/draft.ts +566 -0
  39. package/src/sap/fe/core/actions/messageHandling.js +564 -511
  40. package/src/sap/fe/core/actions/messageHandling.ts +552 -0
  41. package/src/sap/fe/core/actions/nonDraft.js +17 -19
  42. package/src/sap/fe/core/actions/nonDraft.ts +12 -0
  43. package/src/sap/fe/core/actions/operations.js +1093 -1211
  44. package/src/sap/fe/core/actions/operations.ts +1192 -0
  45. package/src/sap/fe/core/actions/sticky.js +114 -104
  46. package/src/sap/fe/core/actions/sticky.ts +119 -0
  47. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +70 -66
  48. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.ts +65 -0
  49. package/src/sap/fe/core/controllerextensions/EditFlow.js +1594 -1701
  50. package/src/sap/fe/core/controllerextensions/EditFlow.ts +1672 -0
  51. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +80 -54
  52. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +61 -0
  53. package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +719 -505
  54. package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +783 -0
  55. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +797 -813
  56. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +803 -0
  57. package/src/sap/fe/core/controllerextensions/InternalRouting.js +1005 -973
  58. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +978 -0
  59. package/src/sap/fe/core/controllerextensions/KPIManagement.js +530 -476
  60. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +137 -46
  61. package/src/sap/fe/core/controllerextensions/MassEdit.js +144 -0
  62. package/src/sap/fe/core/controllerextensions/MassEdit.ts +156 -0
  63. package/src/sap/fe/core/controllerextensions/MessageHandler.js +234 -232
  64. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +225 -0
  65. package/src/sap/fe/core/controllerextensions/PageReady.js +302 -337
  66. package/src/sap/fe/core/controllerextensions/PageReady.ts +23 -17
  67. package/src/sap/fe/core/controllerextensions/Paginator.js +189 -148
  68. package/src/sap/fe/core/controllerextensions/Paginator.ts +163 -0
  69. package/src/sap/fe/core/controllerextensions/Placeholder.js +158 -146
  70. package/src/sap/fe/core/controllerextensions/Placeholder.ts +151 -0
  71. package/src/sap/fe/core/controllerextensions/Routing.js +145 -106
  72. package/src/sap/fe/core/controllerextensions/Routing.ts +132 -0
  73. package/src/sap/fe/core/controllerextensions/RoutingListener.js +8 -6
  74. package/src/sap/fe/core/controllerextensions/RoutingListener.ts +3 -0
  75. package/src/sap/fe/core/controllerextensions/Share.js +220 -244
  76. package/src/sap/fe/core/controllerextensions/Share.ts +231 -0
  77. package/src/sap/fe/core/controllerextensions/SideEffects.js +593 -634
  78. package/src/sap/fe/core/controllerextensions/SideEffects.ts +29 -27
  79. package/src/sap/fe/core/controllerextensions/ViewState.js +789 -806
  80. package/src/sap/fe/core/controllerextensions/ViewState.ts +805 -0
  81. package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +4 -3
  82. package/src/sap/fe/core/controls/ActionPartial.fragment.xml +2 -2
  83. package/src/sap/fe/core/controls/CommandExecution.js +68 -66
  84. package/src/sap/fe/core/controls/CommandExecution.ts +72 -0
  85. package/src/sap/fe/core/controls/ConditionalWrapper.js +91 -75
  86. package/src/sap/fe/core/controls/ConditionalWrapper.ts +83 -0
  87. package/src/sap/fe/core/controls/CustomQuickViewPage.js +131 -125
  88. package/src/sap/fe/core/controls/CustomQuickViewPage.ts +126 -0
  89. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +105 -110
  90. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +101 -0
  91. package/src/sap/fe/core/controls/FieldWrapper.js +122 -140
  92. package/src/sap/fe/core/controls/FieldWrapper.ts +115 -0
  93. package/src/sap/fe/core/controls/FilterBar.js +163 -159
  94. package/src/sap/fe/core/controls/FilterBar.ts +143 -0
  95. package/src/sap/fe/core/controls/FormElementWrapper.js +46 -44
  96. package/src/sap/fe/core/controls/FormElementWrapper.ts +40 -0
  97. package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +38 -42
  98. package/src/sap/fe/core/controls/MultiValueParameterDelegate.ts +31 -0
  99. package/src/sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog.fragment.xml +2 -1
  100. package/src/sap/fe/core/controls/filterbar/FilterContainer.js +127 -116
  101. package/src/sap/fe/core/controls/filterbar/FilterContainer.ts +98 -0
  102. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +242 -255
  103. package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +245 -0
  104. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +151 -141
  105. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +125 -0
  106. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +336 -322
  107. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +337 -0
  108. package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +106 -0
  109. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +79 -0
  110. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +70 -0
  111. package/src/sap/fe/core/converters/ConverterContext.js +348 -367
  112. package/src/sap/fe/core/converters/ConverterContext.ts +33 -19
  113. package/src/sap/fe/core/converters/ManifestSettings.js +12 -1
  114. package/src/sap/fe/core/converters/ManifestSettings.ts +16 -1
  115. package/src/sap/fe/core/converters/ManifestWrapper.js +354 -354
  116. package/src/sap/fe/core/converters/ManifestWrapper.ts +34 -6
  117. package/src/sap/fe/core/converters/MetaModelConverter.js +72 -9
  118. package/src/sap/fe/core/converters/MetaModelConverter.ts +75 -16
  119. package/src/sap/fe/core/converters/TemplateConverter.js +1 -1
  120. package/src/sap/fe/core/converters/TemplateConverter.ts +4 -3
  121. package/src/sap/fe/core/converters/annotations/DataField.js +28 -14
  122. package/src/sap/fe/core/converters/annotations/DataField.ts +38 -14
  123. package/src/sap/fe/core/converters/common/AnnotationConverter.js +33 -21
  124. package/src/sap/fe/core/converters/controls/Common/Action.js +11 -2
  125. package/src/sap/fe/core/converters/controls/Common/Action.ts +8 -2
  126. package/src/sap/fe/core/converters/controls/Common/Chart.js +5 -3
  127. package/src/sap/fe/core/converters/controls/Common/Chart.ts +11 -3
  128. package/src/sap/fe/core/converters/controls/Common/DataVisualization.js +3 -3
  129. package/src/sap/fe/core/converters/controls/Common/DataVisualization.ts +2 -2
  130. package/src/sap/fe/core/converters/controls/Common/Form.js +21 -11
  131. package/src/sap/fe/core/converters/controls/Common/Form.ts +28 -6
  132. package/src/sap/fe/core/converters/controls/Common/KPI.js +69 -4
  133. package/src/sap/fe/core/converters/controls/Common/KPI.ts +75 -2
  134. package/src/sap/fe/core/converters/controls/Common/Table.js +507 -408
  135. package/src/sap/fe/core/converters/controls/Common/Table.ts +618 -500
  136. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +592 -0
  137. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +718 -0
  138. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +465 -59
  139. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +462 -72
  140. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.js +2 -2
  141. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.ts +1 -1
  142. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +17 -9
  143. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +24 -9
  144. package/src/sap/fe/core/converters/helpers/Aggregation.js +118 -121
  145. package/src/sap/fe/core/converters/helpers/Aggregation.ts +28 -5
  146. package/src/sap/fe/core/converters/helpers/BindingHelper.js +20 -6
  147. package/src/sap/fe/core/converters/helpers/BindingHelper.ts +16 -4
  148. package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +12 -1
  149. package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +11 -0
  150. package/src/sap/fe/core/converters/helpers/IssueManager.js +7 -1
  151. package/src/sap/fe/core/converters/helpers/IssueManager.ts +6 -0
  152. package/src/sap/fe/core/converters/helpers/Key.js +42 -57
  153. package/src/sap/fe/core/converters/helpers/Key.ts +1 -1
  154. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +28 -7
  155. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +23 -6
  156. package/src/sap/fe/core/converters/templates/ListReportConverter.js +20 -7
  157. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +36 -14
  158. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +7 -5
  159. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +5 -1
  160. package/src/sap/fe/core/designtime/AppComponent.designtime.js +93 -90
  161. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +91 -0
  162. package/src/sap/fe/core/formatters/CollaborationFormatter.js +104 -0
  163. package/src/sap/fe/core/formatters/CollaborationFormatter.ts +60 -0
  164. package/src/sap/fe/core/formatters/CriticalityFormatter.js +1 -1
  165. package/src/sap/fe/core/formatters/CriticalityFormatter.ts +1 -1
  166. package/src/sap/fe/core/formatters/FPMFormatter.js +1 -1
  167. package/src/sap/fe/core/formatters/FPMFormatter.ts +4 -10
  168. package/src/sap/fe/core/formatters/KPIFormatter.js +1 -1
  169. package/src/sap/fe/core/formatters/KPIFormatter.ts +3 -1
  170. package/src/sap/fe/core/formatters/TableFormatter.js +91 -29
  171. package/src/sap/fe/core/formatters/TableFormatter.ts +94 -28
  172. package/src/sap/fe/core/formatters/ValueFormatter.js +30 -5
  173. package/src/sap/fe/core/formatters/ValueFormatter.ts +30 -7
  174. package/src/sap/fe/core/fpm/Component.js +51 -54
  175. package/src/sap/fe/core/fpm/Component.ts +48 -0
  176. package/src/sap/fe/core/helpers/AppStartupHelper.js +373 -0
  177. package/src/sap/fe/core/helpers/AppStartupHelper.ts +417 -0
  178. package/src/sap/fe/core/helpers/BindingExpression.js +489 -442
  179. package/src/sap/fe/core/helpers/BindingExpression.ts +486 -469
  180. package/src/sap/fe/core/helpers/ClassSupport.js +212 -76
  181. package/src/sap/fe/core/helpers/ClassSupport.ts +198 -71
  182. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +64 -59
  183. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +52 -0
  184. package/src/sap/fe/core/helpers/EditState.js +81 -84
  185. package/src/sap/fe/core/helpers/EditState.ts +81 -0
  186. package/src/sap/fe/core/helpers/ExcelFormatHelper.js +62 -48
  187. package/src/sap/fe/core/helpers/ExcelFormatHelper.ts +49 -0
  188. package/src/sap/fe/core/helpers/FPMHelper.js +52 -56
  189. package/src/sap/fe/core/helpers/FPMHelper.ts +62 -0
  190. package/src/sap/fe/core/helpers/KeepAliveHelper.js +4 -5
  191. package/src/sap/fe/core/helpers/KeepAliveHelper.ts +10 -10
  192. package/src/sap/fe/core/helpers/MassEditHelper.js +604 -0
  193. package/src/sap/fe/core/helpers/MassEditHelper.ts +699 -0
  194. package/src/sap/fe/core/helpers/ModelHelper.js +253 -225
  195. package/src/sap/fe/core/helpers/ModelHelper.ts +250 -0
  196. package/src/sap/fe/core/helpers/PasteHelper.js +210 -132
  197. package/src/sap/fe/core/helpers/PasteHelper.ts +196 -0
  198. package/src/sap/fe/core/helpers/SemanticDateOperators.js +336 -313
  199. package/src/sap/fe/core/helpers/SemanticDateOperators.ts +334 -0
  200. package/src/sap/fe/core/helpers/SemanticKeyHelper.js +66 -67
  201. package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +73 -0
  202. package/src/sap/fe/core/helpers/StableIdHelper.js +4 -7
  203. package/src/sap/fe/core/helpers/StableIdHelper.ts +2 -6
  204. package/src/sap/fe/core/jsx-runtime/jsx.js +1 -1
  205. package/src/sap/fe/core/jsx-runtime/jsx.ts +1 -1
  206. package/src/sap/fe/core/library.js +427 -425
  207. package/src/sap/fe/core/library.support.js +23 -27
  208. package/src/sap/fe/core/library.support.ts +23 -0
  209. package/src/sap/fe/core/library.ts +420 -0
  210. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +64 -0
  211. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +69 -0
  212. package/src/sap/fe/core/messagebundle.properties +78 -13
  213. package/src/sap/fe/core/messagebundle_ar.properties +58 -7
  214. package/src/sap/fe/core/messagebundle_bg.properties +58 -7
  215. package/src/sap/fe/core/messagebundle_ca.properties +58 -7
  216. package/src/sap/fe/core/messagebundle_cs.properties +59 -8
  217. package/src/sap/fe/core/messagebundle_cy.properties +58 -7
  218. package/src/sap/fe/core/messagebundle_da.properties +58 -7
  219. package/src/sap/fe/core/messagebundle_de.properties +58 -7
  220. package/src/sap/fe/core/messagebundle_el.properties +58 -7
  221. package/src/sap/fe/core/messagebundle_en.properties +57 -6
  222. package/src/sap/fe/core/messagebundle_en_GB.properties +57 -6
  223. package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +61 -6
  224. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +58 -7
  225. package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +58 -7
  226. package/src/sap/fe/core/messagebundle_es.properties +58 -7
  227. package/src/sap/fe/core/messagebundle_es_MX.properties +58 -7
  228. package/src/sap/fe/core/messagebundle_et.properties +58 -7
  229. package/src/sap/fe/core/messagebundle_fi.properties +60 -9
  230. package/src/sap/fe/core/messagebundle_fr.properties +64 -13
  231. package/src/sap/fe/core/messagebundle_fr_CA.properties +59 -8
  232. package/src/sap/fe/core/messagebundle_hi.properties +58 -7
  233. package/src/sap/fe/core/messagebundle_hr.properties +58 -7
  234. package/src/sap/fe/core/messagebundle_hu.properties +59 -8
  235. package/src/sap/fe/core/messagebundle_id.properties +61 -10
  236. package/src/sap/fe/core/messagebundle_it.properties +58 -7
  237. package/src/sap/fe/core/messagebundle_iw.properties +58 -7
  238. package/src/sap/fe/core/messagebundle_ja.properties +58 -7
  239. package/src/sap/fe/core/messagebundle_kk.properties +58 -7
  240. package/src/sap/fe/core/messagebundle_ko.properties +58 -7
  241. package/src/sap/fe/core/messagebundle_lt.properties +58 -7
  242. package/src/sap/fe/core/messagebundle_lv.properties +59 -8
  243. package/src/sap/fe/core/messagebundle_ms.properties +58 -7
  244. package/src/sap/fe/core/messagebundle_nl.properties +58 -7
  245. package/src/sap/fe/core/messagebundle_no.properties +58 -7
  246. package/src/sap/fe/core/messagebundle_pl.properties +58 -7
  247. package/src/sap/fe/core/messagebundle_pt.properties +59 -8
  248. package/src/sap/fe/core/messagebundle_pt_PT.properties +58 -7
  249. package/src/sap/fe/core/messagebundle_ro.properties +58 -7
  250. package/src/sap/fe/core/messagebundle_ru.properties +58 -7
  251. package/src/sap/fe/core/messagebundle_sh.properties +58 -7
  252. package/src/sap/fe/core/messagebundle_sk.properties +58 -7
  253. package/src/sap/fe/core/messagebundle_sl.properties +58 -7
  254. package/src/sap/fe/core/messagebundle_sv.properties +59 -8
  255. package/src/sap/fe/core/messagebundle_th.properties +58 -7
  256. package/src/sap/fe/core/messagebundle_tr.properties +60 -9
  257. package/src/sap/fe/core/messagebundle_uk.properties +58 -7
  258. package/src/sap/fe/core/messagebundle_vi.properties +58 -7
  259. package/src/sap/fe/core/messagebundle_zh_CN.properties +58 -7
  260. package/src/sap/fe/core/messagebundle_zh_TW.properties +58 -7
  261. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +45 -71
  262. package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +3 -1
  263. package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +231 -202
  264. package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +212 -0
  265. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +67 -92
  266. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +10 -6
  267. package/src/sap/fe/core/services/NavigationServiceFactory.js +351 -300
  268. package/src/sap/fe/core/services/NavigationServiceFactory.ts +313 -0
  269. package/src/sap/fe/core/services/ResourceModelServiceFactory.js +114 -81
  270. package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +83 -0
  271. package/src/sap/fe/core/services/RoutingServiceFactory.js +927 -1152
  272. package/src/sap/fe/core/services/RoutingServiceFactory.ts +898 -0
  273. package/src/sap/fe/core/services/ShellServicesFactory.js +649 -707
  274. package/src/sap/fe/core/services/ShellServicesFactory.ts +52 -15
  275. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +569 -637
  276. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +78 -102
  277. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +429 -478
  278. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +460 -0
  279. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +10 -8
  280. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +8 -0
  281. package/src/sap/fe/core/support/AnnotationIssue.support.js +15 -3
  282. package/src/sap/fe/core/support/AnnotationIssue.support.ts +16 -2
  283. package/src/sap/fe/core/support/CollectionFacetUnsupportedLevel.support.js +2 -2
  284. package/src/sap/fe/core/support/CollectionFacetUnsupportedLevel.support.ts +1 -1
  285. package/src/sap/fe/core/support/CommonHelper.js +1 -1
  286. package/src/sap/fe/core/support/CommonHelper.ts +1 -1
  287. package/src/sap/fe/core/support/Diagnostics.js +36 -48
  288. package/src/sap/fe/core/support/InvalidAnnotationColumnKey.support.js +38 -0
  289. package/src/sap/fe/core/support/InvalidAnnotationColumnKey.support.ts +18 -0
  290. package/src/sap/fe/core/templating/DataModelPathHelper.js +97 -127
  291. package/src/sap/fe/core/templating/DataModelPathHelper.ts +112 -135
  292. package/src/sap/fe/core/templating/DisplayModeFormatter.js +114 -0
  293. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +86 -0
  294. package/src/sap/fe/core/templating/FieldControlHelper.js +8 -8
  295. package/src/sap/fe/core/templating/FieldControlHelper.ts +25 -7
  296. package/src/sap/fe/core/templating/FilterHelper.js +140 -78
  297. package/src/sap/fe/core/templating/FilterHelper.ts +149 -78
  298. package/src/sap/fe/core/templating/PropertyHelper.js +3 -3
  299. package/src/sap/fe/core/templating/PropertyHelper.ts +2 -2
  300. package/src/sap/fe/core/templating/UIFormatters.js +76 -135
  301. package/src/sap/fe/core/templating/UIFormatters.ts +76 -99
  302. package/src/sap/fe/core/type/Email.js +1 -1
  303. package/src/sap/fe/core/type/Email.ts +4 -6
  304. package/ui5.yaml +0 -3
  305. package/src/sap/fe/core/controls/filterbar.d.js +0 -8
  306. package/src/sap/fe/core/controls/filterbar.d.ts +0 -0
@@ -0,0 +1,1717 @@
1
+ import draft from "sap/fe/core/actions/draft";
2
+ import sticky from "sap/fe/core/actions/sticky";
3
+ import operations from "sap/fe/core/actions/operations";
4
+ import JSONModel from "sap/ui/model/json/JSONModel";
5
+ import Popover from "sap/m/Popover";
6
+ import VBox from "sap/m/VBox";
7
+ import CheckBox from "sap/m/CheckBox";
8
+ import Text from "sap/m/Text";
9
+ import Button from "sap/m/Button";
10
+ import MessageToast from "sap/m/MessageToast";
11
+ import Dialog from "sap/m/Dialog";
12
+ import Log from "sap/base/Log";
13
+ import CommonUtils from "sap/fe/core/CommonUtils";
14
+ import BusyLocker from "sap/fe/core/BusyLocker";
15
+ import XMLPreprocessor from "sap/ui/core/util/XMLPreprocessor";
16
+ import XMLTemplateProcessor from "sap/ui/core/XMLTemplateProcessor";
17
+ import Fragment from "sap/ui/core/Fragment";
18
+ import MessageBox from "sap/m/MessageBox";
19
+ import ModelHelper, { InternalModelContext } from "sap/fe/core/helpers/ModelHelper";
20
+ import FELibrary from "sap/fe/core/library";
21
+ import coreLibrary from "sap/ui/core/library";
22
+ import messageHandling from "sap/fe/core/actions/messageHandling";
23
+ import AppComponent from "sap/fe/core/AppComponent";
24
+ import ResourceBundle from "sap/base/i18n/ResourceBundle";
25
+ import ODataMetaModel from "sap/ui/model/odata/v4/ODataMetaModel";
26
+ import View from "sap/ui/core/mvc/View";
27
+ import FPMHelper from "sap/fe/core/helpers/FPMHelper";
28
+
29
+ import Context from "sap/ui/model/Context";
30
+ const CreationMode = FELibrary.CreationMode;
31
+ const ProgrammingModel = FELibrary.ProgrammingModel;
32
+ const ValueState = coreLibrary.ValueState;
33
+ /* Make sure that the mParameters is not the oEvent */
34
+ function getParameters(mParameters: any) {
35
+ if (mParameters && mParameters.getMetadata && mParameters.getMetadata().getName() === "sap.ui.base.Event") {
36
+ mParameters = {};
37
+ }
38
+ return mParameters || {};
39
+ }
40
+
41
+ class TransactionHelper {
42
+ _oAppComponent: AppComponent;
43
+ oLockObject: any;
44
+ sProgrammingModel?: typeof ProgrammingModel;
45
+ _bIsModified: boolean = false;
46
+ _bCreateMode: boolean = false;
47
+ _bContinueDiscard: boolean = false;
48
+ _oPopover!: Popover;
49
+ constructor(oAppComponent: AppComponent, oLockObject: any) {
50
+ this._oAppComponent = oAppComponent;
51
+ this.oLockObject = oLockObject;
52
+ }
53
+ getProgrammingModel(oContext: any): typeof ProgrammingModel {
54
+ if (!this.sProgrammingModel && oContext) {
55
+ let sPath;
56
+ if (oContext.isA("sap.ui.model.odata.v4.Context")) {
57
+ sPath = oContext.getPath();
58
+ } else {
59
+ sPath = oContext.isRelative() ? oContext.getResolvedPath() : oContext.getPath();
60
+ }
61
+ if (ModelHelper.isDraftSupported(oContext.getModel().getMetaModel(), sPath)) {
62
+ this.sProgrammingModel = ProgrammingModel.Draft;
63
+ } else if (ModelHelper.isStickySessionSupported(oContext.getModel().getMetaModel())) {
64
+ this.sProgrammingModel = ProgrammingModel.Sticky;
65
+ } else {
66
+ // as the transaction helper is a singleton we don't store the non draft as the user could
67
+ // start with a non draft child page and navigates back to a draft enabled one
68
+ return ProgrammingModel.NonDraft;
69
+ }
70
+ }
71
+ return this.sProgrammingModel as typeof ProgrammingModel;
72
+ }
73
+
74
+ /**
75
+ * Validates a document.
76
+ *
77
+ * @memberof sap.fe.core.TransactionHelper
78
+ * @static
79
+ * @param {sap.ui.model.odata.v4.Context} oContext Context of the document to be validated
80
+ * @param {object} [mParameters] Can contain the following attributes:
81
+ * * @param {object} [mParameters.data] A map of data that should be validated
82
+ * * @param {string} [mParameters.customValidationFunction] A string representing the path to the validation function
83
+ * @param {object} oView Contains the object of the current view
84
+ * @returns {Promise} Promise resolves with result of the custom validation function
85
+ * @ui5-restricted
86
+ * @final
87
+ */
88
+ validateDocument(oContext: any, mParameters: any, oView: View): Promise<any> {
89
+ const sCustomValidationFunction = mParameters && mParameters.customValidationFunction;
90
+ if (sCustomValidationFunction) {
91
+ const sModule = sCustomValidationFunction.substring(0, sCustomValidationFunction.lastIndexOf(".") || -1).replace(/\./gi, "/"),
92
+ sFunctionName = sCustomValidationFunction.substring(
93
+ sCustomValidationFunction.lastIndexOf(".") + 1,
94
+ sCustomValidationFunction.length
95
+ ),
96
+ mData = mParameters.data;
97
+ delete mData["@$ui5.context.isTransient"];
98
+ return FPMHelper.validationWrapper(sModule, sFunctionName, mData, oView, oContext);
99
+ }
100
+ return Promise.resolve([]);
101
+ }
102
+
103
+ /**
104
+ * Creates a new document.
105
+ *
106
+ * @memberof sap.fe.core.TransactionHelper
107
+ * @static
108
+ * @param {sap.ui.model.odata.v4.ODataListBinding} oMainListBinding OData V4 ListBinding object
109
+ * @param {object} [mInParameters] Optional, can contain the following attributes:
110
+ * @param {map} [mInParameters.data] A map of data that should be sent within the POST
111
+ * @param {string} [mInParameters.busyMode] Global (default), Local, None TODO: to be refactored
112
+ * @param {map} [mInParameters.keepTransientContextOnFailed] If set, the context stays in the list if the POST failed and POST will be repeated with the next change
113
+ * @param oResourceBundle
114
+ * @param messageHandler
115
+ * @param bFromCopyPaste
116
+ * @param oView The current view
117
+ * @returns {Promise} Promise resolves with new binding context
118
+ * @ui5-restricted
119
+ * @final
120
+ */
121
+ createDocument(
122
+ oMainListBinding: any,
123
+ mInParameters: { data?: any; busyMode?: string | undefined; keepTransientContextOnFailed?: any } | undefined,
124
+ oResourceBundle: any,
125
+ messageHandler: any,
126
+ bFromCopyPaste: boolean = false,
127
+ oView: any
128
+ ) {
129
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
130
+ const that = this,
131
+ oModel = oMainListBinding.getModel(),
132
+ oMetaModel = oModel.getMetaModel(),
133
+ sMetaPath = oMetaModel.getMetaPath(oMainListBinding.getHeaderContext().getPath()),
134
+ sCreateHash = this._getAppComponent()
135
+ .getRouterProxy()
136
+ .getHash(),
137
+ oComponentData = this._getAppComponent().getComponentData(),
138
+ oStartupParameters = (oComponentData && oComponentData.startupParameters) || {},
139
+ sNewAction = !oMainListBinding.isRelative()
140
+ ? this._getNewAction(oStartupParameters, sCreateHash, oMetaModel, sMetaPath)
141
+ : undefined;
142
+ let oCreationPromise;
143
+ const mBindingParameters: any = { "$$patchWithoutSideEffects": true };
144
+ const sMessagesPath = oMetaModel.getObject(sMetaPath + "/@com.sap.vocabularies.Common.v1.Messages/$Path");
145
+ let sBusyPath = "/busy";
146
+ let sFunctionName =
147
+ oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DefaultValuesFunction") ||
148
+ oMetaModel.getObject(
149
+ ModelHelper.getTargetEntitySet(oMetaModel.getContext(sMetaPath)) + "@com.sap.vocabularies.Common.v1.DefaultValuesFunction"
150
+ );
151
+ let bFunctionOnNavProp;
152
+ let oNewDocumentContext: any;
153
+ if (sFunctionName) {
154
+ if (
155
+ oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DefaultValuesFunction") &&
156
+ ModelHelper.getTargetEntitySet(oMetaModel.getContext(sMetaPath)) !== sMetaPath
157
+ ) {
158
+ bFunctionOnNavProp = true;
159
+ } else {
160
+ bFunctionOnNavProp = false;
161
+ }
162
+ }
163
+ if (sMessagesPath) {
164
+ mBindingParameters["$select"] = sMessagesPath;
165
+ }
166
+ const mParameters = getParameters(mInParameters);
167
+ if (!oMainListBinding) {
168
+ return Promise.reject("Binding required for new document creation");
169
+ }
170
+ const sProgrammingModel = this.getProgrammingModel(oMainListBinding);
171
+ if (sProgrammingModel !== ProgrammingModel.Draft && sProgrammingModel !== ProgrammingModel.Sticky) {
172
+ return Promise.reject("Create document only allowed for draft or sticky session supported services");
173
+ }
174
+ if (mParameters.busyMode === "Local") {
175
+ // in case of local busy mode we use the list binding name
176
+ // there's no APY yet so we have to use the .sId TODO provide a public method?
177
+ sBusyPath = "/busyLocal/" + oMainListBinding.sId;
178
+ }
179
+ mParameters.beforeCreateCallBack = bFromCopyPaste ? null : mParameters.beforeCreateCallBack;
180
+ BusyLocker.lock(this.oLockObject, sBusyPath);
181
+ const oResourceBundleCore = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core");
182
+ if (sNewAction) {
183
+ oCreationPromise = this.callAction(
184
+ sNewAction,
185
+ {
186
+ contexts: oMainListBinding.getHeaderContext(),
187
+ showActionParameterDialog: true,
188
+ label: this._getSpecificCreateActionDialogLabel(
189
+ oMetaModel,
190
+ sMetaPath,
191
+ sNewAction,
192
+ oResourceBundleCore as ResourceBundle
193
+ ),
194
+ bindingParameters: mBindingParameters,
195
+ parentControl: mParameters.parentControl,
196
+ bIsCreateAction: true
197
+ },
198
+ null,
199
+ messageHandler
200
+ );
201
+ } else {
202
+ const bIsNewPageCreation =
203
+ mParameters.creationMode !== CreationMode.CreationRow && mParameters.creationMode !== CreationMode.Inline;
204
+ const aNonComputedVisibleKeyFields = bIsNewPageCreation
205
+ ? CommonUtils.getNonComputedVisibleFields(oMetaModel, sMetaPath, oView)
206
+ : [];
207
+ sFunctionName = bFromCopyPaste ? null : sFunctionName;
208
+ let sFunctionPath, oFunctionContext;
209
+ if (sFunctionName) {
210
+ //bound to the source entity:
211
+ if (bFunctionOnNavProp) {
212
+ sFunctionPath =
213
+ oMainListBinding.getContext() &&
214
+ oMetaModel.getMetaPath(oMainListBinding.getContext().getPath()) + "/" + sFunctionName;
215
+ oFunctionContext = oMainListBinding.getContext();
216
+ } else {
217
+ sFunctionPath =
218
+ oMainListBinding.getHeaderContext() &&
219
+ oMetaModel.getMetaPath(oMainListBinding.getHeaderContext().getPath()) + "/" + sFunctionName;
220
+ oFunctionContext = oMainListBinding.getHeaderContext();
221
+ }
222
+ }
223
+ const oFunction = sFunctionPath && oMetaModel.createBindingContext(sFunctionPath);
224
+ if (oFunction && oFunction.getObject() && oFunction.getObject()[0].$IsBound) {
225
+ oCreationPromise = operations.callBoundFunction(sFunctionName, oFunctionContext, oModel);
226
+ } else {
227
+ oCreationPromise = operations.callFunctionImport(sFunctionName, oModel);
228
+ }
229
+
230
+ oCreationPromise = oCreationPromise
231
+ .then(function(oContext: any) {
232
+ if (oContext) {
233
+ return oContext.getObject();
234
+ } else {
235
+ return undefined;
236
+ }
237
+ })
238
+ .catch(function(oError: any) {
239
+ Log.error("Error while executing the function " + sFunctionName, oError);
240
+ throw oError;
241
+ })
242
+ .then(function(oData: any) {
243
+ mParameters.data = oData ? Object.assign({}, oData, mParameters.data) : mParameters.data;
244
+ if (mParameters.data) {
245
+ delete mParameters.data["@odata.context"];
246
+ }
247
+ if (aNonComputedVisibleKeyFields.length > 0) {
248
+ const oTransientListBinding = oModel.bindList(oMainListBinding.getPath(), oMainListBinding.getContext(), [], [], {
249
+ $$updateGroupId: "submitLater"
250
+ });
251
+ oTransientListBinding.refreshInternal = function() {
252
+ /* */
253
+ };
254
+ oNewDocumentContext = oTransientListBinding.create(mParameters.data, true);
255
+ return that._launchDialogWithKeyFields(
256
+ oMainListBinding,
257
+ oTransientListBinding,
258
+ oNewDocumentContext,
259
+ aNonComputedVisibleKeyFields,
260
+ oModel,
261
+ mParameters,
262
+ messageHandler
263
+ );
264
+ } else {
265
+ let onBeforeCreatePromise;
266
+ if (mParameters.beforeCreateCallBack) {
267
+ onBeforeCreatePromise = mParameters.beforeCreateCallBack({
268
+ contextPath: oMainListBinding && oMainListBinding.getPath()
269
+ });
270
+ } else {
271
+ onBeforeCreatePromise = Promise.resolve();
272
+ }
273
+ return onBeforeCreatePromise.then(function() {
274
+ oNewDocumentContext = oMainListBinding.create(mParameters.data, true, mParameters.createAtEnd);
275
+ return that.onAfterCreateCompletion(oMainListBinding, oNewDocumentContext, mParameters);
276
+ });
277
+ }
278
+ })
279
+ .catch(function(oError: any) {
280
+ Log.error("Error while creating the new document", oError);
281
+ throw oError;
282
+ });
283
+ }
284
+ return oCreationPromise
285
+ .then(function(oResult: any) {
286
+ if (!oMainListBinding.isRelative()) {
287
+ // the create mode shall currently only be set on creating a root document
288
+ that._bCreateMode = true;
289
+ }
290
+ oNewDocumentContext = oNewDocumentContext || (oResult && oResult.response);
291
+ // TODO: where does this one coming from???
292
+ if (oResult && oResult.bConsiderDocumentModified) {
293
+ that.handleDocumentModifications();
294
+ }
295
+ return messageHandler.showMessageDialog().then(function() {
296
+ return oNewDocumentContext;
297
+ });
298
+ })
299
+ .catch(function(oError: any) {
300
+ return messageHandler.showMessageDialog().then(function() {
301
+ // for instance, on cancel of create dialog, the promise is rejected
302
+ // a return here would restore the promise chain and result in errors while routing
303
+ // solution - reject here as well
304
+ if (oError && oError.bDeleteTransientContext && oNewDocumentContext.isTransient()) {
305
+ // This is a workaround suggested by model as Context.delete results in an error
306
+ // TODO: remove the $direct once model resolves this issue
307
+ // this line shows the expected console error Uncaught (in promise) Error: Request canceled: POST Travel; group: submitLater
308
+ oNewDocumentContext.delete("$direct");
309
+ }
310
+ return Promise.reject(oError);
311
+ });
312
+ })
313
+ .finally(function() {
314
+ BusyLocker.unlock(that.oLockObject, sBusyPath);
315
+ });
316
+ }
317
+ /**
318
+ * Find the active contexts of the documents, only for the draft roots.
319
+ *
320
+ * @memberof sap.fe.core.TransactionHelper
321
+ * @static
322
+ * @param {sap.ui.model.odata.v4.Context[]} aContexts Contexts Either one context or an array with contexts to be deleted
323
+ * @param bFindActiveContexts
324
+ * @returns {Array} Array of the active contexts
325
+ */
326
+ findActiveDraftRootContexts(aContexts: any[], bFindActiveContexts: any) {
327
+ if (!bFindActiveContexts) {
328
+ return Promise.resolve();
329
+ }
330
+ const activeContexts = aContexts.reduce(function(aResult: any, oContext: any) {
331
+ const oMetaModel = oContext.getModel().getMetaModel();
332
+ const sMetaPath = oMetaModel.getMetaPath(oContext.getPath());
333
+ if (oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DraftRoot")) {
334
+ const bIsActiveEntity = oContext.getObject().IsActiveEntity,
335
+ bHasActiveEntity = oContext.getObject().HasActiveEntity;
336
+ if (!bIsActiveEntity && bHasActiveEntity) {
337
+ const oActiveContext = oContext
338
+ .getModel()
339
+ .bindContext(oContext.getPath() + "/SiblingEntity")
340
+ .getBoundContext();
341
+ aResult.push(oActiveContext);
342
+ }
343
+ }
344
+ return aResult;
345
+ }, []);
346
+ return Promise.all(
347
+ activeContexts.map(function(oContext: any) {
348
+ return oContext.requestCanonicalPath().then(
349
+ function() {
350
+ return oContext;
351
+ },
352
+ function() {
353
+ return;
354
+ }
355
+ );
356
+ })
357
+ );
358
+ }
359
+ afterDeleteProcess(mParameters: any, checkBox: any, aContexts: any, oResourceBundle: any) {
360
+ const oInternalModelContext = mParameters.internalModelContext;
361
+ if (oInternalModelContext && oInternalModelContext.getProperty("deleteEnabled") != undefined) {
362
+ if (checkBox.isCheckBoxVisible === true && checkBox.isCheckBoxSelected === false) {
363
+ //if unsaved objects are not deleted then we need to set the enabled to true and update the model data for next deletion
364
+ oInternalModelContext.setProperty("deleteEnabled", true);
365
+ const obj = Object.assign(oInternalModelContext.getObject(), {});
366
+ obj.selectedContexts = obj.selectedContexts.filter(function(element: any) {
367
+ return obj.deletableContexts.indexOf(element) === -1;
368
+ });
369
+ obj.deletableContexts = [];
370
+ obj.selectedContexts = [];
371
+ obj.numberOfSelectedContexts = obj.selectedContexts.length;
372
+ oInternalModelContext.setProperty("", obj);
373
+ } else {
374
+ oInternalModelContext.setProperty("deleteEnabled", false);
375
+ oInternalModelContext.setProperty("selectedContexts", []);
376
+ oInternalModelContext.setProperty("numberOfSelectedContexts", 0);
377
+ }
378
+ }
379
+ if (aContexts.length === 1) {
380
+ MessageToast.show(
381
+ CommonUtils.getTranslatedText(
382
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_DELETE_TOAST_SINGULAR",
383
+ oResourceBundle,
384
+ null,
385
+ mParameters.entitySetName
386
+ )
387
+ );
388
+ } else {
389
+ MessageToast.show(
390
+ CommonUtils.getTranslatedText(
391
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_DELETE_TOAST_PLURAL",
392
+ oResourceBundle,
393
+ null,
394
+ mParameters.entitySetName
395
+ )
396
+ );
397
+ }
398
+ }
399
+ /**
400
+ * Delete one or multiple document(s).
401
+ *
402
+ * @memberof sap.fe.core.TransactionHelper
403
+ * @static
404
+ * @param {sap.ui.model.odata.v4.Context} vContexts Contexts Either one context or an array with contexts to be deleted
405
+ * @param {object} mParameters Optional, can contain the following attributes:
406
+ * @param {string} mParameters.title Title of the object to be deleted
407
+ * @param {string} mParameters.description Description of the object to be deleted
408
+ * @param {integer} mParameters.numberOfSelectedContexts Number of objects selected
409
+ * @param {boolean} mParameters.noDialog To disable the confirmation dialog
410
+ * @param oResourceBundle
411
+ * @param messageHandler
412
+ * @returns {Promise}
413
+ */
414
+ deleteDocument(vContexts: any, mParameters: any, oResourceBundle: any, messageHandler: any) {
415
+ let fnReject: Function,
416
+ fnResolve: Function,
417
+ aDeletableContexts: any[] = [],
418
+ isCheckBoxVisible = false,
419
+ isLockedTextVisible = false,
420
+ cannotBeDeletedTextVisible = false,
421
+ isCheckBoxSelected: boolean,
422
+ bDialogConfirmed = false;
423
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
424
+ const that = this,
425
+ oResourceBundleCore = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core") as ResourceBundle;
426
+ let aParams;
427
+ let oDeleteMessage: any = {
428
+ title: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE")
429
+ };
430
+ BusyLocker.lock(this.oLockObject);
431
+ if (!Array.isArray(vContexts)) {
432
+ vContexts = [vContexts];
433
+ }
434
+ Promise.resolve(this.getProgrammingModel(vContexts[0]))
435
+ .then(function(sProgrammingModel: any) {
436
+ if (mParameters) {
437
+ if (!mParameters.numberOfSelectedContexts) {
438
+ if (sProgrammingModel === ProgrammingModel.Draft) {
439
+ for (let i = 0; i < vContexts.length; i++) {
440
+ const oContextData = vContexts[i].getObject();
441
+ if (
442
+ oContextData.IsActiveEntity === true &&
443
+ oContextData.HasDraftEntity === true &&
444
+ oContextData.DraftAdministrativeData &&
445
+ oContextData.DraftAdministrativeData.InProcessByUser &&
446
+ !oContextData.DraftAdministrativeData.DraftIsCreatedByMe
447
+ ) {
448
+ MessageBox.show(
449
+ CommonUtils.getTranslatedText(
450
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_SINGLE_OBJECT_LOCKED",
451
+ oResourceBundle
452
+ ),
453
+ {
454
+ title: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE"),
455
+ onClose: fnReject
456
+ }
457
+ );
458
+ return;
459
+ }
460
+ }
461
+ }
462
+ mParameters = getParameters(mParameters);
463
+ if (mParameters.title) {
464
+ if (mParameters.description) {
465
+ aParams = [mParameters.title, mParameters.description];
466
+ } else {
467
+ aParams = [mParameters.title, ""];
468
+ }
469
+ oDeleteMessage.text = CommonUtils.getTranslatedText(
470
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO",
471
+ oResourceBundle,
472
+ aParams,
473
+ mParameters.entitySetName
474
+ );
475
+ } else {
476
+ oDeleteMessage.text = CommonUtils.getTranslatedText(
477
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR",
478
+ oResourceBundle
479
+ );
480
+ }
481
+ aDeletableContexts = vContexts;
482
+ } else {
483
+ oDeleteMessage = {
484
+ title: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE")
485
+ };
486
+ if (mParameters.numberOfSelectedContexts === 1 && mParameters.numberOfSelectedContexts === vContexts.length) {
487
+ aDeletableContexts = vContexts;
488
+ oDeleteMessage.text = CommonUtils.getTranslatedText(
489
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR",
490
+ oResourceBundle,
491
+ null,
492
+ mParameters.entitySetName
493
+ );
494
+ } else if (mParameters.numberOfSelectedContexts === 1 && mParameters.unSavedContexts.length === 1) {
495
+ //only one unsaved object
496
+ aDeletableContexts = mParameters.unSavedContexts;
497
+ const draftAdminData = aDeletableContexts[0].getObject()["DraftAdministrativeData"];
498
+ let sLastChangedByUser = "";
499
+ if (draftAdminData) {
500
+ sLastChangedByUser =
501
+ draftAdminData["LastChangedByUserDescription"] || draftAdminData["LastChangedByUser"] || "";
502
+ }
503
+ aParams = [sLastChangedByUser];
504
+ oDeleteMessage.text = CommonUtils.getTranslatedText(
505
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_CHANGES",
506
+ oResourceBundle,
507
+ aParams
508
+ );
509
+ } else if (mParameters.numberOfSelectedContexts === mParameters.unSavedContexts.length) {
510
+ //only multiple unsaved objects
511
+ aDeletableContexts = mParameters.unSavedContexts;
512
+ oDeleteMessage.text = CommonUtils.getTranslatedText(
513
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_CHANGES_MULTIPLE_OBJECTS",
514
+ oResourceBundle
515
+ );
516
+ } else if (
517
+ mParameters.numberOfSelectedContexts ===
518
+ vContexts.concat(mParameters.unSavedContexts.concat(mParameters.lockedContexts)).length
519
+ ) {
520
+ //only unsaved, locked ,deletable objects but not non-deletable objects
521
+ aDeletableContexts = vContexts.concat(mParameters.unSavedContexts);
522
+ oDeleteMessage.text =
523
+ aDeletableContexts.length === 1
524
+ ? CommonUtils.getTranslatedText(
525
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR",
526
+ oResourceBundle,
527
+ null,
528
+ mParameters.entitySetName
529
+ )
530
+ : CommonUtils.getTranslatedText(
531
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_PLURAL",
532
+ oResourceBundle,
533
+ null,
534
+ mParameters.entitySetName
535
+ );
536
+ } else {
537
+ //if non-deletable objects exists along with any of unsaved ,deletable objects
538
+ aDeletableContexts = vContexts.concat(mParameters.unSavedContexts);
539
+ cannotBeDeletedTextVisible = true;
540
+ oDeleteMessage.text =
541
+ aDeletableContexts.length === 1
542
+ ? CommonUtils.getTranslatedText(
543
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR_NON_DELETABLE",
544
+ oResourceBundle,
545
+ null,
546
+ mParameters.entitySetName
547
+ )
548
+ : CommonUtils.getTranslatedText(
549
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_PLURAL_NON_DELETABLE",
550
+ oResourceBundle,
551
+ null,
552
+ mParameters.entitySetName
553
+ );
554
+ oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText(
555
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_NON_DELETABLE",
556
+ oResourceBundle,
557
+ [
558
+ mParameters.numberOfSelectedContexts - vContexts.concat(mParameters.unSavedContexts).length,
559
+ mParameters.numberOfSelectedContexts
560
+ ]
561
+ );
562
+ }
563
+ if (mParameters.lockedContexts.length == 1) {
564
+ //setting the locked text if locked objects exist
565
+ isLockedTextVisible = true;
566
+ oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText(
567
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_ONE_OBJECT_LOCKED",
568
+ oResourceBundle,
569
+ [mParameters.numberOfSelectedContexts]
570
+ );
571
+ }
572
+ if (mParameters.lockedContexts.length > 1) {
573
+ //setting the locked text if locked objects exist
574
+ isLockedTextVisible = true;
575
+ oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText(
576
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_LOCKED",
577
+ oResourceBundle,
578
+ [mParameters.lockedContexts.length, mParameters.numberOfSelectedContexts]
579
+ );
580
+ }
581
+ if (
582
+ mParameters.unSavedContexts.length > 0 &&
583
+ mParameters.unSavedContexts.length !== mParameters.numberOfSelectedContexts
584
+ ) {
585
+ if (
586
+ (cannotBeDeletedTextVisible || isLockedTextVisible) &&
587
+ aDeletableContexts.length === mParameters.unSavedContexts.length
588
+ ) {
589
+ //if only unsaved and either or both of locked and non-deletable objects exist then we hide the check box
590
+ isCheckBoxVisible = false;
591
+ aDeletableContexts = mParameters.unSavedContexts;
592
+ if (mParameters.unSavedContexts.length === 1) {
593
+ oDeleteMessage.text = CommonUtils.getTranslatedText(
594
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_AND_FEW_OBJECTS_LOCKED_SINGULAR",
595
+ oResourceBundle
596
+ );
597
+ } else {
598
+ oDeleteMessage.text = CommonUtils.getTranslatedText(
599
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_UNSAVED_AND_FEW_OBJECTS_LOCKED_PLURAL",
600
+ oResourceBundle
601
+ );
602
+ }
603
+ } else {
604
+ if (mParameters.unSavedContexts.length === 1) {
605
+ oDeleteMessage.checkBoxText = CommonUtils.getTranslatedText(
606
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_UNSAVED_SINGULAR",
607
+ oResourceBundle
608
+ );
609
+ } else {
610
+ oDeleteMessage.checkBoxText = CommonUtils.getTranslatedText(
611
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_UNSAVED_PLURAL",
612
+ oResourceBundle
613
+ );
614
+ }
615
+ isCheckBoxVisible = true;
616
+ }
617
+ }
618
+ if (cannotBeDeletedTextVisible && isLockedTextVisible) {
619
+ //if both locked and non-deletable objects exist along with deletable objects
620
+ if (mParameters.unSavedContexts.length > 1) {
621
+ oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText(
622
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_FEW_OBJECTS_LOCKED_AND_NON_DELETABLE",
623
+ oResourceBundle,
624
+ [
625
+ mParameters.numberOfSelectedContexts -
626
+ vContexts.concat(mParameters.unSavedContexts).length -
627
+ mParameters.lockedContexts.length,
628
+ mParameters.lockedContexts.length,
629
+ mParameters.numberOfSelectedContexts
630
+ ]
631
+ );
632
+ }
633
+ if (mParameters.unSavedContexts.length == 1) {
634
+ oDeleteMessage.nonDeletableText = CommonUtils.getTranslatedText(
635
+ "C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTINFO_AND_ONE_OBJECT_LOCKED_AND_NON_DELETABLE",
636
+ oResourceBundle,
637
+ [
638
+ mParameters.numberOfSelectedContexts -
639
+ vContexts.concat(mParameters.unSavedContexts).length -
640
+ mParameters.lockedContexts.length,
641
+ mParameters.numberOfSelectedContexts
642
+ ]
643
+ );
644
+ }
645
+ }
646
+ }
647
+ }
648
+ let oNonDeletableMessageTextControl, oDeleteMessageTextControl;
649
+ const oContent = new VBox({
650
+ items: [
651
+ (oNonDeletableMessageTextControl = new Text({
652
+ text: oDeleteMessage.nonDeletableText,
653
+ visible: isLockedTextVisible || cannotBeDeletedTextVisible
654
+ })),
655
+ (oDeleteMessageTextControl = new Text({
656
+ text: oDeleteMessage.text
657
+ })),
658
+ new CheckBox({
659
+ text: oDeleteMessage.checkBoxText,
660
+ selected: true,
661
+ select: function(oEvent: any) {
662
+ const selected = oEvent.getSource().getSelected();
663
+ if (selected) {
664
+ aDeletableContexts = vContexts.concat(mParameters.unSavedContexts);
665
+ isCheckBoxSelected = true;
666
+ } else {
667
+ aDeletableContexts = vContexts;
668
+ isCheckBoxSelected = false;
669
+ }
670
+ },
671
+ visible: isCheckBoxVisible
672
+ })
673
+ ]
674
+ });
675
+ const sTitle = oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE");
676
+ const fnConfirm = function() {
677
+ bDialogConfirmed = true;
678
+ BusyLocker.lock(that.oLockObject);
679
+ const aContexts = aDeletableContexts;
680
+ let onBeforeDeletePromise;
681
+ if (mParameters.beforeDeleteCallBack) {
682
+ onBeforeDeletePromise = mParameters.beforeDeleteCallBack({ contexts: aContexts });
683
+ } else {
684
+ onBeforeDeletePromise = Promise.resolve();
685
+ }
686
+ return onBeforeDeletePromise
687
+ .then(that.findActiveDraftRootContexts.bind(that, aContexts, mParameters.bFindActiveContexts))
688
+ .then(function(activeContexts: any) {
689
+ //make sure to fetch the active contexts before deleting the drafts
690
+ return Promise.all(
691
+ aContexts.map(function(oContext: any) {
692
+ //delete the draft
693
+ return draft.deleteDraft(oContext);
694
+ })
695
+ )
696
+ .catch(function(oError: any) {
697
+ return messageHandler.showMessages().then(function() {
698
+ // re-throw error to enforce rejecting the general promise
699
+ throw oError;
700
+ });
701
+ })
702
+ .then(function() {
703
+ const checkBox = {
704
+ "isCheckBoxVisible": isCheckBoxVisible,
705
+ "isCheckBoxSelected": isCheckBoxSelected
706
+ };
707
+ if (activeContexts && activeContexts.length) {
708
+ return Promise.all(
709
+ activeContexts.map(function(oContext: any) {
710
+ return oContext.delete();
711
+ })
712
+ ).then(function() {
713
+ that.afterDeleteProcess(mParameters, checkBox, aContexts, oResourceBundle);
714
+ return messageHandler.showMessageDialog().then(fnResolve);
715
+ });
716
+ } else {
717
+ that.afterDeleteProcess(mParameters, checkBox, aContexts, oResourceBundle);
718
+ return messageHandler.showMessageDialog().then(fnResolve);
719
+ }
720
+ });
721
+ })
722
+ .catch(function() {
723
+ fnReject();
724
+ })
725
+ .finally(function() {
726
+ BusyLocker.unlock(that.oLockObject);
727
+ });
728
+ };
729
+ const oDialog = new Dialog({
730
+ title: sTitle,
731
+ state: "Warning",
732
+ content: [oContent],
733
+ ariaLabelledBy: oNonDeletableMessageTextControl.getVisible()
734
+ ? [oNonDeletableMessageTextControl, oDeleteMessageTextControl]
735
+ : oDeleteMessageTextControl,
736
+ beginButton: new Button({
737
+ text: oResourceBundleCore.getText("C_COMMON_OBJECT_PAGE_DELETE"),
738
+ type: "Emphasized",
739
+ press: function() {
740
+ oDialog.close();
741
+ return fnConfirm();
742
+ }
743
+ }),
744
+ endButton: new Button({
745
+ text: CommonUtils.getTranslatedText("C_COMMON_OBJECT_PAGE_CANCEL", oResourceBundle),
746
+ press: function() {
747
+ oDialog.close();
748
+ }
749
+ }),
750
+ afterClose: function() {
751
+ oDialog.destroy();
752
+ // if dialog is closed unconfirmed (e.g. via "Cancel" or Escape button), ensure to reject promise
753
+ if (!bDialogConfirmed) {
754
+ fnReject();
755
+ }
756
+ }
757
+ } as any);
758
+ if (mParameters.noDialog) {
759
+ return fnConfirm();
760
+ } else {
761
+ oDialog.addStyleClass("sapUiContentPadding");
762
+ oDialog.open();
763
+ }
764
+ })
765
+ .finally(function() {
766
+ BusyLocker.unlock(that.oLockObject);
767
+ })
768
+ .catch(function() {
769
+ Log.warning("Couldn't get Programming model");
770
+ fnReject();
771
+ });
772
+ return new Promise(function(resolve: (value: any) => void, reject: (reason?: any) => void) {
773
+ fnReject = reject;
774
+ fnResolve = resolve;
775
+ });
776
+ }
777
+ /**
778
+ * Edits a document.
779
+ *
780
+ * @memberof sap.fe.core.TransactionHelper
781
+ * @static
782
+ * @param {sap.ui.model.odata.v4.Context} oContext Context of the active document
783
+ * @param {object} oView Current view
784
+ * @param messageHandler
785
+ * @returns {Promise} Promise resolves with the new draft context in case of draft programming model
786
+ * @ui5-restricted
787
+ * @final
788
+ */
789
+ editDocument(oContext: any, oView: object, messageHandler: any) {
790
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
791
+ const that = this;
792
+ const sProgrammingModel = this.getProgrammingModel(oContext);
793
+ let oEditPromise;
794
+ if (!oContext) {
795
+ return Promise.reject(new Error("Binding context to active document is required"));
796
+ }
797
+ this._bIsModified = false;
798
+ BusyLocker.lock(that.oLockObject);
799
+ // before triggering the edit action we'll have to remove all bound transition messages
800
+ messageHandler.removeTransitionMessages();
801
+ if (sProgrammingModel === ProgrammingModel.Draft) {
802
+ oEditPromise = draft.createDraftFromActiveDocument(oContext, this._getAppComponent(), {
803
+ bPreserveChanges: true,
804
+ oView: oView
805
+ } as any);
806
+ } else if (sProgrammingModel === ProgrammingModel.Sticky) {
807
+ oEditPromise = sticky.editDocumentInStickySession(oContext, this._getAppComponent());
808
+ } else {
809
+ BusyLocker.unlock(that.oLockObject);
810
+ return Promise.reject(new Error("Edit is only allowed for draft or sticky session supported services"));
811
+ }
812
+ return oEditPromise
813
+ .then(function(oNewContext: any) {
814
+ that._bCreateMode = false;
815
+ return messageHandler.showMessageDialog().then(function() {
816
+ return oNewContext;
817
+ });
818
+ })
819
+ .catch(function(err: any) {
820
+ return messageHandler.showMessages().then(function() {
821
+ return Promise.reject(err);
822
+ });
823
+ })
824
+ .finally(function() {
825
+ BusyLocker.unlock(that.oLockObject);
826
+ });
827
+ }
828
+ /**
829
+ * Cancel 'edit' mode of a document.
830
+ *
831
+ * @memberof sap.fe.core.TransactionHelper
832
+ * @static
833
+ * @param {sap.ui.model.odata.v4.Context} oContext Context of the document to be canceled or deleted
834
+ * @param {object} [mInParameters] Optional, can contain the following attributes:
835
+ * @param {sap.m.Button} mInParameters.cancelButton Cancel Button of the discard popover (mandatory for now)
836
+ * @param {boolean} mInParameters.skipDiscardPopover Optional, supresses the discard popover incase of draft applications while navigating out of OP
837
+ * @param oResourceBundle
838
+ * @param messageHandler
839
+ * @returns {Promise} Promise resolves with ???
840
+ * @ui5-restricted
841
+ * @final
842
+ */
843
+ cancelDocument(
844
+ oContext: any,
845
+ mInParameters: { cancelButton: any; skipDiscardPopover: boolean } | undefined,
846
+ oResourceBundle: any,
847
+ messageHandler: any
848
+ ) {
849
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
850
+ const that = this;
851
+ let sProgrammingModel: typeof ProgrammingModel;
852
+ //context must always be passed - mandatory parameter
853
+ if (!oContext) {
854
+ return Promise.reject("No context exists. Pass a meaningful context");
855
+ }
856
+ BusyLocker.lock(that.oLockObject);
857
+ const mParameters = getParameters(mInParameters);
858
+ const oParamsContext = oContext,
859
+ oCancelButton = mParameters.cancelButton,
860
+ oModel = oParamsContext.getModel();
861
+ let onBeforeCancelPromise, sCanonicalPath: string;
862
+ return Promise.resolve(this.getProgrammingModel(oContext))
863
+ .then(function(sPModel: any) {
864
+ sProgrammingModel = sPModel;
865
+ if (sPModel === ProgrammingModel.Draft) {
866
+ const draftDataContext = oModel.bindContext(oParamsContext.getPath() + "/DraftAdministrativeData").getBoundContext();
867
+ if (!that._bIsModified) {
868
+ return draftDataContext.requestObject().then(function(draftAdminData: any) {
869
+ if (draftAdminData) {
870
+ that._bIsModified = !(draftAdminData.CreationDateTime === draftAdminData.LastChangeDateTime);
871
+ }
872
+ });
873
+ }
874
+ }
875
+ })
876
+ .then(function() {
877
+ if (!mParameters.skipDiscardPopover) {
878
+ return that._showDiscardPopover(oCancelButton, that._bIsModified, oResourceBundle);
879
+ } else {
880
+ return Promise.resolve();
881
+ }
882
+ })
883
+ .then(function() {
884
+ if (mParameters.beforeCancelCallBack) {
885
+ onBeforeCancelPromise = mParameters.beforeCancelCallBack({ context: oContext });
886
+ } else {
887
+ onBeforeCancelPromise = Promise.resolve();
888
+ }
889
+ return onBeforeCancelPromise;
890
+ })
891
+ .then(function() {
892
+ // eslint-disable-next-line default-case
893
+ switch (sProgrammingModel) {
894
+ case ProgrammingModel.Draft:
895
+ return oParamsContext.requestObject("HasActiveEntity").then(function(bHasActiveEntity: any) {
896
+ let oDeletePromise;
897
+ if (!bHasActiveEntity) {
898
+ if (oParamsContext && oParamsContext.hasPendingChanges()) {
899
+ oParamsContext.getBinding().resetChanges();
900
+ }
901
+ oDeletePromise = draft.deleteDraft(oParamsContext);
902
+ return oDeletePromise;
903
+ } else {
904
+ let oActiveContext = oModel.bindContext(oParamsContext.getPath() + "/SiblingEntity").getBoundContext();
905
+ return oActiveContext
906
+ .requestCanonicalPath()
907
+ .then(
908
+ function(sPath: any) {
909
+ sCanonicalPath = sPath;
910
+ if (oParamsContext && oParamsContext.hasPendingChanges()) {
911
+ oParamsContext.getBinding().resetChanges();
912
+ }
913
+ oDeletePromise = draft.deleteDraft(oParamsContext);
914
+ return oDeletePromise;
915
+ },
916
+ function() {
917
+ draft.deleteDraft(oParamsContext);
918
+ return;
919
+ }
920
+ )
921
+ .then(function() {
922
+ //oParamsContext.delete() in the previous promise doesnt return anything upon success.
923
+ if (!sCanonicalPath) {
924
+ return;
925
+ }
926
+ if (oActiveContext.getPath() !== sCanonicalPath) {
927
+ // the active context is using the sibling entity - this path is not accessible anymore as we deleted the draft
928
+ // document - therefore we need to create a new context with the canonical path
929
+ oActiveContext = oModel.bindContext(sCanonicalPath).getBoundContext();
930
+ }
931
+ return oActiveContext;
932
+ });
933
+ }
934
+ });
935
+ case ProgrammingModel.Sticky:
936
+ return sticky.discardDocument(oContext).then(function(oContext: any) {
937
+ if (oContext) {
938
+ if (oContext.hasPendingChanges()) {
939
+ oContext.getBinding().resetChanges();
940
+ }
941
+ if (!that._bCreateMode) {
942
+ oContext.refresh();
943
+ return oContext;
944
+ }
945
+ }
946
+ return false;
947
+ });
948
+ default:
949
+ return Promise.reject("Cancel document only allowed for draft or sticky session supported services");
950
+ }
951
+ })
952
+ .then(function(context: any) {
953
+ that._bIsModified = false;
954
+ // remove existing bound transition messages
955
+ messageHandler.removeTransitionMessages();
956
+ // show unbound messages
957
+ return messageHandler.showMessages().then(function() {
958
+ return context;
959
+ });
960
+ })
961
+ .catch(function(err: any) {
962
+ return messageHandler.showMessages().then(function() {
963
+ return Promise.reject(err);
964
+ });
965
+ })
966
+ .finally(function() {
967
+ BusyLocker.unlock(that.oLockObject);
968
+ });
969
+ }
970
+ /**
971
+ * Saves the document.
972
+ *
973
+ * @memberof sap.fe.core.TransactionHelper
974
+ * @static
975
+ * @param {sap.ui.model.odata.v4.Context} oContext Context of the document to be saved
976
+ * @param oResourceBundle
977
+ * @param bExecuteSideEffectsOnError
978
+ * @param aBindings
979
+ * @param messageHandler
980
+ * @returns {Promise} Promise resolves with ???
981
+ * @ui5-restricted
982
+ * @final
983
+ */
984
+ saveDocument(oContext: any, oResourceBundle: any, bExecuteSideEffectsOnError: any, aBindings: any, messageHandler: any) {
985
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
986
+ const that = this;
987
+ const sProgrammingModel = this.getProgrammingModel(oContext);
988
+ let oSavePromise;
989
+ if (!oContext) {
990
+ return Promise.reject(new Error("Binding context to draft document is required"));
991
+ }
992
+ // in case of saving / activating the bound transition messages shall be removed before the PATCH/POST
993
+ // is sent to the backend
994
+ messageHandler.removeTransitionMessages();
995
+ BusyLocker.lock(that.oLockObject);
996
+ if (sProgrammingModel === ProgrammingModel.Draft) {
997
+ oSavePromise = draft.activateDocument(oContext, this._getAppComponent(), {});
998
+ } else if (sProgrammingModel === ProgrammingModel.Sticky) {
999
+ oSavePromise = sticky.activateDocument(oContext);
1000
+ } else {
1001
+ BusyLocker.unlock(that.oLockObject);
1002
+ return Promise.reject(new Error("Save is only allowed for draft or sticky session supported services"));
1003
+ }
1004
+ return oSavePromise
1005
+ .then(function(oActiveDocument: any) {
1006
+ const bNewObject =
1007
+ that.sProgrammingModel === ProgrammingModel.Sticky ? that._bCreateMode : !oContext.getObject().HasActiveEntity;
1008
+ MessageToast.show(
1009
+ bNewObject
1010
+ ? CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_CREATED", oResourceBundle)
1011
+ : CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_OBJECT_SAVED", oResourceBundle)
1012
+ );
1013
+ that._bIsModified = false;
1014
+ return messageHandler.showMessageDialog().then(function() {
1015
+ return oActiveDocument;
1016
+ });
1017
+ })
1018
+ .catch(function(err: any) {
1019
+ if (aBindings && aBindings.length > 0) {
1020
+ /* The sideEffects are executed only for table items in transient state */
1021
+ aBindings.forEach(function(oListBinding: any) {
1022
+ if (!CommonUtils.hasTransientContext(oListBinding) && bExecuteSideEffectsOnError) {
1023
+ const oAppComponent = that._getAppComponent();
1024
+ oAppComponent.getSideEffectsService().requestSideEffectsForNavigationProperty(oListBinding.getPath(), oContext);
1025
+ }
1026
+ });
1027
+ }
1028
+ return messageHandler.showMessages().then(function() {
1029
+ return Promise.reject(err);
1030
+ });
1031
+ })
1032
+ .finally(function() {
1033
+ BusyLocker.unlock(that.oLockObject);
1034
+ });
1035
+ }
1036
+ /**
1037
+ * Calls a bound or unbound action.
1038
+ *
1039
+ * @function
1040
+ * @static
1041
+ * @name sap.fe.core.TransactionHelper.callAction
1042
+ * @memberof sap.fe.core.TransactionHelper
1043
+ * @param {string} sActionName The name of the action to be called
1044
+ * @param {map} [mParameters] Contains the following attributes:
1045
+ * @param {sap.ui.model.odata.v4.Context} [mParameters.contexts] Mandatory for a bound action: Either one context or an array with contexts for which the action is to be called
1046
+ * @param {sap.ui.model.odata.v4.ODataModel} [mParameters.model] Mandatory for an unbound action: An instance of an OData V4 model
1047
+ * @param {string} [mParameters.invocationGrouping] Mode how actions are to be called: 'ChangeSet' to put all action calls into one changeset, 'Isolated' to put them into separate changesets
1048
+ * @param {string} [mParameters.label] A human-readable label for the action
1049
+ * @param {boolean} [mParameters.bGetBoundContext] If specified, the action promise returns the bound context
1050
+ * @param {object} oView Contains the object of the current view
1051
+ * @param messageHandler
1052
+ * @returns {Promise} Promise resolves with an array of response objects (TODO: to be changed)
1053
+ * @ui5-restricted
1054
+ * @final
1055
+ **/
1056
+ callAction(sActionName: string, mParameters: any, oView: View | null, messageHandler: any) {
1057
+ mParameters = getParameters(mParameters);
1058
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
1059
+ const that = this;
1060
+ let oContext, oModel: any, oPromise;
1061
+ const mBindingParameters = mParameters.bindingParameters;
1062
+ if (!sActionName) {
1063
+ return Promise.reject("Provide name of action to be executed");
1064
+ }
1065
+ // action imports are not directly obtained from the metaModel by it is present inside the entityContainer
1066
+ // and the acions it refers to present outside the entitycontainer, hence to obtain kind of the action
1067
+ // split() on its name was required
1068
+ const sName = sActionName.split("/")[1];
1069
+ sActionName = sName || sActionName;
1070
+ oContext = sName ? undefined : mParameters.contexts;
1071
+ //checking whether the context is an array with more than 0 length or not an array(create action)
1072
+ if (oContext && ((Array.isArray(oContext) && oContext.length) || !Array.isArray(oContext))) {
1073
+ oContext = Array.isArray(oContext) ? oContext[0] : oContext;
1074
+ oModel = oContext.getModel();
1075
+ }
1076
+ if (mParameters.model) {
1077
+ oModel = mParameters.model;
1078
+ }
1079
+ if (!oModel) {
1080
+ return Promise.reject("Pass a context for a bound action or pass the model for an unbound action");
1081
+ }
1082
+ // get the binding parameters $select and $expand for the side effect on this action
1083
+ // also gather additional property paths to be requested such as text associations
1084
+ const oAppComponent = that._getAppComponent();
1085
+ const mSideEffectsParameters = oAppComponent.getSideEffectsService().getODataActionSideEffects(sActionName, oContext) || {};
1086
+ if (oContext && oModel) {
1087
+ oPromise = new Promise<void>(function(resolve, reject) {
1088
+ let oApplicableContextDialog: Dialog;
1089
+ const oController = {
1090
+ onClose: function() {
1091
+ // User cancels action
1092
+ oApplicableContextDialog.close();
1093
+ resolve();
1094
+ },
1095
+ onContinue: function() {
1096
+ // Users continues the action with the bound contexts
1097
+ oApplicableContextDialog.close();
1098
+ resolve(mParameters.applicableContext);
1099
+ }
1100
+ };
1101
+ const fnOpenAndFillDialog = function() {
1102
+ let oDialogContent;
1103
+ const nNotApplicable = mParameters.notApplicableContext.length,
1104
+ aNotApplicableItems = [];
1105
+ for (let i = 0; i < mParameters.notApplicableContext.length; i++) {
1106
+ oDialogContent = mParameters.notApplicableContext[i].getObject();
1107
+ aNotApplicableItems.push(oDialogContent);
1108
+ }
1109
+ const oNotApplicableItemsModel = new JSONModel(aNotApplicableItems);
1110
+ const oTotals = new JSONModel({ total: nNotApplicable, label: mParameters.label });
1111
+ oApplicableContextDialog.setModel(oNotApplicableItemsModel, "notApplicable");
1112
+ oApplicableContextDialog.setModel(oTotals, "totals");
1113
+ oApplicableContextDialog.open();
1114
+ };
1115
+ if (mParameters.notApplicableContext && mParameters.notApplicableContext.length >= 1) {
1116
+ // Show the contexts that are not applicable and will not therefore be processed
1117
+ const sFragmentName = "sap.fe.core.controls.ActionPartial";
1118
+ const oDialogFragment = XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment");
1119
+ const oMetaModel = oModel.getMetaModel();
1120
+ const sCanonicalPath = mParameters.contexts[0].getCanonicalPath();
1121
+ const sEntitySet = sCanonicalPath.substr(0, sCanonicalPath.indexOf("(")) + "/";
1122
+ const oDialogLabelModel = new JSONModel({
1123
+ title: mParameters.label
1124
+ });
1125
+ Promise.resolve(
1126
+ XMLPreprocessor.process(
1127
+ oDialogFragment,
1128
+ { name: sFragmentName },
1129
+ {
1130
+ bindingContexts: {
1131
+ entityType: oMetaModel.createBindingContext(sEntitySet),
1132
+ label: oDialogLabelModel.createBindingContext("/")
1133
+ },
1134
+ models: {
1135
+ entityType: oMetaModel,
1136
+ metaModel: oMetaModel,
1137
+ label: oDialogLabelModel
1138
+ }
1139
+ }
1140
+ )
1141
+ )
1142
+ .then(function(oFragment: any) {
1143
+ return Fragment.load({ definition: oFragment, controller: oController });
1144
+ })
1145
+ .then(function(oPopover: any) {
1146
+ oApplicableContextDialog = oPopover;
1147
+ mParameters.parentControl.addDependent(oPopover);
1148
+ fnOpenAndFillDialog();
1149
+ })
1150
+ .catch(reject);
1151
+ } else {
1152
+ resolve(mParameters.contexts);
1153
+ }
1154
+ }).then(function(contextToProcess: any) {
1155
+ if (contextToProcess) {
1156
+ return operations.callBoundAction(sActionName, contextToProcess, oModel, oAppComponent, {
1157
+ invocationGrouping: mParameters.invocationGrouping,
1158
+ label: mParameters.label,
1159
+ showActionParameterDialog: true,
1160
+ mBindingParameters: mBindingParameters,
1161
+ entitySetName: mParameters.entitySetName,
1162
+ additionalSideEffect: mSideEffectsParameters,
1163
+ onSubmitted: function() {
1164
+ messageHandler.removeTransitionMessages();
1165
+ BusyLocker.lock(that.oLockObject);
1166
+ },
1167
+ onResponse: function() {
1168
+ BusyLocker.unlock(that.oLockObject);
1169
+ },
1170
+ parentControl: mParameters.parentControl,
1171
+ internalModelContext: mParameters.internalModelContext,
1172
+ operationAvailableMap: mParameters.operationAvailableMap,
1173
+ bIsCreateAction: mParameters.bIsCreateAction,
1174
+ bGetBoundContext: mParameters.bGetBoundContext,
1175
+ bObjectPage: mParameters.bObjectPage,
1176
+ messageHandler: messageHandler,
1177
+ defaultValuesExtensionFunction: mParameters.defaultValuesExtensionFunction
1178
+ });
1179
+ } else {
1180
+ return null;
1181
+ }
1182
+ });
1183
+ } else {
1184
+ // TODO: confirm if action import needs side effects.
1185
+ oPromise = operations.callActionImport(sActionName, oModel, oAppComponent, {
1186
+ label: mParameters.label,
1187
+ showActionParameterDialog: true,
1188
+ bindingParameters: mBindingParameters,
1189
+ entitySetName: mParameters.entitySetName,
1190
+ onSubmitted: function() {
1191
+ BusyLocker.lock(that.oLockObject);
1192
+ },
1193
+ onResponse: function() {
1194
+ BusyLocker.unlock(that.oLockObject);
1195
+ },
1196
+ parentControl: mParameters.parentControl,
1197
+ internalModelContext: mParameters.internalModelContext,
1198
+ operationAvailableMap: mParameters.operationAvailableMap,
1199
+ messageHandler: messageHandler,
1200
+ bObjectPage: mParameters.bObjectPage
1201
+ });
1202
+ }
1203
+ return oPromise
1204
+ .then(function(oResult: any) {
1205
+ // Succeeded
1206
+ return that._handleActionResponse(messageHandler, mParameters, sActionName).then(function() {
1207
+ return oResult;
1208
+ });
1209
+ })
1210
+ .catch(function(err: any) {
1211
+ return that._handleActionResponse(messageHandler, mParameters, sActionName).then(function() {
1212
+ return Promise.reject(err);
1213
+ });
1214
+ });
1215
+ }
1216
+ /**
1217
+ * Handles messages for action call.
1218
+ *
1219
+ * @function
1220
+ * @name sap.fe.core.TransactionHelper#_handleActionResponse
1221
+ * @memberof sap.fe.core.TransactionHelper
1222
+ * @param messageHandler
1223
+ * @param {object} mParameters Parameters to be considered for the action.
1224
+ * @param {string} sActionName The name of the action to be called
1225
+ * @returns {Promise} Promise after message dialog is opened if required.
1226
+ * @ui5-restricted
1227
+ * @final
1228
+ */
1229
+ _handleActionResponse(messageHandler: any, mParameters: any, sActionName: string) {
1230
+ const aTransientMessages = messageHandling.getMessages(true, true);
1231
+ if (aTransientMessages.length > 0 && mParameters && mParameters.internalModelContext) {
1232
+ mParameters.internalModelContext.setProperty("sActionName", mParameters.label ? mParameters.label : sActionName);
1233
+ }
1234
+ return messageHandler.showMessages();
1235
+ }
1236
+ /**
1237
+ * Handles validation errors for the 'discard' action.
1238
+ *
1239
+ * @function
1240
+ * @name sap.fe.core.TransactionHelper#handleValidationError
1241
+ * @memberof sap.fe.core.TransactionHelper
1242
+ * @static
1243
+ * @ui5-restricted
1244
+ * @final
1245
+ */
1246
+ handleValidationError() {
1247
+ const oMessageManager = (sap.ui.getCore() as any).getMessageManager(),
1248
+ errorToRemove = oMessageManager
1249
+ .getMessageModel()
1250
+ .getData()
1251
+ .filter(function(error: any) {
1252
+ // only needs to handle validation messages, technical and persistent errors needs not to be checked here.
1253
+ if (error.validation) {
1254
+ return error;
1255
+ }
1256
+ });
1257
+ oMessageManager.removeMessages(errorToRemove);
1258
+ }
1259
+ /**
1260
+ * Shows a popover if it needs to be shown.
1261
+ * TODO: Popover is shown if user has modified any data.
1262
+ * TODO: Popover is shown if there's a difference from draft admin data.
1263
+ * @static
1264
+ * @name sap.fe.core.TransactionHelper._showDiscardPopover
1265
+ * @memberof sap.fe.core.TransactionHelper
1266
+ * @param {sap.ui.core.Control} oCancelButton The control which will open the popover
1267
+ * @param bIsModified
1268
+ * @param oResourceBundle
1269
+ * @returns {Promise} Promise resolves if user confirms discard, rejects if otherwise, rejects if no control passed to open popover
1270
+ * @ui5-restricted
1271
+ * @final
1272
+ */
1273
+ _showDiscardPopover(oCancelButton: any, bIsModified: any, oResourceBundle: any) {
1274
+ // TODO: Implement this popover as a fragment as in v2??
1275
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
1276
+ const that = this;
1277
+ that._bContinueDiscard = false;
1278
+ // to be implemented
1279
+ return new Promise<void>(function(resolve, reject) {
1280
+ if (!oCancelButton) {
1281
+ reject("Cancel button not found");
1282
+ }
1283
+ //Show popover only when data is changed.
1284
+ if (bIsModified) {
1285
+ const fnOnAfterDiscard = function() {
1286
+ oCancelButton.setEnabled(true);
1287
+ if (that._bContinueDiscard) {
1288
+ resolve();
1289
+ } else {
1290
+ reject("Discard operation was rejected. Document has not been discarded");
1291
+ }
1292
+ that._oPopover.detachAfterClose(fnOnAfterDiscard);
1293
+ };
1294
+ if (!that._oPopover) {
1295
+ const oText = new Text({
1296
+ //This text is the same as LR v2.
1297
+ //TODO: Display message provided by app developer???
1298
+ text: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_DRAFT_DISCARD_MESSAGE", oResourceBundle)
1299
+ }),
1300
+ oButton = new Button({
1301
+ text: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_DRAFT_DISCARD_BUTTON", oResourceBundle),
1302
+ width: "100%",
1303
+ press: function() {
1304
+ that.handleValidationError();
1305
+ that._bContinueDiscard = true;
1306
+ that._oPopover.close();
1307
+ },
1308
+ ariaLabelledBy: oText
1309
+ } as any);
1310
+ that._oPopover = new Popover({
1311
+ showHeader: false,
1312
+ placement: "Top",
1313
+ content: [
1314
+ new VBox({
1315
+ items: [oText, oButton]
1316
+ })
1317
+ ],
1318
+ beforeOpen: function() {
1319
+ // make sure to NOT trigger multiple cancel flows
1320
+ oCancelButton.setEnabled(false);
1321
+ that._oPopover.setInitialFocus(oButton);
1322
+ }
1323
+ });
1324
+ that._oPopover.addStyleClass("sapUiContentPadding");
1325
+ }
1326
+ that._oPopover.attachAfterClose(fnOnAfterDiscard);
1327
+ that._oPopover.openBy(oCancelButton, false);
1328
+ } else {
1329
+ that.handleValidationError();
1330
+ resolve();
1331
+ }
1332
+ });
1333
+ }
1334
+ /**
1335
+ * Sets the document to modified state on patch event.
1336
+ *
1337
+ * @function
1338
+ * @static
1339
+ * @name sap.fe.core.TransactionHelper.handleDocumentModifications
1340
+ * @memberof sap.fe.core.TransactionHelper
1341
+ * @ui5-restricted
1342
+ * @final
1343
+ */
1344
+ handleDocumentModifications() {
1345
+ this._bIsModified = true;
1346
+ }
1347
+ /**
1348
+ * Retrieves the owner component.
1349
+ *
1350
+ * @function
1351
+ * @static
1352
+ * @private
1353
+ * @name sap.fe.core.TransactionHelper._getOwnerComponent
1354
+ * @memberof sap.fe.core.TransactionHelper
1355
+ * @returns {sap.fe.core.AppComponent} The app component
1356
+ * @ui5-restricted
1357
+ * @final
1358
+ **/
1359
+ _getAppComponent() {
1360
+ return this._oAppComponent;
1361
+ }
1362
+ _launchDialogWithKeyFields(
1363
+ oListBinding: any,
1364
+ oTransientListBinding: any,
1365
+ oTransientContext: any,
1366
+ mFields: any,
1367
+ oModel: any,
1368
+ mParameters: any,
1369
+ messageHandler: any
1370
+ ) {
1371
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
1372
+ const that = this;
1373
+ let oDialog: Dialog;
1374
+ const oParentControl = mParameters.parentControl,
1375
+ bSuccess = false;
1376
+ return new Promise(function(resolve: (value: any) => void, reject: (reason?: any) => void) {
1377
+ const sFragmentName = "sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog";
1378
+ const oFragment = XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment"),
1379
+ oResourceBundle = oParentControl.getController().oResourceBundle,
1380
+ oMetaModel = oModel.getMetaModel(),
1381
+ aImmutableFields: any[] = [],
1382
+ oAppComponent = that._getAppComponent(),
1383
+ sPath = oListBinding.isRelative() ? oListBinding.getResolvedPath() : oListBinding.getPath(),
1384
+ oEntitySetContext = oMetaModel.createBindingContext(sPath),
1385
+ sMetaPath = oMetaModel.getMetaPath(sPath);
1386
+ for (const i in mFields) {
1387
+ aImmutableFields.push(oMetaModel.createBindingContext(sMetaPath + "/" + mFields[i]));
1388
+ }
1389
+ const oImmutableCtxModel = new JSONModel(aImmutableFields);
1390
+ const oImmutableCtx = oImmutableCtxModel.createBindingContext("/") as Context;
1391
+ return Promise.resolve(
1392
+ XMLPreprocessor.process(
1393
+ oFragment,
1394
+ { name: sFragmentName },
1395
+ {
1396
+ bindingContexts: {
1397
+ entitySet: oEntitySetContext,
1398
+ fields: oImmutableCtx
1399
+ },
1400
+ models: {
1401
+ entitySet: oEntitySetContext.getModel(),
1402
+ fields: oImmutableCtx.getModel(),
1403
+ metaModel: oMetaModel
1404
+ }
1405
+ }
1406
+ )
1407
+ ).then(function(oFragment: any) {
1408
+ let aFormElements: any[] = [];
1409
+ const mFieldValueMap: any = {};
1410
+ let oCreateButton: Button;
1411
+ const validateRequiredProperties = function() {
1412
+ return Promise.all(
1413
+ aFormElements
1414
+ .map(function(oFormElement: any) {
1415
+ return oFormElement.getFields()[0];
1416
+ })
1417
+ .filter(function(oField: any) {
1418
+ return oField.getRequired();
1419
+ })
1420
+ .map(function(oField: any) {
1421
+ const sFieldId = oField.getId();
1422
+ if (sFieldId in mFieldValueMap) {
1423
+ return Promise.resolve(mFieldValueMap[sFieldId])
1424
+ .then(function(vValue: any) {
1425
+ return vValue;
1426
+ })
1427
+ .catch(function() {
1428
+ return undefined;
1429
+ });
1430
+ }
1431
+ return oField.getValueState() === ValueState.Error ? undefined : oField.getValue();
1432
+ })
1433
+ )
1434
+ .then(function(aResults: any[]) {
1435
+ return aResults.every(function(vValue: any) {
1436
+ return vValue !== undefined && vValue !== null && vValue !== "";
1437
+ });
1438
+ })
1439
+ .catch(function() {
1440
+ return false;
1441
+ })
1442
+ .then(function(bEnabled: boolean) {
1443
+ oCreateButton.setEnabled(bEnabled);
1444
+ });
1445
+ };
1446
+ const oController = {
1447
+ /*
1448
+ fired on focus out from field or on selecting a value from the valuehelp.
1449
+ the create button is enabled when a value is added.
1450
+ liveChange is not fired when value is added from valuehelp.
1451
+ value validation is not done for create button enablement.
1452
+ */
1453
+ handleChange: function(oEvent: any) {
1454
+ messageHandler.removeTransitionMessages();
1455
+ const oField = oEvent.getSource();
1456
+ const sFieldId = oEvent.getParameter("id");
1457
+ const oFieldPromise = oEvent.getParameter("promise");
1458
+ if (oFieldPromise) {
1459
+ mFieldValueMap[sFieldId] = oFieldPromise.then(function() {
1460
+ return oField.getValue();
1461
+ });
1462
+ }
1463
+ validateRequiredProperties();
1464
+ },
1465
+ /*
1466
+ fired on key press. the create button is enabled when a value is added.
1467
+ liveChange is not fired when value is added from valuehelp.
1468
+ value validation is not done for create button enablement.
1469
+ */
1470
+ handleLiveChange: function(oEvent: any) {
1471
+ const sFieldId = oEvent.getParameter("id");
1472
+ const vValue = oEvent.getParameter("value");
1473
+ mFieldValueMap[sFieldId] = vValue;
1474
+ validateRequiredProperties();
1475
+ }
1476
+ };
1477
+ return Fragment.load({
1478
+ definition: oFragment,
1479
+ controller: oController
1480
+ }).then(function(oDialogContent: any) {
1481
+ oDialog = new Dialog({
1482
+ title: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE", oResourceBundle),
1483
+ content: [oDialogContent],
1484
+ beginButton: {
1485
+ text: CommonUtils.getTranslatedText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE_BUTTON", oResourceBundle),
1486
+ type: "Emphasized",
1487
+ press: function(oEvent: any) {
1488
+ const oCreateButton = oEvent.getSource();
1489
+ oCreateButton.setEnabled(false);
1490
+ BusyLocker.lock(oDialog);
1491
+ mParameters.bIsCreateDialog = true;
1492
+ return Promise.all(
1493
+ Object.keys(mFieldValueMap).map(function(sKey: string) {
1494
+ return mFieldValueMap[sKey].then(function(oValue: any) {
1495
+ const oDialogValue: any = {};
1496
+ oDialogValue[sKey] = oValue;
1497
+ return oDialogValue;
1498
+ });
1499
+ })
1500
+ )
1501
+ .then(function(aValues: any[]) {
1502
+ let onBeforeCreatePromise;
1503
+ if (mParameters.beforeCreateCallBack) {
1504
+ onBeforeCreatePromise = mParameters.beforeCreateCallBack({
1505
+ contextPath: oListBinding && oListBinding.getPath(),
1506
+ createParameters: aValues
1507
+ });
1508
+ } else {
1509
+ onBeforeCreatePromise = Promise.resolve();
1510
+ }
1511
+ return onBeforeCreatePromise;
1512
+ })
1513
+ .then(function() {
1514
+ const oPromise = that.onAfterCreateCompletion(
1515
+ oTransientListBinding,
1516
+ oTransientContext,
1517
+ mParameters
1518
+ );
1519
+ oModel.submitBatch("submitLater");
1520
+ return oPromise;
1521
+ })
1522
+ .then(function(oResponse: any) {
1523
+ if (!oResponse || (oResponse && oResponse.bKeepDialogOpen !== true)) {
1524
+ oDialog.setBindingContext(null as any);
1525
+ oDialog.close();
1526
+ resolve(oResponse);
1527
+ }
1528
+ })
1529
+ .catch(function(oError: any) {
1530
+ reject(oError);
1531
+ })
1532
+ .finally(function() {
1533
+ BusyLocker.unlock(oDialog);
1534
+ oCreateButton.setEnabled(true);
1535
+ return messageHandler.showMessages();
1536
+ });
1537
+ }
1538
+ },
1539
+ endButton: {
1540
+ text: CommonUtils.getTranslatedText("C_COMMON_ACTION_PARAMETER_DIALOG_CANCEL", oResourceBundle),
1541
+ press: function() {
1542
+ oDialog.close();
1543
+ }
1544
+ },
1545
+ afterClose: function() {
1546
+ // show footer as per UX guidelines when dialog is not open
1547
+ (oDialog.getBindingContext("internal") as InternalModelContext)?.setProperty("isCreateDialogOpen", false);
1548
+ oDialog.destroy();
1549
+ if (!bSuccess) {
1550
+ reject({
1551
+ bDeleteTransientContext: true,
1552
+ navigateBackFromTransientState: true
1553
+ });
1554
+ }
1555
+ }
1556
+ } as any);
1557
+ aFormElements = oDialogContent
1558
+ .getAggregation("form")
1559
+ .getAggregation("formContainers")[0]
1560
+ .getAggregation("formElements");
1561
+ if (oParentControl && oParentControl.addDependent) {
1562
+ // if there is a parent control specified add the dialog as dependent
1563
+ oParentControl.addDependent(oDialog);
1564
+ }
1565
+ oCreateButton = oDialog.getBeginButton();
1566
+ oDialog.setBindingContext(oTransientContext);
1567
+ return CommonUtils.setUserDefaults(
1568
+ oAppComponent,
1569
+ aImmutableFields,
1570
+ oTransientContext,
1571
+ false,
1572
+ mParameters.createAction,
1573
+ mParameters.data
1574
+ )
1575
+ .then(function() {
1576
+ validateRequiredProperties();
1577
+ // footer must not be visible when the dialog is open as per UX guidelines
1578
+ (oDialog.getBindingContext("internal") as InternalModelContext).setProperty("isCreateDialogOpen", true);
1579
+ oDialog.open();
1580
+ })
1581
+ .catch(function(oError: any) {
1582
+ return messageHandler.showMessages().then(function() {
1583
+ return Promise.reject(oError);
1584
+ });
1585
+ });
1586
+ });
1587
+ });
1588
+ });
1589
+ }
1590
+ onAfterCreateCompletion(oListBinding: any, oNewDocumentContext: any, mParameters: any) {
1591
+ let fnResolve: Function, fnReject: Function;
1592
+ const oPromise = new Promise(function(resolve, reject) {
1593
+ fnResolve = resolve;
1594
+ fnReject = reject;
1595
+ });
1596
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
1597
+ const that = this;
1598
+ // Workaround suggested by OData model v4 colleagues
1599
+ const fnCreateCompleted = function(oEvent: any) {
1600
+ const oContext = oEvent.getParameter("context"),
1601
+ bSuccess = oEvent.getParameter("success");
1602
+ if (oContext === oNewDocumentContext) {
1603
+ oListBinding.detachCreateCompleted(fnCreateCompleted, that);
1604
+ if (!bSuccess) {
1605
+ const oError: any = { bDeleteTransientContext: false };
1606
+ if (!mParameters.keepTransientContextOnFailed) {
1607
+ // the context is deleted
1608
+
1609
+ // this is needed to avoid console errors TO be checked with model colleagues
1610
+ oContext
1611
+ .created()
1612
+ .then(undefined, function() {
1613
+ Log.trace("transient creation context deleted");
1614
+ })
1615
+ .catch(function(oError: any) {
1616
+ Log.trace("transient creation context deletion error", oError);
1617
+ });
1618
+ if (!mParameters.bIsCreateDialog) {
1619
+ // if current state is transient (...), browser will come back to previous state
1620
+ oError.navigateBackFromTransientState = true;
1621
+ oError.bDeleteTransientContext = true;
1622
+ fnReject(oError);
1623
+ }
1624
+ }
1625
+ fnResolve({ bKeepDialogOpen: true });
1626
+ } else {
1627
+ fnResolve();
1628
+ }
1629
+ }
1630
+ };
1631
+ oListBinding.attachCreateCompleted(fnCreateCompleted, this);
1632
+ return oPromise;
1633
+ }
1634
+ /**
1635
+ * Retrieves the name of the NewAction to be executed.
1636
+ *
1637
+ * @function
1638
+ * @static
1639
+ * @private
1640
+ * @name sap.fe.core.TransactionHelper._getNewAction
1641
+ * @memberof sap.fe.core.TransactionHelper
1642
+ * @param {object} oStartupParameters Startup parameters of the application
1643
+ * @param {string} sCreateHash Hash to be checked for action type
1644
+ * @param {object} oMetaModel The MetaModel used to check for NewAction parameter
1645
+ * @param {string} sMetaPath The MetaPath
1646
+ * @returns {string} The name of the action
1647
+ * @ui5-restricted
1648
+ * @final
1649
+ **/
1650
+ _getNewAction(oStartupParameters: any, sCreateHash: string, oMetaModel: ODataMetaModel, sMetaPath: string) {
1651
+ let sNewAction;
1652
+
1653
+ if (oStartupParameters && oStartupParameters.preferredMode && sCreateHash.indexOf("i-action=createWith") > -1) {
1654
+ const sPreferredMode = oStartupParameters.preferredMode[0];
1655
+ sNewAction =
1656
+ sPreferredMode.indexOf("createWith:") > -1 ? sPreferredMode.substr(sPreferredMode.lastIndexOf(":") + 1) : undefined;
1657
+ } else {
1658
+ sNewAction =
1659
+ oMetaModel && oMetaModel.getObject !== undefined
1660
+ ? oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Session.v1.StickySessionSupported/NewAction") ||
1661
+ oMetaModel.getObject(sMetaPath + "@com.sap.vocabularies.Common.v1.DraftRoot/NewAction")
1662
+ : undefined;
1663
+ }
1664
+ return sNewAction;
1665
+ }
1666
+ /**
1667
+ * Retrieves the label for the title of a specific create action dialog, e.g. Create Sales Order from Quotation.
1668
+ *
1669
+ * The following priority is applied:
1670
+ * 1. label of line-item annotation.
1671
+ * 2. label annotated in the action.
1672
+ * 3. "Create" as a constant from i18n.
1673
+ *
1674
+ * @function
1675
+ * @static
1676
+ * @private
1677
+ * @name sap.fe.core.TransactionHelper._getSpecificCreateActionDialogLabel
1678
+ * @memberof sap.fe.core.TransactionHelper
1679
+ * @param {object} oMetaModel The MetaModel used to check for the NewAction parameter
1680
+ * @param {string} sMetaPath The MetaPath
1681
+ * @param {string} sNewAction Contains the name of the action to be executed
1682
+ * @param {object} oResourceBundleCore ResourceBundle to access the default Create label
1683
+ * @returns {string} The label for the Create Action Dialog
1684
+ * @ui5-restricted
1685
+ * @final
1686
+ **/
1687
+ _getSpecificCreateActionDialogLabel(
1688
+ oMetaModel: ODataMetaModel,
1689
+ sMetaPath: string,
1690
+ sNewAction: string,
1691
+ oResourceBundleCore: ResourceBundle
1692
+ ) {
1693
+ const fnGetLabelFromLineItemAnnotation = function() {
1694
+ if (oMetaModel && oMetaModel.getObject(sMetaPath + "/@com.sap.vocabularies.UI.v1.LineItem")) {
1695
+ const iLineItemIndex = oMetaModel
1696
+ .getObject(sMetaPath + "/@com.sap.vocabularies.UI.v1.LineItem")
1697
+ .findIndex(function(oLineItem: any) {
1698
+ const aLineItemAction = oLineItem.Action ? oLineItem.Action.split("(") : undefined;
1699
+ return aLineItemAction ? aLineItemAction[0] === sNewAction : false;
1700
+ });
1701
+ return iLineItemIndex > -1
1702
+ ? oMetaModel.getObject(sMetaPath + "/@com.sap.vocabularies.UI.v1.LineItem")[iLineItemIndex].Label
1703
+ : undefined;
1704
+ } else {
1705
+ return undefined;
1706
+ }
1707
+ };
1708
+
1709
+ return (
1710
+ fnGetLabelFromLineItemAnnotation() ||
1711
+ (oMetaModel && oMetaModel.getObject(sMetaPath + "/" + sNewAction + "@com.sap.vocabularies.Common.v1.Label")) ||
1712
+ (oResourceBundleCore && oResourceBundleCore.getText("C_TRANSACTION_HELPER_SAPFE_ACTION_CREATE"))
1713
+ );
1714
+ }
1715
+ }
1716
+
1717
+ export default TransactionHelper;