@sapui5/sap.fe.core 1.100.0 → 1.102.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 (295) hide show
  1. package/package.json +4 -4
  2. package/src/sap/fe/core/.library +2 -3
  3. package/src/sap/fe/core/AppComponent.js +23 -30
  4. package/src/sap/fe/core/AppComponent.ts +35 -40
  5. package/src/sap/fe/core/AppStateHandler.js +8 -8
  6. package/src/sap/fe/core/AppStateHandler.ts +11 -11
  7. package/src/sap/fe/core/BaseController.js +9 -9
  8. package/src/sap/fe/core/BaseController.ts +3 -4
  9. package/src/sap/fe/core/CommonUtils.js +122 -101
  10. package/src/sap/fe/core/CommonUtils.ts +239 -193
  11. package/src/sap/fe/core/ExtensionAPI.js +12 -13
  12. package/src/sap/fe/core/ExtensionAPI.ts +21 -31
  13. package/src/sap/fe/core/PageController.js +19 -13
  14. package/src/sap/fe/core/PageController.ts +40 -34
  15. package/src/sap/fe/core/TemplateComponent.js +198 -123
  16. package/src/sap/fe/core/TemplateComponent.ts +109 -121
  17. package/src/sap/fe/core/TemplateModel.js +7 -9
  18. package/src/sap/fe/core/TemplateModel.ts +3 -3
  19. package/src/sap/fe/core/buildingBlocks/AttributeModel.js +60 -0
  20. package/src/sap/fe/core/buildingBlocks/AttributeModel.ts +37 -0
  21. package/src/sap/fe/core/buildingBlocks/BuildingBlock.js +165 -0
  22. package/src/sap/fe/core/buildingBlocks/BuildingBlock.ts +178 -0
  23. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.js +935 -0
  24. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.ts +837 -0
  25. package/src/sap/fe/core/buildingBlocks/TraceInfo.js +436 -0
  26. package/src/sap/fe/core/buildingBlocks/TraceInfo.ts +431 -0
  27. package/src/sap/fe/core/{BusyLocker.js → controllerextensions/BusyLocker.js} +1 -1
  28. package/src/sap/fe/core/{BusyLocker.ts → controllerextensions/BusyLocker.ts} +7 -7
  29. package/src/sap/fe/core/controllerextensions/EditFlow.js +660 -288
  30. package/src/sap/fe/core/controllerextensions/EditFlow.ts +513 -331
  31. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +11 -11
  32. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +6 -7
  33. package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +43 -25
  34. package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +132 -103
  35. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +16 -16
  36. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +64 -55
  37. package/src/sap/fe/core/controllerextensions/InternalRouting.js +166 -99
  38. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +187 -149
  39. package/src/sap/fe/core/controllerextensions/KPIManagement.js +14 -14
  40. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +12 -11
  41. package/src/sap/fe/core/controllerextensions/MassEdit.js +13 -12
  42. package/src/sap/fe/core/controllerextensions/MassEdit.ts +22 -22
  43. package/src/sap/fe/core/controllerextensions/MessageHandler.js +14 -26
  44. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +20 -30
  45. package/src/sap/fe/core/controllerextensions/PageReady.js +25 -23
  46. package/src/sap/fe/core/controllerextensions/PageReady.ts +49 -47
  47. package/src/sap/fe/core/controllerextensions/Paginator.js +24 -15
  48. package/src/sap/fe/core/controllerextensions/Paginator.ts +35 -20
  49. package/src/sap/fe/core/controllerextensions/Placeholder.js +10 -10
  50. package/src/sap/fe/core/controllerextensions/Placeholder.ts +12 -14
  51. package/src/sap/fe/core/controllerextensions/Routing.js +11 -11
  52. package/src/sap/fe/core/controllerextensions/Routing.ts +12 -13
  53. package/src/sap/fe/core/controllerextensions/Share.js +34 -16
  54. package/src/sap/fe/core/controllerextensions/Share.ts +50 -32
  55. package/src/sap/fe/core/controllerextensions/SideEffects.js +15 -15
  56. package/src/sap/fe/core/controllerextensions/SideEffects.ts +64 -65
  57. package/src/sap/fe/core/controllerextensions/ViewState.js +27 -31
  58. package/src/sap/fe/core/controllerextensions/ViewState.ts +103 -102
  59. package/src/sap/fe/core/controllerextensions/collaboration/ActivityBase.js +105 -0
  60. package/src/sap/fe/core/controllerextensions/collaboration/ActivityBase.ts +98 -0
  61. package/src/sap/fe/core/controllerextensions/collaboration/ActivitySync.js +360 -0
  62. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/ActivitySync.ts +90 -132
  63. package/src/sap/fe/core/controllerextensions/collaboration/CollaborationCommon.js +146 -0
  64. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/CollaborationCommon.ts +18 -8
  65. package/src/sap/fe/core/controllerextensions/collaboration/Manage.js +264 -0
  66. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/Manage.ts +35 -33
  67. package/src/sap/fe/core/controllerextensions/collaboration/ManageDialog.fragment.xml +100 -0
  68. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/UserDetails.fragment.xml +5 -7
  69. package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.js +1584 -0
  70. package/src/sap/fe/core/{TransactionHelper.ts → controllerextensions/editFlow/TransactionHelper.ts} +190 -159
  71. package/src/sap/fe/core/controllerextensions/editFlow/draft.js +780 -0
  72. package/src/sap/fe/core/{actions → controllerextensions/editFlow}/draft.ts +329 -76
  73. package/src/sap/fe/core/controllerextensions/editFlow/operations.js +1149 -0
  74. package/src/sap/fe/core/{actions → controllerextensions/editFlow}/operations.ts +169 -97
  75. package/src/sap/fe/core/controllerextensions/editFlow/sticky.js +190 -0
  76. package/src/sap/fe/core/{actions → controllerextensions/editFlow}/sticky.ts +76 -12
  77. package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.js +592 -0
  78. package/src/sap/fe/core/{actions → controllerextensions/messageHandler}/messageHandling.ts +83 -60
  79. package/src/sap/fe/core/controllerextensions/routing/RouterProxy.js +940 -0
  80. package/src/sap/fe/core/{RouterProxy.ts → controllerextensions/routing/RouterProxy.ts} +52 -36
  81. package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +21 -18
  82. package/src/sap/fe/core/controls/Any.js +28 -0
  83. package/src/sap/fe/core/controls/Any.ts +30 -0
  84. package/src/sap/fe/core/controls/CommandExecution.js +50 -16
  85. package/src/sap/fe/core/controls/CommandExecution.ts +31 -22
  86. package/src/sap/fe/core/controls/ConditionalWrapper.js +136 -65
  87. package/src/sap/fe/core/controls/ConditionalWrapper.ts +49 -58
  88. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.js +371 -0
  89. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.ts +282 -0
  90. package/src/sap/fe/core/controls/CustomQuickViewPage.js +74 -36
  91. package/src/sap/fe/core/controls/CustomQuickViewPage.ts +23 -32
  92. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossDraft.fragment.xml +52 -5
  93. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +127 -67
  94. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +127 -67
  95. package/src/sap/fe/core/controls/FieldWrapper.js +171 -87
  96. package/src/sap/fe/core/controls/FieldWrapper.ts +69 -80
  97. package/src/sap/fe/core/controls/FileWrapper.js +360 -0
  98. package/src/sap/fe/core/controls/FileWrapper.ts +202 -0
  99. package/src/sap/fe/core/controls/FilterBar.js +154 -119
  100. package/src/sap/fe/core/controls/FilterBar.ts +128 -123
  101. package/src/sap/fe/core/controls/FormElementWrapper.js +102 -37
  102. package/src/sap/fe/core/controls/FormElementWrapper.ts +43 -35
  103. package/src/sap/fe/core/controls/MassEditSelect.js +33 -0
  104. package/src/sap/fe/core/controls/MassEditSelect.ts +45 -0
  105. package/src/sap/fe/core/controls/filterbar/FilterContainer.js +111 -89
  106. package/src/sap/fe/core/controls/filterbar/FilterContainer.ts +86 -82
  107. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +242 -193
  108. package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +211 -204
  109. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +152 -116
  110. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +105 -105
  111. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +2 -2
  112. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +23 -28
  113. package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +41 -81
  114. package/src/sap/fe/core/controls/massEdit/MassEditField.fragment.xml +107 -0
  115. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +550 -35
  116. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +604 -35
  117. package/src/sap/fe/core/converters/ManifestSettings.js +3 -1
  118. package/src/sap/fe/core/converters/ManifestSettings.ts +9 -2
  119. package/src/sap/fe/core/converters/MetaModelConverter.js +11 -40
  120. package/src/sap/fe/core/converters/MetaModelConverter.ts +56 -84
  121. package/src/sap/fe/core/converters/annotations/DataField.js +20 -5
  122. package/src/sap/fe/core/converters/annotations/DataField.ts +27 -6
  123. package/src/sap/fe/core/converters/controls/Common/Action.js +14 -21
  124. package/src/sap/fe/core/converters/controls/Common/Action.ts +23 -28
  125. package/src/sap/fe/core/converters/controls/Common/Chart.js +17 -10
  126. package/src/sap/fe/core/converters/controls/Common/Chart.ts +20 -14
  127. package/src/sap/fe/core/converters/controls/Common/Form.js +16 -18
  128. package/src/sap/fe/core/converters/controls/Common/Form.ts +20 -20
  129. package/src/sap/fe/core/converters/controls/Common/KPI.js +1 -1
  130. package/src/sap/fe/core/converters/controls/Common/KPI.ts +2 -3
  131. package/src/sap/fe/core/converters/controls/Common/Table.js +389 -173
  132. package/src/sap/fe/core/converters/controls/Common/Table.ts +440 -244
  133. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +26 -16
  134. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +27 -19
  135. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +78 -47
  136. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +146 -107
  137. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +6 -6
  138. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +20 -18
  139. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +30 -25
  140. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +39 -34
  141. package/src/sap/fe/core/converters/helpers/Aggregation.js +10 -2
  142. package/src/sap/fe/core/converters/helpers/Aggregation.ts +18 -13
  143. package/src/sap/fe/core/converters/helpers/BindingHelper.js +3 -2
  144. package/src/sap/fe/core/converters/helpers/BindingHelper.ts +6 -5
  145. package/src/sap/fe/core/converters/objectPage/FormMenuActions.js +1 -1
  146. package/src/sap/fe/core/converters/objectPage/FormMenuActions.ts +0 -4
  147. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +27 -24
  148. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +49 -40
  149. package/src/sap/fe/core/converters/templates/ListReportConverter.js +33 -22
  150. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +77 -62
  151. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +28 -28
  152. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +38 -45
  153. package/src/sap/fe/core/designtime/AppComponent.designtime.js +3 -3
  154. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +8 -6
  155. package/src/sap/fe/core/formatters/KPIFormatter.js +3 -12
  156. package/src/sap/fe/core/formatters/KPIFormatter.ts +3 -2
  157. package/src/sap/fe/core/formatters/TableFormatter.js +74 -13
  158. package/src/sap/fe/core/formatters/TableFormatter.ts +71 -16
  159. package/src/sap/fe/core/formatters/ValueFormatter.js +4 -4
  160. package/src/sap/fe/core/formatters/ValueFormatter.ts +4 -7
  161. package/src/sap/fe/core/fpm/Component.js +46 -17
  162. package/src/sap/fe/core/fpm/Component.ts +11 -16
  163. package/src/sap/fe/core/helpers/AppStartupHelper.js +4 -4
  164. package/src/sap/fe/core/helpers/AppStartupHelper.ts +3 -3
  165. package/src/sap/fe/core/helpers/BindingExpression.js +10 -7
  166. package/src/sap/fe/core/helpers/BindingExpression.ts +37 -35
  167. package/src/sap/fe/core/helpers/ClassSupport.js +273 -256
  168. package/src/sap/fe/core/helpers/ClassSupport.ts +315 -237
  169. package/src/sap/fe/core/helpers/FPMHelper.js +3 -2
  170. package/src/sap/fe/core/helpers/FPMHelper.ts +9 -8
  171. package/src/sap/fe/core/helpers/MassEditHelper.js +522 -147
  172. package/src/sap/fe/core/helpers/MassEditHelper.ts +563 -236
  173. package/src/sap/fe/core/helpers/ModelHelper.js +29 -1
  174. package/src/sap/fe/core/helpers/ModelHelper.ts +39 -26
  175. package/src/sap/fe/core/helpers/PasteHelper.js +4 -4
  176. package/src/sap/fe/core/helpers/PasteHelper.ts +4 -3
  177. package/src/sap/fe/core/helpers/SemanticDateOperators.js +3 -3
  178. package/src/sap/fe/core/helpers/SemanticDateOperators.ts +3 -1
  179. package/src/sap/fe/core/helpers/SemanticKeyHelper.js +1 -1
  180. package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +1 -1
  181. package/src/sap/fe/core/helpers/StableIdHelper.js +5 -7
  182. package/src/sap/fe/core/helpers/StableIdHelper.ts +8 -8
  183. package/src/sap/fe/core/{Synchronization.js → helpers/Synchronization.js} +1 -1
  184. package/src/sap/fe/core/{Synchronization.ts → helpers/Synchronization.ts} +1 -1
  185. package/src/sap/fe/core/jsx-runtime/jsx.js +35 -5
  186. package/src/sap/fe/core/jsx-runtime/jsx.ts +22 -8
  187. package/src/sap/fe/core/library.js +13 -5
  188. package/src/sap/fe/core/library.ts +26 -17
  189. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +1 -1
  190. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +0 -3
  191. package/src/sap/fe/core/messagebundle.properties +135 -180
  192. package/src/sap/fe/core/messagebundle_ar.properties +31 -64
  193. package/src/sap/fe/core/messagebundle_bg.properties +31 -64
  194. package/src/sap/fe/core/messagebundle_ca.properties +31 -64
  195. package/src/sap/fe/core/messagebundle_cs.properties +31 -64
  196. package/src/sap/fe/core/messagebundle_cy.properties +32 -65
  197. package/src/sap/fe/core/messagebundle_da.properties +31 -64
  198. package/src/sap/fe/core/messagebundle_de.properties +29 -62
  199. package/src/sap/fe/core/messagebundle_el.properties +32 -65
  200. package/src/sap/fe/core/messagebundle_en.properties +32 -65
  201. package/src/sap/fe/core/messagebundle_en_GB.properties +29 -62
  202. package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +41 -74
  203. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +32 -65
  204. package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +20 -6
  205. package/src/sap/fe/core/messagebundle_es.properties +31 -64
  206. package/src/sap/fe/core/messagebundle_es_MX.properties +31 -64
  207. package/src/sap/fe/core/messagebundle_et.properties +31 -64
  208. package/src/sap/fe/core/messagebundle_fi.properties +29 -62
  209. package/src/sap/fe/core/messagebundle_fr.properties +36 -69
  210. package/src/sap/fe/core/messagebundle_fr_CA.properties +33 -66
  211. package/src/sap/fe/core/messagebundle_hi.properties +29 -62
  212. package/src/sap/fe/core/messagebundle_hr.properties +32 -65
  213. package/src/sap/fe/core/messagebundle_hu.properties +30 -63
  214. package/src/sap/fe/core/messagebundle_id.properties +32 -65
  215. package/src/sap/fe/core/messagebundle_it.properties +31 -64
  216. package/src/sap/fe/core/messagebundle_iw.properties +31 -64
  217. package/src/sap/fe/core/messagebundle_ja.properties +29 -62
  218. package/src/sap/fe/core/messagebundle_kk.properties +31 -64
  219. package/src/sap/fe/core/messagebundle_ko.properties +31 -64
  220. package/src/sap/fe/core/messagebundle_lt.properties +31 -64
  221. package/src/sap/fe/core/messagebundle_lv.properties +32 -65
  222. package/src/sap/fe/core/messagebundle_ms.properties +31 -64
  223. package/src/sap/fe/core/messagebundle_nl.properties +31 -64
  224. package/src/sap/fe/core/messagebundle_no.properties +31 -64
  225. package/src/sap/fe/core/messagebundle_pl.properties +34 -67
  226. package/src/sap/fe/core/messagebundle_pt.properties +32 -65
  227. package/src/sap/fe/core/messagebundle_pt_PT.properties +31 -64
  228. package/src/sap/fe/core/messagebundle_ro.properties +33 -66
  229. package/src/sap/fe/core/messagebundle_ru.properties +33 -66
  230. package/src/sap/fe/core/messagebundle_sh.properties +31 -64
  231. package/src/sap/fe/core/messagebundle_sk.properties +31 -64
  232. package/src/sap/fe/core/messagebundle_sl.properties +29 -62
  233. package/src/sap/fe/core/messagebundle_sv.properties +30 -63
  234. package/src/sap/fe/core/messagebundle_th.properties +31 -64
  235. package/src/sap/fe/core/messagebundle_tr.properties +31 -64
  236. package/src/sap/fe/core/messagebundle_uk.properties +32 -65
  237. package/src/sap/fe/core/messagebundle_vi.properties +31 -64
  238. package/src/sap/fe/core/messagebundle_zh_CN.properties +32 -65
  239. package/src/sap/fe/core/messagebundle_zh_TW.properties +34 -67
  240. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +4 -4
  241. package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +1 -1
  242. package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +5 -5
  243. package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +1 -2
  244. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +11 -8
  245. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +15 -13
  246. package/src/sap/fe/core/services/NavigationServiceFactory.js +5 -5
  247. package/src/sap/fe/core/services/NavigationServiceFactory.ts +9 -5
  248. package/src/sap/fe/core/services/ResourceModelServiceFactory.js +4 -4
  249. package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +1 -1
  250. package/src/sap/fe/core/services/RoutingServiceFactory.js +105 -66
  251. package/src/sap/fe/core/services/RoutingServiceFactory.ts +59 -49
  252. package/src/sap/fe/core/services/ShellServicesFactory.js +104 -29
  253. package/src/sap/fe/core/services/ShellServicesFactory.ts +64 -30
  254. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +4 -4
  255. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +1 -1
  256. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +11 -10
  257. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +38 -51
  258. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +43 -5
  259. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +6 -3
  260. package/src/sap/fe/core/support/CommonHelper.js +1 -1
  261. package/src/sap/fe/core/support/CommonHelper.ts +0 -3
  262. package/src/sap/fe/core/templating/DataModelPathHelper.js +2 -9
  263. package/src/sap/fe/core/templating/DataModelPathHelper.ts +32 -38
  264. package/src/sap/fe/core/templating/DisplayModeFormatter.js +23 -3
  265. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +27 -6
  266. package/src/sap/fe/core/templating/EntitySetHelper.js +1 -9
  267. package/src/sap/fe/core/templating/EntitySetHelper.ts +11 -13
  268. package/src/sap/fe/core/templating/FilterHelper.js +4 -4
  269. package/src/sap/fe/core/templating/FilterHelper.ts +6 -5
  270. package/src/sap/fe/core/templating/PropertyHelper.js +70 -33
  271. package/src/sap/fe/core/templating/PropertyHelper.ts +49 -27
  272. package/src/sap/fe/core/templating/UIFormatters.js +133 -22
  273. package/src/sap/fe/core/templating/UIFormatters.ts +144 -50
  274. package/src/sap/fe/core/type/DateTimeWithTimezone.js +47 -0
  275. package/src/sap/fe/core/type/DateTimeWithTimezone.ts +23 -0
  276. package/src/sap/fe/core/type/Email.js +26 -8
  277. package/src/sap/fe/core/type/Email.ts +8 -7
  278. package/src/sap/fe/core/AnnotationHelper.js +0 -312
  279. package/src/sap/fe/core/AnnotationHelper.ts +0 -315
  280. package/src/sap/fe/core/RouterProxy.js +0 -926
  281. package/src/sap/fe/core/TransactionHelper.js +0 -1562
  282. package/src/sap/fe/core/actions/collaboration/ActivitySync.js +0 -392
  283. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.js +0 -136
  284. package/src/sap/fe/core/actions/collaboration/Manage.js +0 -262
  285. package/src/sap/fe/core/actions/collaboration/ManageDialog.fragment.xml +0 -103
  286. package/src/sap/fe/core/actions/draft.js +0 -523
  287. package/src/sap/fe/core/actions/messageHandling.js +0 -567
  288. package/src/sap/fe/core/actions/nonDraft.js +0 -20
  289. package/src/sap/fe/core/actions/nonDraft.ts +0 -12
  290. package/src/sap/fe/core/actions/operations.js +0 -1096
  291. package/src/sap/fe/core/actions/sticky.js +0 -130
  292. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +0 -78
  293. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.ts +0 -65
  294. package/src/sap/fe/core/formatters/CriticalityFormatter.js +0 -77
  295. package/src/sap/fe/core/formatters/CriticalityFormatter.ts +0 -58
@@ -1,28 +1,31 @@
1
- import ControllerExtension from "sap/ui/core/mvc/ControllerExtension";
2
- import OverrideExecution from "sap/ui/core/mvc/OverrideExecution";
3
1
  import Log from "sap/base/Log";
2
+ import FlexibleColumnLayout from "sap/f/FlexibleColumnLayout";
4
3
  import CommonUtils from "sap/fe/core/CommonUtils";
5
- import BusyLocker from "sap/fe/core/BusyLocker";
6
- import FELibrary from "sap/fe/core/library";
7
- import ODataListBinding from "sap/ui/model/odata/v4/ODataListBinding";
8
- import SemanticKeyHelper from "sap/fe/core/helpers/SemanticKeyHelper";
4
+ import BusyLocker from "sap/fe/core/controllerextensions/BusyLocker";
5
+ import { send } from "sap/fe/core/controllerextensions/collaboration/ActivitySync";
6
+ import { Activity } from "sap/fe/core/controllerextensions/collaboration/CollaborationCommon";
7
+ import draft, { SiblingInformation } from "sap/fe/core/controllerextensions/editFlow/draft";
8
+ import { defineUI5Class, extensible, finalExtension, publicExtension } from "sap/fe/core/helpers/ClassSupport";
9
9
  import EditState from "sap/fe/core/helpers/EditState";
10
- import Message from "sap/ui/core/message/Message";
11
- import coreLibrary from "sap/ui/core/library";
12
10
  import ModelHelper, { InternalModelContext } from "sap/fe/core/helpers/ModelHelper";
13
- import { Extensible, Final, Public, UI5Class } from "sap/fe/core/helpers/ClassSupport";
14
- import ControllerExtensionMetadata from "sap/fe/core/controllerextensions/ControllerExtensionMetadata";
11
+ import SemanticKeyHelper from "sap/fe/core/helpers/SemanticKeyHelper";
12
+ import FELibrary from "sap/fe/core/library";
15
13
  import PageController from "sap/fe/core/PageController";
16
- import ODataMetaModel from "sap/ui/model/odata/v4/ODataMetaModel";
14
+ import { SemanticMapping } from "sap/fe/core/services/RoutingServiceFactory";
15
+ import { standardActions, triggerConfiguredSurvey, triggerType } from "sap/fe/templates/Feedback";
16
+ import NavContainer from "sap/m/NavContainer";
17
+ import Control from "sap/ui/core/Control";
18
+ import Core from "sap/ui/core/Core";
19
+ import coreLibrary from "sap/ui/core/library";
20
+ import Message from "sap/ui/core/message/Message";
21
+ import ControllerExtension from "sap/ui/core/mvc/ControllerExtension";
22
+ import OverrideExecution from "sap/ui/core/mvc/OverrideExecution";
17
23
  import Table from "sap/ui/mdc/Table";
18
24
  import Context from "sap/ui/model/odata/v4/Context";
19
- import ResourceBundle from "sap/base/i18n/ResourceBundle";
20
- import Control from "sap/ui/core/Control";
21
- import { send } from "sap/fe/core/actions/collaboration/ActivitySync";
22
- import { Activity } from "sap/fe/core/actions/collaboration/CollaborationCommon";
25
+ import ODataListBinding from "sap/ui/model/odata/v4/ODataListBinding";
26
+ import ODataMetaModel from "sap/ui/model/odata/v4/ODataMetaModel";
23
27
  import ODataModel from "sap/ui/model/odata/v4/ODataModel";
24
- import FlexibleColumnLayout from "sap/f/FlexibleColumnLayout";
25
- import NavContainer from "sap/m/NavContainer";
28
+ import { CoreEx } from "types/extension_types";
26
29
 
27
30
  const CreationMode = FELibrary.CreationMode,
28
31
  ProgrammingModel = FELibrary.ProgrammingModel,
@@ -30,6 +33,7 @@ const CreationMode = FELibrary.CreationMode,
30
33
  DraftStatus = FELibrary.DraftStatus,
31
34
  EditMode = FELibrary.EditMode,
32
35
  MessageType = coreLibrary.MessageType;
36
+
33
37
  /**
34
38
  * A controller extension offering hooks into the edit flow of the application
35
39
  *
@@ -37,9 +41,9 @@ const CreationMode = FELibrary.CreationMode,
37
41
  * @public
38
42
  * @since 1.90.0
39
43
  */
40
- @UI5Class("sap.fe.core.controllerextensions.EditFlow", ControllerExtensionMetadata)
44
+ @defineUI5Class("sap.fe.core.controllerextensions.EditFlow")
41
45
  class EditFlow extends ControllerExtension {
42
- private base!: PageController;
46
+ protected base!: PageController;
43
47
 
44
48
  //////////////////////////////////////
45
49
  // Public methods
@@ -60,42 +64,51 @@ class EditFlow extends ControllerExtension {
60
64
  * @public
61
65
  * @since 1.90.0
62
66
  */
63
- @Public
64
- @Final
65
- editDocument(oContext: Context): Promise<any> {
67
+ @publicExtension()
68
+ @finalExtension()
69
+ async editDocument(oContext: Context): Promise<void> {
66
70
  const bDraftNavigation = true;
67
71
  const transactionHelper = this._getTransactionHelper();
72
+ const oRootViewController = this._getRootViewController() as any;
73
+ let rightmostContext;
74
+ try {
75
+ await this.base.editFlow.onBeforeEdit({ context: oContext });
76
+ const oNewDocumentContext = await transactionHelper.editDocument(oContext, this.getView(), this._getMessageHandler());
77
+
78
+ const sProgrammingModel = this._getProgrammingModel(oContext);
79
+
80
+ this._setStickySessionInternalProperties(sProgrammingModel, oContext.getModel() as ODataModel);
81
+
82
+ if (oNewDocumentContext) {
83
+ this._setEditMode(EditMode.Editable, false);
84
+ this._getMessageHandler().showMessageDialog();
85
+
86
+ if (oNewDocumentContext !== oContext) {
87
+ let contextToNavigate = oNewDocumentContext;
88
+ if (this._isFclEnabled()) {
89
+ rightmostContext = oRootViewController.getRightmostContext();
90
+ let siblingInfo = await this._computeSiblingInformation(oContext, rightmostContext, sProgrammingModel, true);
91
+ siblingInfo = siblingInfo ?? this._createSiblingInfo(oContext, oNewDocumentContext);
92
+ this._updatePathsInHistory(siblingInfo.pathMapping);
93
+ if (siblingInfo.targetContext.getPath() != oNewDocumentContext.getPath()) {
94
+ contextToNavigate = siblingInfo.targetContext;
95
+ }
96
+ }
68
97
 
69
- return this.base.editFlow
70
- .onBeforeEdit({ context: oContext })
71
- .then(transactionHelper.editDocument.bind(transactionHelper, oContext, this.getView(), this._getMessageHandler()))
72
- .then((oNewDocumentContext: any) => {
73
- const sProgrammingModel = this._getProgrammingModel(oContext);
74
-
75
- if (sProgrammingModel === ProgrammingModel.Sticky) {
76
- this._getInternalModel().setProperty("/sessionOn", true);
77
- }
78
- if (oNewDocumentContext) {
79
- this._setEditMode(EditMode.Editable, false);
80
- this._getMessageHandler().showMessageDialog();
81
-
82
- if (oNewDocumentContext !== oContext) {
83
- return this._handleNewContext(oNewDocumentContext, true, false, bDraftNavigation, true).then(() => {
84
- if (sProgrammingModel === ProgrammingModel.Sticky) {
85
- // The stickyOn handler must be set after the navigation has been done,
86
- // as the URL may change in the case of FCL
87
- this._handleStickyOn(oNewDocumentContext);
88
- }
89
- });
98
+ await this._handleNewContext(contextToNavigate, true, false, bDraftNavigation, true);
99
+ if (sProgrammingModel === ProgrammingModel.Sticky) {
100
+ // The stickyOn handler must be set after the navigation has been done,
101
+ // as the URL may change in the case of FCL
102
+ this._handleStickyOn(oNewDocumentContext);
90
103
  }
91
104
  }
92
- })
93
- .catch(function(oError: any) {
94
- Log.error("Error while editing the document", oError);
95
- });
105
+ }
106
+ } catch (oError) {
107
+ Log.error("Error while editing the document", oError as any);
108
+ }
96
109
  }
97
- @Public
98
- @Final
110
+ @publicExtension()
111
+ @finalExtension()
99
112
  deleteMultipleDocuments(aContexts: any, mParameters: any) {
100
113
  if (mParameters) {
101
114
  mParameters.beforeDeleteCallBack = this.base.editFlow.onBeforeDelete;
@@ -118,18 +131,20 @@ class EditFlow extends ControllerExtension {
118
131
  * @public
119
132
  * @since 1.90.0
120
133
  */
121
- @Public
122
- @Final
123
- updateDocument(oContext: object, oPromise: Promise<any>): Promise<void> {
124
- const transactionHelper = this._getTransactionHelper(),
125
- oBindingContext = this.getView().getBindingContext(),
126
- bIsDraft = this._getProgrammingModel(oContext) === ProgrammingModel.Draft;
134
+ @publicExtension()
135
+ @finalExtension()
136
+ updateDocument(oContext: object, oPromise: Promise<any>): Promise<void> | undefined {
137
+ const transactionHelper = this._getTransactionHelper();
138
+ const originalBindingContext = this.getView().getBindingContext();
139
+ const bIsDraft = this._getProgrammingModel(oContext) === ProgrammingModel.Draft;
127
140
 
128
141
  this._getMessageHandler().removeTransitionMessages();
129
142
  return this._syncTask(() => {
130
- if (oBindingContext) {
143
+ if (originalBindingContext) {
131
144
  transactionHelper.handleDocumentModifications();
132
- EditState.setEditStateDirty();
145
+ if (!this._isFclEnabled()) {
146
+ EditState.setEditStateDirty();
147
+ }
133
148
 
134
149
  if (bIsDraft) {
135
150
  this._setDraftStatus(DraftStatus.Saving);
@@ -140,18 +155,19 @@ class EditFlow extends ControllerExtension {
140
155
  return oPromise
141
156
  .then(
142
157
  () => {
143
- if (bIsDraft && oBindingContext) {
158
+ // If a navigation happened while oPromise was being resolved, the binding context of the page changed
159
+ // In that case, we shouldn't do anything
160
+ const oBindingContext = this.getView().getBindingContext();
161
+ if (bIsDraft && oBindingContext && oBindingContext === originalBindingContext) {
144
162
  const oMetaModel = oBindingContext.getModel().getMetaModel() as ODataMetaModel,
145
163
  sEntitySetName = (oMetaModel as any).getMetaContext(oBindingContext.getPath()).getObject("@sapui.name"),
146
164
  aSemanticKeys = SemanticKeyHelper.getSemanticKeys(oMetaModel, sEntitySetName);
147
165
  if (aSemanticKeys && aSemanticKeys.length) {
148
- const oCurrentSemanticMapping = (this.base.getAppComponent() as any)
149
- .getRoutingService()
150
- .getLastSemanticMapping(),
166
+ const oCurrentSemanticMapping = this._getSemanticMapping(),
151
167
  sCurrentSemanticPath = oCurrentSemanticMapping && oCurrentSemanticMapping.semanticPath,
152
168
  sChangedPath = SemanticKeyHelper.getSemanticPath(oBindingContext, true);
153
-
154
- if (sCurrentSemanticPath !== sChangedPath) {
169
+ // sCurrentSemanticPath could be null if we have navigated via deep link then there are no semanticMappings to calculate it from
170
+ if (sCurrentSemanticPath && sCurrentSemanticPath !== sChangedPath) {
155
171
  return this._handleNewContext(oBindingContext, true, false, true).then(() => {
156
172
  this._setDraftStatus(DraftStatus.Saved);
157
173
  });
@@ -164,12 +180,12 @@ class EditFlow extends ControllerExtension {
164
180
  }
165
181
  },
166
182
  () => {
167
- if (bIsDraft && oBindingContext) {
183
+ if (bIsDraft && originalBindingContext) {
168
184
  this._setDraftStatus(DraftStatus.Clear);
169
185
  }
170
186
  }
171
187
  )
172
- .catch(function(oError: any) {
188
+ .catch(function (oError: any) {
173
189
  Log.error("Error while updating the document", oError);
174
190
  })
175
191
  .finally(() => {
@@ -204,8 +220,8 @@ class EditFlow extends ControllerExtension {
204
220
  * @public
205
221
  * @since 1.90.0
206
222
  */
207
- @Public
208
- @Final
223
+ @publicExtension()
224
+ @finalExtension()
209
225
  createDocument(
210
226
  vListBinding: ODataListBinding | string,
211
227
  mInParameters: {
@@ -216,10 +232,9 @@ class EditFlow extends ControllerExtension {
216
232
  ): Promise<void> {
217
233
  const transactionHelper = this._getTransactionHelper(),
218
234
  oLockObject = this._getGlobalUIModel();
219
- let oTable: Table;
220
- let iCountTableItems = 0;
235
+ let oTable: any; //should be Table but there are missing methods into the def
221
236
  let mParameters: any = mInParameters;
222
- const oResourceBundle = (this.getView().getController() as any).oResourceBundle;
237
+ const oResourceBundle = this._getResourceBundle();
223
238
  const bShouldBusyLock =
224
239
  !mParameters ||
225
240
  (mParameters.creationMode !== CreationMode.Inline &&
@@ -270,7 +285,7 @@ class EditFlow extends ControllerExtension {
270
285
  */
271
286
  const handleSideEffects = (oListBinding: any, oCreationPromise: Promise<Context>) => {
272
287
  oCreationPromise
273
- .then(function(oNewContext: any) {
288
+ .then(function (oNewContext: any) {
274
289
  // transient contexts are reliably removed once oNewContext.created() is resolved
275
290
  return oNewContext.created();
276
291
  })
@@ -286,7 +301,7 @@ class EditFlow extends ControllerExtension {
286
301
  .requestSideEffectsForNavigationProperty(oListBinding.getPath(), oBindingContext);
287
302
  }
288
303
  })
289
- .catch(function(oError: any) {
304
+ .catch(function (oError: any) {
290
305
  Log.error("Error while creating the document", oError);
291
306
  });
292
307
  };
@@ -297,7 +312,7 @@ class EditFlow extends ControllerExtension {
297
312
  const createCustomValidationMessages = (aValidationMessages: any[]) => {
298
313
  const sCustomValidationFunction = oTable && (oTable.getCreationRow() as any).data("customValidationFunction");
299
314
  const mCustomValidity = oTable && oTable.getBindingContext("internal")?.getProperty("creationRowCustomValidity");
300
- const oMessageManager = sap.ui.getCore().getMessageManager();
315
+ const oMessageManager = Core.getMessageManager();
301
316
  const aCustomMessages: any[] = [];
302
317
  let oFieldControl;
303
318
  let sTarget: string;
@@ -306,7 +321,7 @@ class EditFlow extends ControllerExtension {
306
321
  oMessageManager
307
322
  .getMessageModel()
308
323
  .getData()
309
- .forEach(function(oMessage: any) {
324
+ .forEach(function (oMessage: any) {
310
325
  if (oMessage.code === sCustomValidationFunction) {
311
326
  oMessageManager.removeMessages(oMessage);
312
327
  }
@@ -315,14 +330,14 @@ class EditFlow extends ControllerExtension {
315
330
  aValidationMessages.forEach((oValidationMessage: any) => {
316
331
  // Handle Bound CustomValidation message
317
332
  if (oValidationMessage.messageTarget) {
318
- oFieldControl = sap.ui.getCore().getControl(mCustomValidity[oValidationMessage.messageTarget].fieldId) as Control;
333
+ oFieldControl = Core.getControl(mCustomValidity[oValidationMessage.messageTarget].fieldId) as Control;
319
334
  sTarget = oFieldControl.getBindingContext()?.getPath() + "/" + oFieldControl.getBindingPath("value");
320
335
  // Add validation message if still not exists
321
336
  if (
322
337
  oMessageManager
323
338
  .getMessageModel()
324
339
  .getData()
325
- .filter(function(oMessage: any) {
340
+ .filter(function (oMessage: any) {
326
341
  return oMessage.target === sTarget;
327
342
  }).length === 0
328
343
  ) {
@@ -342,7 +357,7 @@ class EditFlow extends ControllerExtension {
342
357
  const aExistingValidationMessages = oMessageManager
343
358
  .getMessageModel()
344
359
  .getData()
345
- .filter(function(oMessage: any) {
360
+ .filter(function (oMessage: any) {
346
361
  return oMessage.target === sTarget;
347
362
  });
348
363
  aExistingValidationMessages[0].addControlId(mCustomValidity[oValidationMessage.messageTarget].fieldId);
@@ -392,7 +407,6 @@ class EditFlow extends ControllerExtension {
392
407
  }
393
408
 
394
409
  const oModel = oListBinding.getModel();
395
- iCountTableItems = oListBinding.iMaxLength || 0;
396
410
  const sCreationMode = mParameters.creationMode;
397
411
 
398
412
  return Promise.resolve(this._getProgrammingModel(oListBinding))
@@ -452,7 +466,7 @@ class EditFlow extends ControllerExtension {
452
466
  // prefill data from creation row
453
467
  oPayload = oCreationRowContext.getObject();
454
468
  mParameters.data = {};
455
- Object.keys(oPayload).forEach(function(sPropertyPath: string) {
469
+ Object.keys(oPayload).forEach(function (sPropertyPath: string) {
456
470
  const oProperty = oMetaModel.getObject(sMetaPath + "/" + sPropertyPath);
457
471
  // ensure navigation properties are not part of the payload, deep create not supported
458
472
  if (oProperty && oProperty.$kind === "NavigationProperty") {
@@ -512,9 +526,9 @@ class EditFlow extends ControllerExtension {
512
526
  if (sProgrammingModel == ProgrammingModel.Sticky || mParameters.createAction) {
513
527
  mArgs.transient = true;
514
528
  }
515
- oNavigation = oCreation.then(function(oNewDocumentContext: any) {
529
+ oNavigation = oCreation.then(function (oNewDocumentContext: any) {
516
530
  if (!oNewDocumentContext) {
517
- const oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core") as ResourceBundle;
531
+ const oResourceBundle = (Core as CoreEx).getLibraryResourceBundle("sap.fe.core");
518
532
  return oRoutingListener.navigateToMessagePage(
519
533
  oResourceBundle.getText("C_COMMON_SAPFE_DATA_RECEIVED_ERROR"),
520
534
  {
@@ -535,7 +549,7 @@ class EditFlow extends ControllerExtension {
535
549
  // the creation row shall be cleared once the validation check was successful and
536
550
  // therefore the POST can be sent async to the backend
537
551
  oNavigation = oValidationCheck
538
- .then(function() {
552
+ .then(function () {
539
553
  const oCreationRowListBinding = oCreationRowContext.getBinding();
540
554
 
541
555
  if (!mParameters.bSkipSideEffects) {
@@ -546,7 +560,7 @@ class EditFlow extends ControllerExtension {
546
560
  oCreationRow.setBindingContext(oNewTransientContext);
547
561
 
548
562
  // this is needed to avoid console errors TO be checked with model colleagues
549
- oNewTransientContext.created().catch(function() {
563
+ oNewTransientContext.created().catch(function () {
550
564
  Log.trace("transient fast creation context deleted");
551
565
  });
552
566
  return oCreationRowContext.delete("$direct");
@@ -564,14 +578,13 @@ class EditFlow extends ControllerExtension {
564
578
  break;
565
579
  }
566
580
 
567
- if (sProgrammingModel === ProgrammingModel.Sticky) {
568
- this._getInternalModel().setProperty("/sessionOn", true);
569
- }
570
581
  const bIsNewPageCreation =
571
582
  mParameters.creationMode !== CreationMode.CreationRow && mParameters.creationMode !== CreationMode.Inline;
572
583
  if (oCreation) {
573
584
  return Promise.all([oCreation, oNavigation])
574
585
  .then((aParams: [any, any]) => {
586
+ this._setStickySessionInternalProperties(sProgrammingModel, oModel);
587
+
575
588
  if (bIsNewPageCreation) {
576
589
  this._setEditMode(EditMode.Editable, bIsNewPageCreation);
577
590
  } else {
@@ -579,15 +592,23 @@ class EditFlow extends ControllerExtension {
579
592
  }
580
593
  const oNewDocumentContext = aParams[0];
581
594
  if (oNewDocumentContext) {
582
- EditState.setEditStateDirty();
583
- send(this.getView(), Activity.Create, oNewDocumentContext);
595
+ if (!this._isFclEnabled()) {
596
+ EditState.setEditStateDirty();
597
+ }
598
+ this._sendActivity(Activity.Create, oNewDocumentContext);
584
599
  if (sProgrammingModel === ProgrammingModel.Sticky) {
585
600
  this._handleStickyOn(oNewDocumentContext);
586
601
  }
587
602
  }
588
603
  })
589
- .catch(function(oError: any) {
590
- if (oError && (oError.navigateBackFromTransientState || oError == Constants.CancelActionDialog)) {
604
+ .catch(function (oError: any) {
605
+ if (
606
+ oError &&
607
+ (oError.navigateBackFromTransientState ||
608
+ oError == Constants.CancelActionDialog ||
609
+ oError.canceled ||
610
+ (oError.rejectedItems && oError.rejectedItems[0].canceled))
611
+ ) {
591
612
  oRoutingListener.navigateBackFromTransientState();
592
613
  }
593
614
 
@@ -596,23 +617,12 @@ class EditFlow extends ControllerExtension {
596
617
  }
597
618
  });
598
619
  })
599
- .finally(function() {
620
+ .finally(function () {
600
621
  if (oTable && oTable.isA("sap.ui.mdc.Table")) {
601
622
  const fnFocusOrScroll =
602
623
  mParameters.creationMode === CreationMode.Inline ? oTable.focusRow.bind(oTable) : oTable.scrollToIndex.bind(oTable);
603
- oTable.getRowBinding().attachEventOnce("change", function() {
604
- switch (mParameters.createAtEnd) {
605
- case true:
606
- if (oTable.data("tableType") === "ResponsiveTable" && oTable.getThreshold()) {
607
- fnFocusOrScroll(oTable.getThreshold(), true);
608
- } else {
609
- fnFocusOrScroll(iCountTableItems, true);
610
- }
611
- break;
612
- case false:
613
- fnFocusOrScroll(0, true);
614
- break;
615
- }
624
+ oTable.getRowBinding().attachEventOnce("change", function () {
625
+ fnFocusOrScroll(mParameters.createAtEnd ? oTable.getRowBinding().getLength() : 0, true);
616
626
  });
617
627
  }
618
628
  bShouldBusyLock && BusyLocker.unlock(oLockObject);
@@ -632,11 +642,10 @@ class EditFlow extends ControllerExtension {
632
642
  * @memberof sap.fe.core.controllerextensions.EditFlow
633
643
  * @alias sap.fe.core.controllerextensions.EditFlow#onBeforeSave
634
644
  * @public
635
- * @experimental As of version 1.90.0
636
645
  * @since 1.90.0
637
646
  */
638
- @Public
639
- @Extensible(OverrideExecution.After)
647
+ @publicExtension()
648
+ @extensible(OverrideExecution.After)
640
649
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
641
650
  onBeforeSave(mParameters?: { context?: Context }): Promise<void> {
642
651
  // to be overridden
@@ -656,11 +665,10 @@ class EditFlow extends ControllerExtension {
656
665
  * @memberof sap.fe.core.controllerextensions.EditFlow
657
666
  * @alias sap.fe.core.controllerextensions.EditFlow#onBeforeCreate
658
667
  * @public
659
- * @experimental As of version 1.98.0
660
668
  * @since 1.98.0
661
669
  */
662
- @Public
663
- @Extensible(OverrideExecution.After)
670
+ @publicExtension()
671
+ @extensible(OverrideExecution.After)
664
672
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
665
673
  onBeforeCreate(mParameters?: { contextPath?: string; createParameters?: any[] }): Promise<void> {
666
674
  // to be overridden
@@ -679,11 +687,10 @@ class EditFlow extends ControllerExtension {
679
687
  * @memberof sap.fe.core.controllerextensions.EditFlow
680
688
  * @alias sap.fe.core.controllerextensions.EditFlow#onBeforeEdit
681
689
  * @public
682
- * @experimental As of version 1.98.0
683
690
  * @since 1.98.0
684
691
  */
685
- @Public
686
- @Extensible(OverrideExecution.After)
692
+ @publicExtension()
693
+ @extensible(OverrideExecution.After)
687
694
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
688
695
  onBeforeEdit(mParameters?: { context?: Context }): Promise<void> {
689
696
  // to be overridden
@@ -702,11 +709,10 @@ class EditFlow extends ControllerExtension {
702
709
  * @memberof sap.fe.core.controllerextensions.EditFlow
703
710
  * @alias sap.fe.core.controllerextensions.EditFlow#onBeforeDiscard
704
711
  * @public
705
- * @experimental As of version 1.98.0
706
712
  * @since 1.98.0
707
713
  */
708
- @Public
709
- @Extensible(OverrideExecution.After)
714
+ @publicExtension()
715
+ @extensible(OverrideExecution.After)
710
716
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
711
717
  onBeforeDiscard(mParameters?: { context?: Context }): Promise<void> {
712
718
  // to be overridden
@@ -725,11 +731,10 @@ class EditFlow extends ControllerExtension {
725
731
  * @memberof sap.fe.core.controllerextensions.EditFlow
726
732
  * @alias sap.fe.core.controllerextensions.EditFlow#onBeforeDelete
727
733
  * @public
728
- * @experimental As of version 1.98.0
729
734
  * @since 1.98.0
730
735
  */
731
- @Public
732
- @Extensible(OverrideExecution.After)
736
+ @publicExtension()
737
+ @extensible(OverrideExecution.After)
733
738
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
734
739
  onBeforeDelete(mParameters?: { contexts?: Context[] }): Promise<void> {
735
740
  // to be overridden
@@ -753,68 +758,80 @@ class EditFlow extends ControllerExtension {
753
758
  * @public
754
759
  * @since 1.90.0
755
760
  */
756
- @Public
757
- @Final
758
- saveDocument(oContext: Context, mParameters: any): Promise<void> {
761
+ @publicExtension()
762
+ @finalExtension()
763
+ async saveDocument(oContext: Context, mParameters: any): Promise<void> {
759
764
  mParameters = mParameters || {};
760
765
  const bExecuteSideEffectsOnError = mParameters.bExecuteSideEffectsOnError || undefined;
761
766
  const bDraftNavigation = true;
762
767
  const transactionHelper = this._getTransactionHelper();
763
- const oResourceBundle = (this.getView().getController() as any).oResourceBundle;
768
+ const oResourceBundle = this._getResourceBundle();
764
769
  const aBindings = mParameters.bindings;
765
- // first of all wait until all key-match-requests are done
766
- return (
767
- this._syncTask()
768
- // submit any open changes if there any (although there are validation/parse errors)
769
- .then(this._submitOpenChanges.bind(this, oContext))
770
- // check if there are any validation/parse errors
771
- .then(this._checkForValidationErrors.bind(this, oContext))
772
- .then(this.base.editFlow.onBeforeSave.bind(this, { context: oContext }))
773
- // and finally if all user changes are submitted and valid save the document
774
- .then(
775
- transactionHelper.saveDocument.bind(
776
- transactionHelper,
777
- oContext,
778
- oResourceBundle,
779
- bExecuteSideEffectsOnError,
780
- aBindings,
781
- this._getMessageHandler()
782
- )
783
- )
784
- .then((oActiveDocumentContext: any) => {
785
- const sProgrammingModel = this._getProgrammingModel(oContext);
786
770
 
787
- this._removeContextsFromPages();
788
- if (sProgrammingModel === ProgrammingModel.Sticky) {
789
- this._getInternalModel().setProperty("/sessionOn", false);
790
- this._handleStickyOff(/*oContext*/);
791
- }
771
+ try {
772
+ await this._syncTask();
773
+ await this._submitOpenChanges(oContext);
774
+ await this._checkForValidationErrors();
775
+ await this.base.editFlow.onBeforeSave({ context: oContext });
776
+
777
+ const sProgrammingModel = this._getProgrammingModel(oContext);
778
+ const oRootViewController = this._getRootViewController() as any;
779
+ let siblingInfo: SiblingInformation | undefined;
780
+ if (
781
+ (sProgrammingModel === ProgrammingModel.Sticky || oContext.getProperty("HasActiveEntity")) &&
782
+ oRootViewController.isFclEnabled()
783
+ ) {
784
+ // No need to try to get rightmost context in case of a new object
785
+ siblingInfo = await this._computeSiblingInformation(
786
+ oContext,
787
+ oRootViewController.getRightmostContext(),
788
+ sProgrammingModel,
789
+ true
790
+ );
791
+ }
792
+
793
+ const activeDocumentContext = await transactionHelper.saveDocument(
794
+ oContext,
795
+ oResourceBundle,
796
+ bExecuteSideEffectsOnError,
797
+ aBindings,
798
+ this._getMessageHandler()
799
+ );
800
+
801
+ this._removeContextsFromPages();
802
+ this._removeStickySessionInternalProperties(sProgrammingModel);
792
803
 
793
- send(this.getView(), Activity.Activate, oActiveDocumentContext);
804
+ this._sendActivity(Activity.Activate, activeDocumentContext);
805
+ this._triggerConfiguredSurvey(standardActions.save, triggerType.standardAction);
794
806
 
795
- this._setEditMode(EditMode.Display, false);
796
- this._getMessageHandler().showMessageDialog();
807
+ this._setEditMode(EditMode.Display, false);
808
+ this._getMessageHandler().showMessageDialog();
797
809
 
798
- if (oActiveDocumentContext !== oContext) {
799
- this._handleNewContext(oActiveDocumentContext, false, false, bDraftNavigation, true);
810
+ if (activeDocumentContext !== oContext) {
811
+ let contextToNavigate = activeDocumentContext;
812
+ if (oRootViewController.isFclEnabled()) {
813
+ siblingInfo = siblingInfo ?? this._createSiblingInfo(oContext, activeDocumentContext);
814
+ this._updatePathsInHistory(siblingInfo.pathMapping);
815
+ if (siblingInfo.targetContext.getPath() !== activeDocumentContext.getPath()) {
816
+ contextToNavigate = siblingInfo.targetContext;
800
817
  }
801
- })
802
- .catch(function(oError: any) {
803
- Log.error("Error while saving the document", oError);
804
- return Promise.reject(oError);
805
- })
806
- );
818
+ }
819
+
820
+ await this._handleNewContext(contextToNavigate, false, false, bDraftNavigation, true);
821
+ }
822
+ } catch (oError: any) {
823
+ if (!(oError && oError.canceled)) {
824
+ Log.error("Error while saving the document", oError);
825
+ }
826
+ return Promise.reject(oError);
827
+ }
807
828
  }
808
- @Public
809
- @Final
810
- toggleDraftActive(oContext: any) {
829
+ @publicExtension()
830
+ @finalExtension()
831
+ async toggleDraftActive(oContext: Context): Promise<void> {
811
832
  const oContextData = oContext.getObject();
812
833
  let bEditable: boolean;
813
834
  const bIsDraft = oContext && this._getProgrammingModel(oContext) === ProgrammingModel.Draft;
814
- const oToggleContext = oContext
815
- .getModel()
816
- .bindContext(oContext.getPath() + "/SiblingEntity")
817
- .getBoundContext();
818
835
 
819
836
  //toggle between draft and active document is only available for edit drafts and active documents with draft)
820
837
  if (
@@ -830,27 +847,34 @@ class EditFlow extends ControllerExtension {
830
847
  if (!oContextData.IsActiveEntity && oContextData.HasActiveEntity) {
831
848
  //start Point: edit draft
832
849
  bEditable = false;
833
- } else if (oContextData.IsActiveEntity && oContextData.HasDraftEntity) {
850
+ } else {
834
851
  // start point active document
835
852
  bEditable = true;
836
853
  }
837
- oToggleContext
838
- .requestCanonicalPath()
839
- .then(function(sCanonicalPath: any) {
840
- // We use the canonical path for the navigation instead of the semantic path, as the
841
- // semantic key values may have changed between the draft and the active version (BCP 2170216142)
842
- return oToggleContext
843
- .getModel()
844
- .bindContext(sCanonicalPath)
845
- .getBoundContext();
846
- })
847
- .then((oToggleContext: any) => {
854
+
855
+ try {
856
+ const oRootViewController = this._getRootViewController() as any;
857
+ const oRightmostContext = oRootViewController.isFclEnabled() ? oRootViewController.getRightmostContext() : oContext;
858
+ const siblingInfo = await this._computeSiblingInformation(oContext, oRightmostContext, ProgrammingModel.Draft, false);
859
+ if (siblingInfo) {
848
860
  this._setEditMode(bEditable ? EditMode.Editable : EditMode.Display, false); //switch to edit mode only if a draft is available
849
- this._handleNewContext(oToggleContext, bEditable, true, true, true);
850
- })
851
- .catch(function(err: any) {
852
- return Promise.reject("Error in EditFlow.toggleDraftActive:" + err);
853
- });
861
+
862
+ if (oRootViewController.isFclEnabled()) {
863
+ const lastSemanticMapping = this._getSemanticMapping();
864
+ if (lastSemanticMapping?.technicalPath === oContext.getPath()) {
865
+ const targetPath = siblingInfo.pathMapping[siblingInfo.pathMapping.length - 1].newPath;
866
+ siblingInfo.pathMapping.push({ oldPath: lastSemanticMapping!.semanticPath, newPath: targetPath });
867
+ }
868
+ this._updatePathsInHistory(siblingInfo.pathMapping);
869
+ }
870
+
871
+ await this._handleNewContext(siblingInfo.targetContext, bEditable, true, true, true, false);
872
+ } else {
873
+ return Promise.reject("Error in EditFlow.toggleDraftActive - Cannot find sibling");
874
+ }
875
+ } catch (oError) {
876
+ return Promise.reject(("Error in EditFlow.toggleDraftActive:" + oError) as any);
877
+ }
854
878
  }
855
879
 
856
880
  // Internal only params ---
@@ -861,7 +885,7 @@ class EditFlow extends ControllerExtension {
861
885
  * Discard the editable document.
862
886
  *
863
887
  * @memberof sap.fe.core.controllerextensions.EditFlow
864
- * @param {object} oContext Context of the editable document
888
+ * @param oContext Context of the editable document
865
889
  * @param {map} mParameters Can contain the following attributes:
866
890
  * @param {object} mParameters.control This is the control used to open the discard popover
867
891
  * @param {boolean} mParameters.skipDiscardPopover Optional, supresses the discard popover and allows custom handling
@@ -870,58 +894,86 @@ class EditFlow extends ControllerExtension {
870
894
  * @public
871
895
  * @since 1.90.0
872
896
  */
873
- @Public
874
- @Final
875
- cancelDocument(oContext: object, mParameters: { control: object; skipDiscardPopover?: boolean }): Promise<void> {
876
- const transactionHelper = this._getTransactionHelper(),
877
- oResourceBundle = (this.getView().getController() as any).oResourceBundle;
897
+ @publicExtension()
898
+ @finalExtension()
899
+ async cancelDocument(oContext: Context, mParameters: { control: object; skipDiscardPopover?: boolean }): Promise<any> {
900
+ const transactionHelper = this._getTransactionHelper();
901
+ const oResourceBundle = this._getResourceBundle();
878
902
  const mInParameters: any = mParameters;
903
+ let siblingInfo: SiblingInformation | undefined;
904
+
879
905
  mInParameters.cancelButton = mParameters.control || mInParameters.cancelButton;
880
906
  mInParameters.beforeCancelCallBack = this.base.editFlow.onBeforeDiscard;
881
- return this._syncTask()
882
- .then(
883
- transactionHelper.cancelDocument.bind(transactionHelper, oContext, mParameters, oResourceBundle, this._getMessageHandler())
884
- )
885
- .then((oActiveDocumentContext: any) => {
886
- const bDraftNavigation = true,
887
- sProgrammingModel = this._getProgrammingModel(oContext);
888
-
889
- this._removeContextsFromPages();
890
- if (sProgrammingModel === ProgrammingModel.Sticky) {
891
- this._getInternalModel().setProperty("/sessionOn", false);
892
- this._handleStickyOff(/*oContext*/);
893
- }
894
907
 
895
- send(this.getView(), Activity.Discard, oActiveDocumentContext);
908
+ try {
909
+ await this._syncTask();
910
+ const sProgrammingModel = this._getProgrammingModel(oContext);
911
+ if ((sProgrammingModel === ProgrammingModel.Sticky || oContext.getProperty("HasActiveEntity")) && this._isFclEnabled()) {
912
+ const oRootViewController = this._getRootViewController() as any;
913
+
914
+ // No need to try to get rightmost context in case of a new object
915
+ siblingInfo = await this._computeSiblingInformation(
916
+ oContext,
917
+ oRootViewController.getRightmostContext(),
918
+ sProgrammingModel,
919
+ true
920
+ );
921
+ }
896
922
 
897
- this._setEditMode(EditMode.Display, false);
898
- this._setDraftStatus(DraftStatus.Clear);
923
+ const oActiveDocumentContext = await transactionHelper.cancelDocument(
924
+ oContext,
925
+ mInParameters,
926
+ oResourceBundle,
927
+ this._getMessageHandler()
928
+ );
929
+ const bDraftNavigation = true;
930
+
931
+ this._removeContextsFromPages();
932
+ this._removeStickySessionInternalProperties(sProgrammingModel);
933
+
934
+ this._setEditMode(EditMode.Display, false);
935
+ this._setDraftStatus(DraftStatus.Clear);
936
+ // we force the edit state even for FCL because the draft discard might not be implemented
937
+ // and we may just delete the draft
938
+ EditState.setEditStateDirty();
939
+
940
+ if (!oActiveDocumentContext) {
941
+ this._sendActivity(Activity.Discard, undefined);
942
+ //in case of a new document, no activeContext is returned --> navigate back.
943
+ if (!mInParameters.skipBackNavigation) {
944
+ await this._getRoutingListener().navigateBackFromContext(oContext);
945
+ }
946
+ } else {
947
+ this._sendActivity(Activity.Discard, oActiveDocumentContext);
948
+ let contextToNavigate = oActiveDocumentContext;
949
+ if (this._isFclEnabled()) {
950
+ siblingInfo = siblingInfo ?? this._createSiblingInfo(oContext, oActiveDocumentContext);
951
+ this._updatePathsInHistory(siblingInfo.pathMapping);
952
+ if (siblingInfo.targetContext.getPath() !== oActiveDocumentContext.getPath()) {
953
+ contextToNavigate = siblingInfo.targetContext;
954
+ }
955
+ }
899
956
 
900
- //in case of a new document, the value of hasActiveEntity is returned. navigate back.
901
- if (!oActiveDocumentContext) {
902
- EditState.setEditStateDirty();
903
- return mInParameters.skipBackNavigation ? undefined : this._getRoutingListener().navigateBackFromContext(oContext);
904
- } else if (sProgrammingModel === ProgrammingModel.Draft) {
957
+ if (sProgrammingModel === ProgrammingModel.Draft) {
905
958
  // We need to load the semantic keys of the active context, as we need them
906
959
  // for the navigation
907
- return this._fetchSemanticKeyValues(oActiveDocumentContext).then(() => {
908
- // We force the recreation of the context, so that it's created and bound in the same microtask,
909
- // so that all properties are loaded together by autoExpandSelect, so that when switching back to Edit mode
910
- // $$inheritExpandSelect takes all loaded properties into account (BCP 2070462265)
911
- if (mInParameters.skipBindingToView) {
912
- return oActiveDocumentContext;
913
- } else {
914
- return this._handleNewContext(oActiveDocumentContext, false, true, bDraftNavigation, true);
915
- }
916
- });
960
+ await this._fetchSemanticKeyValues(oActiveDocumentContext);
961
+ // We force the recreation of the context, so that it's created and bound in the same microtask,
962
+ // so that all properties are loaded together by autoExpandSelect, so that when switching back to Edit mode
963
+ // $$inheritExpandSelect takes all loaded properties into account (BCP 2070462265)
964
+ if (!mInParameters.skipBindingToView) {
965
+ await this._handleNewContext(contextToNavigate, false, true, bDraftNavigation, true);
966
+ } else {
967
+ return oActiveDocumentContext;
968
+ }
917
969
  } else {
918
970
  //active context is returned in case of cancel of existing document
919
- return this._handleNewContext(oActiveDocumentContext, false, false, bDraftNavigation, true);
971
+ await this._handleNewContext(contextToNavigate, false, false, bDraftNavigation, true);
920
972
  }
921
- })
922
- .catch(function(oError: any) {
923
- Log.error("Error while discarding the document", oError);
924
- });
973
+ }
974
+ } catch (oError) {
975
+ Log.error("Error while discarding the document", oError as any);
976
+ }
925
977
  }
926
978
 
927
979
  // Internal only params ---
@@ -940,11 +992,10 @@ class EditFlow extends ControllerExtension {
940
992
  * @public
941
993
  * @since 1.90.0
942
994
  */
943
- @Public
944
- @Final
995
+ @publicExtension()
996
+ @finalExtension()
945
997
  deleteDocument(oContext: Context, mInParameters: { title: string; description: string }): Promise<void> {
946
998
  const oAppComponent = CommonUtils.getAppComponent(this.getView());
947
- const sPath = oContext.getPath();
948
999
  let mParameters: any = mInParameters;
949
1000
  if (!mParameters) {
950
1001
  mParameters = {
@@ -958,9 +1009,10 @@ class EditFlow extends ControllerExtension {
958
1009
  .then(() => {
959
1010
  // Single objet deletion is triggered from an OP header button (not from a list)
960
1011
  // --> Mark UI dirty and navigate back to dismiss the OP
961
- EditState.setEditStateDirty();
962
-
963
- send(this.getView(), Activity.Delete, sPath);
1012
+ if (!this._isFclEnabled()) {
1013
+ EditState.setEditStateDirty();
1014
+ }
1015
+ this._sendActivity(Activity.Delete, oContext);
964
1016
 
965
1017
  this._getRoutingListener().navigateBackFromContext(oContext);
966
1018
  // After delete is successfull, we need to dettch the setBackNavigation Methods
@@ -968,7 +1020,7 @@ class EditFlow extends ControllerExtension {
968
1020
  oAppComponent.getShellServices().setBackNavigation();
969
1021
  }
970
1022
  })
971
- .catch(function(oError: any) {
1023
+ .catch(function (oError: any) {
972
1024
  Log.error("Error while deleting the document", oError);
973
1025
  });
974
1026
  }
@@ -983,26 +1035,23 @@ class EditFlow extends ControllerExtension {
983
1035
  * @public
984
1036
  * @since 1.90.0
985
1037
  */
986
- @Public
987
- @Final
988
- applyDocument(oContext: object): Promise<void> {
1038
+ @publicExtension()
1039
+ @finalExtension()
1040
+ async applyDocument(oContext: object): Promise<void> {
989
1041
  const oLockObject = this._getGlobalUIModel();
990
1042
  BusyLocker.lock(oLockObject);
991
- return (
992
- this._submitOpenChanges(oContext)
993
- // check if there are any validation/parse errors
994
- .then(this._checkForValidationErrors.bind(this, oContext))
995
- .then(() => {
996
- this._getMessageHandler().showMessageDialog();
997
- this._getRoutingListener().navigateBackFromContext(oContext);
998
- return true;
999
- })
1000
- .finally(function() {
1001
- if (BusyLocker.isLocked(oLockObject)) {
1002
- BusyLocker.unlock(oLockObject);
1003
- }
1004
- })
1005
- );
1043
+
1044
+ try {
1045
+ await this._syncTask();
1046
+ await this._submitOpenChanges(oContext);
1047
+ await this._checkForValidationErrors();
1048
+ await this._getMessageHandler().showMessageDialog();
1049
+ await this._getRoutingListener().navigateBackFromContext(oContext);
1050
+ } finally {
1051
+ if (BusyLocker.isLocked(oLockObject)) {
1052
+ BusyLocker.unlock(oLockObject);
1053
+ }
1054
+ }
1006
1055
  }
1007
1056
 
1008
1057
  // Internal only params ---
@@ -1028,8 +1077,8 @@ class EditFlow extends ControllerExtension {
1028
1077
  * @since 1.90.0
1029
1078
  * @final
1030
1079
  **/
1031
- @Public
1032
- @Final
1080
+ @publicExtension()
1081
+ @finalExtension()
1033
1082
  invokeAction(
1034
1083
  sActionName: string,
1035
1084
  mInParameters?: {
@@ -1113,11 +1162,8 @@ class EditFlow extends ControllerExtension {
1113
1162
  oBindingContext = oCurrentControl.getBindingContext();
1114
1163
  if (
1115
1164
  oBindingContext &&
1116
- oBindingContext
1117
- .getModel()
1118
- .getMetaModel()
1119
- .getMetaContext(oBindingContext.getPath())
1120
- .getObject("$Type") === sOverloadEntityType
1165
+ oBindingContext.getModel().getMetaModel().getMetaContext(oBindingContext.getPath()).getObject("$Type") ===
1166
+ sOverloadEntityType
1121
1167
  ) {
1122
1168
  mParameters.contexts = oBindingContext;
1123
1169
  break;
@@ -1144,12 +1190,7 @@ class EditFlow extends ControllerExtension {
1144
1190
  oCurrentActionCallBacks = this._createActionPromise(sActionName, oControl.sId);
1145
1191
  }
1146
1192
  }
1147
-
1148
- if (mParameters.isNavigable) {
1149
- mParameters.bGetBoundContext = false;
1150
- } else {
1151
- mParameters.bGetBoundContext = true;
1152
- }
1193
+ mParameters.bGetBoundContext = this._getBoundContext(oView, mParameters);
1153
1194
  // Need to know that the action is called from ObjectPage for changeSet Isolated workaround
1154
1195
  mParameters.bObjectPage = (oView.getViewData() as any).converterType === "ObjectPage";
1155
1196
  return this._syncTask()
@@ -1161,13 +1202,14 @@ class EditFlow extends ControllerExtension {
1161
1202
  return this._refreshListIfRequired(
1162
1203
  this._getActionResponseDataAndKeys(sActionName, oResponse),
1163
1204
  mParameters.contexts[0]
1164
- ).then(function() {
1205
+ ).then(function () {
1165
1206
  return oResponse;
1166
1207
  });
1167
1208
  }
1168
1209
  })
1169
1210
  .then((oResponse: any) => {
1170
- send(this.getView(), Activity.Action, mParameters.contexts);
1211
+ this._sendActivity(Activity.Action, mParameters.contexts);
1212
+ this._triggerConfiguredSurvey(sActionName, triggerType.action);
1171
1213
 
1172
1214
  if (oCurrentActionCallBacks) {
1173
1215
  oCurrentActionCallBacks.fResolver(oResponse);
@@ -1185,7 +1227,9 @@ class EditFlow extends ControllerExtension {
1185
1227
  first one as they are anyway siblings
1186
1228
  */
1187
1229
  if (mParameters.contexts) {
1188
- EditState.setEditStateDirty();
1230
+ if (!this._isFclEnabled()) {
1231
+ EditState.setEditStateDirty();
1232
+ }
1189
1233
  this._getInternalModel().setProperty("/sCustomAction", sActionName);
1190
1234
  }
1191
1235
  if (mParameters.isNavigable) {
@@ -1210,14 +1254,16 @@ class EditFlow extends ControllerExtension {
1210
1254
  }
1211
1255
  }
1212
1256
  })
1213
- .catch(function(err: any) {
1257
+ .catch(function (err: any) {
1214
1258
  if (oCurrentActionCallBacks) {
1215
1259
  oCurrentActionCallBacks.fRejector();
1216
1260
  }
1217
1261
  if (err == Constants.CancelActionDialog) {
1218
1262
  return Promise.reject("Dialog cancelled.");
1219
1263
  } else {
1220
- return Promise.reject("Error in EditFlow.invokeAction:" + err);
1264
+ if (!(err && (err.canceled || (err.rejectedItems && err.rejectedItems[0].canceled)))) {
1265
+ return Promise.reject("Error in EditFlow.invokeAction:" + err);
1266
+ }
1221
1267
  }
1222
1268
  });
1223
1269
  }
@@ -1238,8 +1284,8 @@ class EditFlow extends ControllerExtension {
1238
1284
  * @experimental As of version 1.90.0
1239
1285
  * @since 1.90.0
1240
1286
  */
1241
- @Public
1242
- @Final
1287
+ @publicExtension()
1288
+ @finalExtension()
1243
1289
  securedExecution(
1244
1290
  fnFunction: Function,
1245
1291
  mParameters?: {
@@ -1275,7 +1321,9 @@ class EditFlow extends ControllerExtension {
1275
1321
  .then(() => {
1276
1322
  if (bUpdatesDocument) {
1277
1323
  this._getTransactionHelper().handleDocumentModifications();
1278
- EditState.setEditStateDirty();
1324
+ if (!this._isFclEnabled()) {
1325
+ EditState.setEditStateDirty();
1326
+ }
1279
1327
  if (bIsDraft) {
1280
1328
  this._setDraftStatus(DraftStatus.Saved);
1281
1329
  }
@@ -1300,33 +1348,43 @@ class EditFlow extends ControllerExtension {
1300
1348
  *
1301
1349
  * @param oEvent
1302
1350
  */
1303
- @Public
1351
+ @publicExtension()
1304
1352
  handlePatchSent(oEvent: any) {
1305
- this.mPatchPromises = this.mPatchPromises ? this.mPatchPromises : {};
1306
- // do this for every unique object (eg: every table) so that each associated promise is fulfilled at the end
1307
- const oPatchPromise = new Promise((resolve, reject) => {
1308
- this.mPatchPromises[oEvent.getSource()] = {
1309
- resolvePatchPromise: resolve,
1310
- rejectPatchPromise: reject
1311
- };
1312
- });
1313
- this.updateDocument(oEvent.getSource(), oPatchPromise);
1353
+ if (!(this.base.getView()?.getBindingContext("internal") as InternalModelContext)?.getProperty("skipPatchHandlers")) {
1354
+ // Create a promise that will be resolved or rejected when the path is completed
1355
+ const oPatchPromise = new Promise<void>((resolve, reject) => {
1356
+ oEvent.getSource().attachEventOnce("patchCompleted", (oEvent: any) => {
1357
+ const bSuccess = oEvent.getParameter("success");
1358
+ if (bSuccess) {
1359
+ resolve();
1360
+ } else {
1361
+ reject();
1362
+ }
1363
+ });
1364
+ });
1365
+ this.updateDocument(oEvent.getSource(), oPatchPromise);
1366
+ }
1314
1367
  }
1315
1368
 
1316
1369
  /**
1317
- * Handles the patchCompleted event: resolves or rejects document modification.
1370
+ * Handles the CreateActivate event.
1318
1371
  *
1319
1372
  * @param oEvent
1320
1373
  */
1321
- @Public
1322
- handlePatchCompleted(oEvent: any) {
1323
- const bSuccess = oEvent.getParameter("success");
1324
- if (bSuccess) {
1325
- this.mPatchPromises[oEvent.getSource()].resolvePatchPromise();
1326
- } else {
1327
- this.mPatchPromises[oEvent.getSource()].rejectPatchPromise();
1328
- }
1329
- delete this.mPatchPromises[oEvent.getSource()];
1374
+ handleCreateActivate(oEvent: any) {
1375
+ const oBinding = oEvent.getSource();
1376
+ const transactionHelper = this._getTransactionHelper();
1377
+ const bAtEnd = true;
1378
+ const bInactive = true;
1379
+ const oResourceBundle = this._getResourceBundle();
1380
+ const oParams: any = {
1381
+ creationMode: CreationMode.Inline,
1382
+ createAtEnd: bAtEnd,
1383
+ inactive: bInactive,
1384
+ keepTransientContextOnFailed: false, // currently not fully supported
1385
+ busyMode: "None"
1386
+ };
1387
+ transactionHelper.createDocument(oBinding, oParams, oResourceBundle, this._getMessageHandler(), false, this.getView());
1330
1388
  }
1331
1389
 
1332
1390
  //////////////////////////////////////
@@ -1379,6 +1437,18 @@ class EditFlow extends ControllerExtension {
1379
1437
  return (this.base.getView().getController() as PageController)._editFlow.getInternalModel();
1380
1438
  }
1381
1439
 
1440
+ _getRootViewController() {
1441
+ return this.base.getAppComponent().getRootViewController();
1442
+ }
1443
+
1444
+ _getResourceBundle() {
1445
+ return (this.getView().getController() as any).oResourceBundle;
1446
+ }
1447
+
1448
+ _getSemanticMapping(): SemanticMapping | undefined {
1449
+ return this.base.getAppComponent().getRoutingService().getLastSemanticMapping();
1450
+ }
1451
+
1382
1452
  /**
1383
1453
  * Creates a new promise to wait for an action to be executed
1384
1454
  *
@@ -1405,6 +1475,15 @@ class EditFlow extends ControllerExtension {
1405
1475
  return (this.base.getView().getController() as PageController)._editFlow.getMessageHandler();
1406
1476
  }
1407
1477
 
1478
+ _sendActivity(action: Activity, relatedContexts: Context | Context[] | undefined) {
1479
+ const content = Array.isArray(relatedContexts) ? relatedContexts.map((context) => context.getPath()) : relatedContexts?.getPath();
1480
+ send(this.getView(), action, content);
1481
+ }
1482
+
1483
+ _triggerConfiguredSurvey(sActionName: string, triggerType: triggerType) {
1484
+ triggerConfiguredSurvey(this.getView(), sActionName, triggerType);
1485
+ }
1486
+
1408
1487
  /**
1409
1488
  * @function
1410
1489
  * @name _getActionResponseDataAndKeys
@@ -1417,23 +1496,29 @@ class EditFlow extends ControllerExtension {
1417
1496
  return (this.base.getView().getController() as PageController)._editFlow.getActionResponseDataAndKeys(sActionName, oResponse);
1418
1497
  }
1419
1498
 
1420
- _submitOpenChanges(oContext: any) {
1499
+ async _submitOpenChanges(oContext: any): Promise<any> {
1421
1500
  const oModel = oContext.getModel(),
1422
1501
  oLockObject = this._getGlobalUIModel();
1423
- //Currently we are using only 1 updateGroupId, hence submitting the batch directly here
1424
- return oModel
1425
- .submitBatch("$auto")
1426
- .then(function() {
1427
- if (oModel.hasPendingChanges("$auto")) {
1428
- // the submit was not successful
1429
- return Promise.reject("submit of open changes failed");
1430
- }
1431
- })
1432
- .finally(function() {
1433
- if (BusyLocker.isLocked(oLockObject)) {
1434
- BusyLocker.unlock(oLockObject);
1435
- }
1436
- });
1502
+
1503
+ try {
1504
+ // Submit any leftover changes that are not yet submitted
1505
+ // Currently we are using only 1 updateGroupId, hence submitting the batch directly here
1506
+ await oModel.submitBatch("$auto");
1507
+
1508
+ // Wait for all currently running changes
1509
+ // For the time being we agreed with the v4 model team to use an internal method. We'll replace it once
1510
+ // a public or restricted method was provided
1511
+ await oModel.oRequestor.waitForRunningChangeRequests("$auto");
1512
+
1513
+ // Check if all changes were submitted successfully
1514
+ if (oModel.hasPendingChanges("$auto")) {
1515
+ throw new Error("submit of open changes failed");
1516
+ }
1517
+ } finally {
1518
+ if (BusyLocker.isLocked(oLockObject)) {
1519
+ BusyLocker.unlock(oLockObject);
1520
+ }
1521
+ }
1437
1522
  }
1438
1523
 
1439
1524
  _handleStickyOn(oContext: Context) {
@@ -1452,20 +1537,54 @@ class EditFlow extends ControllerExtension {
1452
1537
  return (this.base.getView().getController() as PageController)._editFlow.discardStickySession(oContext);
1453
1538
  }
1454
1539
 
1455
- _handleNewContext(oContext: any, bEditable: boolean, bRecreateContext: boolean, bDraftNavigation: boolean, bForceFocus?: boolean) {
1456
- EditState.setEditStateDirty();
1540
+ _setStickySessionInternalProperties(programmingModel: any, model: ODataModel) {
1541
+ if (programmingModel === ProgrammingModel.Sticky) {
1542
+ const internalModel = this._getInternalModel();
1543
+ internalModel.setProperty("/sessionOn", true);
1544
+ internalModel.setProperty("/stickySessionToken", (model.getHttpHeaders(true) as any)["SAP-ContextId"]);
1545
+ }
1546
+ }
1547
+
1548
+ _removeStickySessionInternalProperties(programmingModel: any) {
1549
+ if (programmingModel === ProgrammingModel.Sticky) {
1550
+ const internalModel = this._getInternalModel();
1551
+ internalModel.setProperty("/sessionOn", false);
1552
+ internalModel.setProperty("/stickySessionToken", undefined);
1553
+ this._handleStickyOff(/*oContext*/);
1554
+ }
1555
+ }
1457
1556
 
1458
- return this._getRoutingListener().navigateToContext(oContext, {
1557
+ async _handleNewContext(
1558
+ oContext: any,
1559
+ bEditable: boolean,
1560
+ bRecreateContext: boolean,
1561
+ bDraftNavigation: boolean,
1562
+ bForceFocus?: boolean,
1563
+ bNavigateToSiblingEntity?: boolean
1564
+ ) {
1565
+ if (!this._isFclEnabled()) {
1566
+ EditState.setEditStateDirty();
1567
+ }
1568
+
1569
+ await this._getRoutingListener().navigateToContext(oContext, {
1459
1570
  checkNoHashChange: true,
1460
1571
  editable: bEditable,
1461
1572
  bPersistOPScroll: true,
1462
1573
  bRecreateContext: bRecreateContext,
1463
1574
  bDraftNavigation: bDraftNavigation,
1464
1575
  showPlaceholder: false,
1465
- bForceFocus: bForceFocus
1576
+ bForceFocus: bForceFocus,
1577
+ keepCurrentLayout: true,
1578
+ bNavigateToSiblingEntity: bNavigateToSiblingEntity
1466
1579
  });
1467
1580
  }
1468
1581
 
1582
+ _getBoundContext(view: any, params: any) {
1583
+ const viewLevel = (view.getViewData() as any).viewLevel;
1584
+ const bRefreshAfterAction = viewLevel > 1 || (viewLevel === 1 && params.controlId);
1585
+ return !params.isNavigable || !!bRefreshAfterAction;
1586
+ }
1587
+
1469
1588
  /**
1470
1589
  * Checks if there are validation (parse) errors for controls bound to a given context
1471
1590
  *
@@ -1478,11 +1597,7 @@ class EditFlow extends ControllerExtension {
1478
1597
  _checkForValidationErrors() {
1479
1598
  return this._syncTask().then(() => {
1480
1599
  const sViewId = this.base.getView().getId();
1481
- const aMessages = sap.ui
1482
- .getCore()
1483
- .getMessageManager()
1484
- .getMessageModel()
1485
- .getData();
1600
+ const aMessages = sap.ui.getCore().getMessageManager().getMessageModel().getData();
1486
1601
  let oControl;
1487
1602
  let oMessage;
1488
1603
 
@@ -1493,7 +1608,7 @@ class EditFlow extends ControllerExtension {
1493
1608
  for (let i = 0; i < aMessages.length; i++) {
1494
1609
  oMessage = aMessages[i];
1495
1610
  if (oMessage.validation) {
1496
- oControl = sap.ui.getCore().byId(oMessage.getControlId());
1611
+ oControl = Core.byId(oMessage.getControlId());
1497
1612
  while (oControl) {
1498
1613
  if (oControl.getId() === sViewId) {
1499
1614
  return Promise.reject("validation errors exist");
@@ -1527,13 +1642,13 @@ class EditFlow extends ControllerExtension {
1527
1642
  // ensure context is in the response
1528
1643
  if (Object.keys(oContextData).length) {
1529
1644
  // check if context in response is different than the bound context
1530
- bReturnedContextIsSame = aKeys.every(function(sKey: any) {
1645
+ bReturnedContextIsSame = aKeys.every(function (sKey: any) {
1531
1646
  return oCurrentData[sKey] === oContextData[sKey];
1532
1647
  });
1533
1648
  if (!bReturnedContextIsSame) {
1534
- return new Promise<void>(resolve => {
1649
+ return new Promise<void>((resolve) => {
1535
1650
  if ((oBinding as any).isRoot()) {
1536
- oBinding.attachEventOnce("dataReceived", function() {
1651
+ oBinding.attachEventOnce("dataReceived", function () {
1537
1652
  resolve();
1538
1653
  });
1539
1654
  oBinding.refresh();
@@ -1543,15 +1658,15 @@ class EditFlow extends ControllerExtension {
1543
1658
  .getSideEffectsService()
1544
1659
  .requestSideEffects([{ $NavigationPropertyPath: oBinding.getPath() }], oBinding.getContext() as Context)
1545
1660
  .then(
1546
- function() {
1661
+ function () {
1547
1662
  resolve();
1548
1663
  },
1549
- function() {
1664
+ function () {
1550
1665
  Log.error("Error while refreshing the table");
1551
1666
  resolve();
1552
1667
  }
1553
1668
  )
1554
- .catch(function(e: any) {
1669
+ .catch(function (e: any) {
1555
1670
  Log.error("Error while refreshing the table", e);
1556
1671
  });
1557
1672
  }
@@ -1563,13 +1678,13 @@ class EditFlow extends ControllerExtension {
1563
1678
  return Promise.resolve();
1564
1679
  }
1565
1680
 
1566
- _fetchSemanticKeyValues(oContext: any) {
1567
- const oMetaModel = oContext.getModel().getMetaModel(),
1681
+ _fetchSemanticKeyValues(oContext: Context): Promise<any> {
1682
+ const oMetaModel = oContext.getModel().getMetaModel() as any,
1568
1683
  sEntitySetName = oMetaModel.getMetaContext(oContext.getPath()).getObject("@sapui.name"),
1569
1684
  aSemanticKeys = SemanticKeyHelper.getSemanticKeys(oMetaModel, sEntitySetName);
1570
1685
 
1571
1686
  if (aSemanticKeys && aSemanticKeys.length) {
1572
- const aRequestPromises = aSemanticKeys.map(function(oKey: any) {
1687
+ const aRequestPromises = aSemanticKeys.map(function (oKey: any) {
1573
1688
  return oContext.requestObject(oKey.$PropertyPath);
1574
1689
  });
1575
1690
 
@@ -1586,7 +1701,7 @@ class EditFlow extends ControllerExtension {
1586
1701
  let aPages: any[] = [];
1587
1702
  const oAppComponent = CommonUtils.getAppComponent(this.getView());
1588
1703
 
1589
- if (oAppComponent._isFclEnabled()) {
1704
+ if (this._isFclEnabled()) {
1590
1705
  const oFCL = oAppComponent.getRootContainer() as FlexibleColumnLayout;
1591
1706
  aPages = aPages.concat(oFCL.getMidColumnPages() || []);
1592
1707
  aPages = aPages.concat(oFCL.getEndColumnPages() || []);
@@ -1595,7 +1710,7 @@ class EditFlow extends ControllerExtension {
1595
1710
  aPages = oNavContainer.getPages() || [];
1596
1711
  }
1597
1712
 
1598
- aPages.forEach(function(oPage: any) {
1713
+ aPages.forEach(function (oPage: any) {
1599
1714
  if (oPage.isA("sap.ui.core.ComponentContainer")) {
1600
1715
  oPage = oPage.getComponentInstance(); // The binding context is set at the component level, not the component container
1601
1716
  }
@@ -1612,7 +1727,7 @@ class EditFlow extends ControllerExtension {
1612
1727
  function _checkActions(aActions: Array<object>) {
1613
1728
  let oActionBindingContext: any;
1614
1729
  try {
1615
- aActions.forEach(function(oAction: any) {
1730
+ aActions.forEach(function (oAction: any) {
1616
1731
  oActionBindingContext = oAction.getBindingContext();
1617
1732
  if (
1618
1733
  oActionBindingContext
@@ -1633,10 +1748,13 @@ class EditFlow extends ControllerExtension {
1633
1748
  function _checkSubSections(aSubSections: Array<object>) {
1634
1749
  let oActionBindingContext: any;
1635
1750
  try {
1636
- aSubSections.forEach(function(oSubSection: any) {
1751
+ aSubSections.forEach(function (oSubSection: any) {
1637
1752
  if (oActionBindingContext) {
1638
1753
  throw "context found - stop SubSections loop";
1639
1754
  }
1755
+ if (oSubSection.getBindingContext() === null) {
1756
+ oSubSection.setBindingContext(undefined);
1757
+ }
1640
1758
  const aActions = oSubSection.getAggregation("actions");
1641
1759
  oActionBindingContext = _checkActions(aActions);
1642
1760
  });
@@ -1663,10 +1781,74 @@ class EditFlow extends ControllerExtension {
1663
1781
  return _checkSubSections(aSubSections);
1664
1782
  }
1665
1783
  } catch (error) {
1666
- Log.info(error);
1784
+ Log.info(error as any);
1667
1785
  return undefined;
1668
1786
  }
1669
1787
  }
1788
+
1789
+ _createSiblingInfo(currentContext: Context, newContext: Context): SiblingInformation {
1790
+ return {
1791
+ targetContext: newContext,
1792
+ pathMapping: [
1793
+ {
1794
+ oldPath: currentContext.getPath(),
1795
+ newPath: newContext.getPath()
1796
+ }
1797
+ ]
1798
+ };
1799
+ }
1800
+
1801
+ _updatePathsInHistory(mappings: { oldPath: string; newPath: string }[]) {
1802
+ const oAppComponent = this.base.getAppComponent();
1803
+ oAppComponent.getRouterProxy().setPathMapping(mappings);
1804
+
1805
+ // Also update the semantic mapping in the routing service
1806
+ const lastSemanticMapping = this._getSemanticMapping();
1807
+ if (mappings.length && lastSemanticMapping?.technicalPath === mappings[mappings.length - 1].oldPath) {
1808
+ lastSemanticMapping.technicalPath = mappings[mappings.length - 1].newPath;
1809
+ }
1810
+ }
1811
+
1812
+ /**
1813
+ * This methods creates a sibling context for a sub-object page, and calculates a sibling path for
1814
+ * all intermediates paths between the OP and the sub-OP.
1815
+ *
1816
+ * @param {object} rootCurrentContext The context for the root of the draft
1817
+ * @param {object} rightmostCurrentContext The context of the sub-object
1818
+ * @param {string} sProgrammingModel The programming model
1819
+ * @param {boolean} doNotComputeIfRoot If true, we don't compute siblingInfo if the root and the rightmost contexts are the same
1820
+ * @returns {Promise} Returns the siblingInformation object
1821
+ */
1822
+ async _computeSiblingInformation(
1823
+ rootCurrentContext: Context,
1824
+ rightmostCurrentContext: Context,
1825
+ sProgrammingModel: string,
1826
+ doNotComputeIfRoot: boolean
1827
+ ): Promise<SiblingInformation | undefined> {
1828
+ if (!rightmostCurrentContext.getPath().startsWith(rootCurrentContext.getPath())) {
1829
+ // Wrong usage !!
1830
+ Log.error("Cannot compute rightmost sibling context");
1831
+ throw new Error("Cannot compute rightmost sibling context");
1832
+ }
1833
+ if (doNotComputeIfRoot && rightmostCurrentContext.getPath() === rootCurrentContext.getPath()) {
1834
+ return Promise.resolve(undefined);
1835
+ }
1836
+
1837
+ const model = rootCurrentContext.getModel();
1838
+ if (sProgrammingModel === ProgrammingModel.Draft) {
1839
+ return draft.computeSiblingInformation(rootCurrentContext, rightmostCurrentContext);
1840
+ } else {
1841
+ // If not in draft mode, we just recreate a context from the path of the rightmost context
1842
+ // No path mapping is needed
1843
+ return {
1844
+ targetContext: model.bindContext(rightmostCurrentContext.getPath()).getBoundContext() as Context,
1845
+ pathMapping: []
1846
+ };
1847
+ }
1848
+ }
1849
+ _isFclEnabled(): boolean {
1850
+ return CommonUtils.getAppComponent(this.getView())._isFclEnabled();
1851
+ }
1670
1852
  }
1671
1853
 
1672
1854
  export default EditFlow;