@sapui5/sap.fe.core 1.101.0 → 1.103.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 (339) hide show
  1. package/package.json +5 -5
  2. package/src/sap/fe/core/.library +1 -1
  3. package/src/sap/fe/core/AppComponent.js +66 -30
  4. package/src/sap/fe/core/AppComponent.ts +68 -51
  5. package/src/sap/fe/core/AppStateHandler.js +13 -13
  6. package/src/sap/fe/core/AppStateHandler.ts +18 -18
  7. package/src/sap/fe/core/BaseController.js +11 -9
  8. package/src/sap/fe/core/BaseController.ts +15 -13
  9. package/src/sap/fe/core/CommonUtils.js +279 -188
  10. package/src/sap/fe/core/CommonUtils.ts +306 -215
  11. package/src/sap/fe/core/ExtensionAPI.js +25 -30
  12. package/src/sap/fe/core/ExtensionAPI.ts +37 -41
  13. package/src/sap/fe/core/PageController.js +12 -7
  14. package/src/sap/fe/core/PageController.ts +10 -5
  15. package/src/sap/fe/core/TemplateComponent.js +6 -6
  16. package/src/sap/fe/core/TemplateComponent.ts +11 -11
  17. package/src/sap/fe/core/TemplateModel.js +2 -2
  18. package/src/sap/fe/core/TemplateModel.ts +3 -3
  19. package/src/sap/fe/core/buildingBlocks/AttributeModel.js +1 -1
  20. package/src/sap/fe/core/buildingBlocks/AttributeModel.ts +1 -1
  21. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.js +306 -78
  22. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.ts +280 -70
  23. package/src/sap/fe/core/buildingBlocks/TraceInfo.js +27 -27
  24. package/src/sap/fe/core/buildingBlocks/TraceInfo.ts +28 -26
  25. package/src/sap/fe/core/{BusyLocker.js → controllerextensions/BusyLocker.js} +1 -1
  26. package/src/sap/fe/core/{BusyLocker.ts → controllerextensions/BusyLocker.ts} +7 -7
  27. package/src/sap/fe/core/controllerextensions/EditFlow.js +351 -229
  28. package/src/sap/fe/core/controllerextensions/EditFlow.ts +321 -246
  29. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +9 -9
  30. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +10 -10
  31. package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +59 -34
  32. package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +71 -45
  33. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +72 -72
  34. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +82 -80
  35. package/src/sap/fe/core/controllerextensions/InternalRouting.js +152 -131
  36. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +171 -152
  37. package/src/sap/fe/core/controllerextensions/KPIManagement.js +66 -68
  38. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +106 -123
  39. package/src/sap/fe/core/controllerextensions/MassEdit.js +11 -10
  40. package/src/sap/fe/core/controllerextensions/MassEdit.ts +31 -37
  41. package/src/sap/fe/core/controllerextensions/MessageHandler.js +21 -13
  42. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +30 -15
  43. package/src/sap/fe/core/controllerextensions/PageReady.js +97 -25
  44. package/src/sap/fe/core/controllerextensions/PageReady.ts +94 -34
  45. package/src/sap/fe/core/controllerextensions/Paginator.js +19 -11
  46. package/src/sap/fe/core/controllerextensions/Paginator.ts +22 -14
  47. package/src/sap/fe/core/controllerextensions/Placeholder.js +4 -6
  48. package/src/sap/fe/core/controllerextensions/Placeholder.ts +12 -14
  49. package/src/sap/fe/core/controllerextensions/Routing.js +10 -11
  50. package/src/sap/fe/core/controllerextensions/Routing.ts +12 -13
  51. package/src/sap/fe/core/controllerextensions/Share.js +39 -21
  52. package/src/sap/fe/core/controllerextensions/Share.ts +45 -26
  53. package/src/sap/fe/core/controllerextensions/SideEffects.js +47 -51
  54. package/src/sap/fe/core/controllerextensions/SideEffects.ts +58 -62
  55. package/src/sap/fe/core/controllerextensions/ViewState.js +75 -62
  56. package/src/sap/fe/core/controllerextensions/ViewState.ts +78 -63
  57. package/src/sap/fe/core/controllerextensions/collaboration/ActivityBase.js +105 -0
  58. package/src/sap/fe/core/controllerextensions/collaboration/ActivityBase.ts +99 -0
  59. package/src/sap/fe/core/controllerextensions/collaboration/ActivitySync.js +360 -0
  60. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/ActivitySync.ts +58 -112
  61. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/CollaborationCommon.js +2 -2
  62. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/CollaborationCommon.ts +7 -7
  63. package/src/sap/fe/core/controllerextensions/collaboration/Manage.js +262 -0
  64. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/Manage.ts +20 -21
  65. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/ManageDialog.fragment.xml +0 -0
  66. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/UserDetails.fragment.xml +5 -7
  67. package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.js +1631 -0
  68. package/src/sap/fe/core/{TransactionHelper.ts → controllerextensions/editFlow/TransactionHelper.ts} +270 -211
  69. package/src/sap/fe/core/controllerextensions/editFlow/draft.js +772 -0
  70. package/src/sap/fe/core/{actions → controllerextensions/editFlow}/draft.ts +240 -100
  71. package/src/sap/fe/core/controllerextensions/editFlow/operations.js +1199 -0
  72. package/src/sap/fe/core/{actions → controllerextensions/editFlow}/operations.ts +364 -229
  73. package/src/sap/fe/core/controllerextensions/editFlow/sticky.js +188 -0
  74. package/src/sap/fe/core/controllerextensions/editFlow/sticky.ts +185 -0
  75. package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.js +626 -0
  76. package/src/sap/fe/core/{actions → controllerextensions/messageHandler}/messageHandling.ts +112 -69
  77. package/src/sap/fe/core/controllerextensions/routing/RouterProxy.js +937 -0
  78. package/src/sap/fe/core/{RouterProxy.ts → controllerextensions/routing/RouterProxy.ts} +72 -73
  79. package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +21 -18
  80. package/src/sap/fe/core/controls/Any.js +9 -5
  81. package/src/sap/fe/core/controls/Any.ts +10 -4
  82. package/src/sap/fe/core/controls/CommandExecution.js +21 -24
  83. package/src/sap/fe/core/controls/CommandExecution.ts +19 -24
  84. package/src/sap/fe/core/controls/ConditionalWrapper.js +2 -2
  85. package/src/sap/fe/core/controls/ConditionalWrapper.ts +3 -3
  86. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.js +48 -43
  87. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.ts +51 -46
  88. package/src/sap/fe/core/controls/CustomQuickViewPage.js +3 -2
  89. package/src/sap/fe/core/controls/CustomQuickViewPage.ts +3 -2
  90. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossDraft.fragment.xml +11 -3
  91. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +19 -9
  92. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +14 -8
  93. package/src/sap/fe/core/controls/FieldWrapper.js +2 -2
  94. package/src/sap/fe/core/controls/FieldWrapper.ts +3 -3
  95. package/src/sap/fe/core/controls/FileWrapper.js +50 -3
  96. package/src/sap/fe/core/controls/FileWrapper.ts +45 -12
  97. package/src/sap/fe/core/controls/FilterBar.js +6 -2
  98. package/src/sap/fe/core/controls/FilterBar.ts +13 -9
  99. package/src/sap/fe/core/controls/FormElementWrapper.js +12 -2
  100. package/src/sap/fe/core/controls/FormElementWrapper.ts +14 -3
  101. package/src/sap/fe/core/controls/MassEditSelect.js +33 -0
  102. package/src/sap/fe/core/controls/MassEditSelect.ts +41 -0
  103. package/src/sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog.fragment.xml +3 -3
  104. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +16 -12
  105. package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +20 -22
  106. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +3 -3
  107. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +8 -8
  108. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +48 -48
  109. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +71 -76
  110. package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +36 -65
  111. package/src/sap/fe/core/controls/massEdit/MassEditField.fragment.xml +107 -0
  112. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +551 -36
  113. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +605 -36
  114. package/src/sap/fe/core/converters/ConverterContext.js +26 -33
  115. package/src/sap/fe/core/converters/ConverterContext.ts +51 -60
  116. package/src/sap/fe/core/converters/ManifestSettings.js +2 -1
  117. package/src/sap/fe/core/converters/ManifestSettings.ts +17 -14
  118. package/src/sap/fe/core/converters/ManifestWrapper.js +59 -45
  119. package/src/sap/fe/core/converters/ManifestWrapper.ts +55 -45
  120. package/src/sap/fe/core/converters/MetaModelConverter.js +56 -67
  121. package/src/sap/fe/core/converters/MetaModelConverter.ts +183 -193
  122. package/src/sap/fe/core/converters/TemplateConverter.js +21 -20
  123. package/src/sap/fe/core/converters/TemplateConverter.ts +27 -24
  124. package/src/sap/fe/core/converters/annotations/DataField.js +73 -37
  125. package/src/sap/fe/core/converters/annotations/DataField.ts +121 -77
  126. package/src/sap/fe/core/converters/common/AnnotationConverter.js +1911 -1495
  127. package/src/sap/fe/core/converters/controls/Common/Action.js +51 -49
  128. package/src/sap/fe/core/converters/controls/Common/Action.ts +58 -54
  129. package/src/sap/fe/core/converters/controls/Common/Chart.js +22 -15
  130. package/src/sap/fe/core/converters/controls/Common/Chart.ts +29 -27
  131. package/src/sap/fe/core/converters/controls/Common/Criticality.js +3 -3
  132. package/src/sap/fe/core/converters/controls/Common/Criticality.ts +4 -4
  133. package/src/sap/fe/core/converters/controls/Common/DataVisualization.js +28 -28
  134. package/src/sap/fe/core/converters/controls/Common/DataVisualization.ts +40 -36
  135. package/src/sap/fe/core/converters/controls/Common/Form.js +30 -34
  136. package/src/sap/fe/core/converters/controls/Common/Form.ts +48 -58
  137. package/src/sap/fe/core/converters/controls/Common/KPI.js +11 -11
  138. package/src/sap/fe/core/converters/controls/Common/KPI.ts +35 -39
  139. package/src/sap/fe/core/converters/controls/Common/Table.js +318 -244
  140. package/src/sap/fe/core/converters/controls/Common/Table.ts +368 -297
  141. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +135 -125
  142. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +162 -148
  143. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +51 -45
  144. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +79 -67
  145. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.js +28 -26
  146. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.ts +46 -43
  147. package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.js +9 -9
  148. package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.ts +14 -13
  149. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +67 -64
  150. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +69 -66
  151. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +92 -89
  152. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +124 -120
  153. package/src/sap/fe/core/converters/helpers/Aggregation.js +11 -5
  154. package/src/sap/fe/core/converters/helpers/Aggregation.ts +25 -23
  155. package/src/sap/fe/core/converters/helpers/BindingHelper.js +31 -30
  156. package/src/sap/fe/core/converters/helpers/BindingHelper.ts +31 -29
  157. package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +4 -4
  158. package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +9 -9
  159. package/src/sap/fe/core/converters/helpers/ID.js +46 -46
  160. package/src/sap/fe/core/converters/helpers/ID.ts +25 -25
  161. package/src/sap/fe/core/converters/helpers/Key.js +7 -7
  162. package/src/sap/fe/core/converters/helpers/Key.ts +7 -7
  163. package/src/sap/fe/core/converters/helpers/SelectionVariantHelper.js +1 -1
  164. package/src/sap/fe/core/converters/helpers/SelectionVariantHelper.ts +4 -4
  165. package/src/sap/fe/core/converters/objectPage/FormMenuActions.js +6 -6
  166. package/src/sap/fe/core/converters/objectPage/FormMenuActions.ts +10 -10
  167. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +46 -62
  168. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +54 -82
  169. package/src/sap/fe/core/converters/templates/ListReportConverter.js +30 -29
  170. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +40 -40
  171. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +56 -55
  172. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +65 -77
  173. package/src/sap/fe/core/designtime/AppComponent.designtime.js +6 -6
  174. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +10 -8
  175. package/src/sap/fe/core/formatters/CollaborationFormatter.js +2 -2
  176. package/src/sap/fe/core/formatters/CollaborationFormatter.ts +3 -3
  177. package/src/sap/fe/core/formatters/FPMFormatter.js +5 -5
  178. package/src/sap/fe/core/formatters/FPMFormatter.ts +10 -10
  179. package/src/sap/fe/core/formatters/KPIFormatter.js +7 -7
  180. package/src/sap/fe/core/formatters/KPIFormatter.ts +10 -10
  181. package/src/sap/fe/core/formatters/StandardFormatter.js +89 -0
  182. package/src/sap/fe/core/formatters/StandardFormatter.ts +64 -0
  183. package/src/sap/fe/core/formatters/TableFormatter.js +83 -22
  184. package/src/sap/fe/core/formatters/TableFormatter.ts +80 -25
  185. package/src/sap/fe/core/formatters/ValueFormatter.js +8 -8
  186. package/src/sap/fe/core/formatters/ValueFormatter.ts +9 -9
  187. package/src/sap/fe/core/fpm/Component.js +2 -2
  188. package/src/sap/fe/core/fpm/Component.ts +1 -1
  189. package/src/sap/fe/core/helpers/AppStartupHelper.js +15 -15
  190. package/src/sap/fe/core/helpers/AppStartupHelper.ts +37 -40
  191. package/src/sap/fe/core/helpers/BindingToolkit.js +1809 -0
  192. package/src/sap/fe/core/helpers/{BindingExpression.ts → BindingToolkit.ts} +388 -285
  193. package/src/sap/fe/core/helpers/ClassSupport.js +20 -11
  194. package/src/sap/fe/core/helpers/ClassSupport.ts +15 -10
  195. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +2 -2
  196. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +1 -1
  197. package/src/sap/fe/core/helpers/EditState.js +1 -6
  198. package/src/sap/fe/core/helpers/EditState.ts +5 -10
  199. package/src/sap/fe/core/helpers/ExcelFormatHelper.js +2 -2
  200. package/src/sap/fe/core/helpers/ExcelFormatHelper.ts +4 -4
  201. package/src/sap/fe/core/helpers/FPMHelper.js +3 -2
  202. package/src/sap/fe/core/helpers/FPMHelper.ts +10 -9
  203. package/src/sap/fe/core/helpers/KeepAliveHelper.js +31 -31
  204. package/src/sap/fe/core/helpers/KeepAliveHelper.ts +52 -56
  205. package/src/sap/fe/core/helpers/MassEditHelper.js +532 -264
  206. package/src/sap/fe/core/helpers/MassEditHelper.ts +560 -289
  207. package/src/sap/fe/core/helpers/ModelHelper.js +25 -25
  208. package/src/sap/fe/core/helpers/ModelHelper.ts +50 -58
  209. package/src/sap/fe/core/helpers/PasteHelper.js +3 -10
  210. package/src/sap/fe/core/helpers/PasteHelper.ts +20 -25
  211. package/src/sap/fe/core/helpers/SemanticDateOperators.js +1 -1
  212. package/src/sap/fe/core/helpers/SemanticDateOperators.ts +11 -11
  213. package/src/sap/fe/core/helpers/SemanticKeyHelper.js +3 -3
  214. package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +8 -8
  215. package/src/sap/fe/core/helpers/StableIdHelper.js +16 -12
  216. package/src/sap/fe/core/helpers/StableIdHelper.ts +20 -16
  217. package/src/sap/fe/core/{Synchronization.js → helpers/Synchronization.js} +1 -1
  218. package/src/sap/fe/core/{Synchronization.ts → helpers/Synchronization.ts} +1 -1
  219. package/src/sap/fe/core/jsx-runtime/jsx.js +1 -1
  220. package/src/sap/fe/core/jsx-runtime/jsx.ts +8 -8
  221. package/src/sap/fe/core/library.js +51 -3
  222. package/src/sap/fe/core/library.ts +47 -0
  223. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +3 -3
  224. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +2 -2
  225. package/src/sap/fe/core/messagebundle.properties +151 -197
  226. package/src/sap/fe/core/messagebundle_ar.properties +36 -63
  227. package/src/sap/fe/core/messagebundle_bg.properties +36 -63
  228. package/src/sap/fe/core/messagebundle_ca.properties +36 -63
  229. package/src/sap/fe/core/messagebundle_cs.properties +36 -63
  230. package/src/sap/fe/core/messagebundle_cy.properties +36 -63
  231. package/src/sap/fe/core/messagebundle_da.properties +37 -64
  232. package/src/sap/fe/core/messagebundle_de.properties +36 -63
  233. package/src/sap/fe/core/messagebundle_el.properties +38 -65
  234. package/src/sap/fe/core/messagebundle_en.properties +37 -64
  235. package/src/sap/fe/core/messagebundle_en_GB.properties +37 -64
  236. package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +44 -73
  237. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +37 -64
  238. package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +52 -81
  239. package/src/sap/fe/core/messagebundle_es.properties +36 -63
  240. package/src/sap/fe/core/messagebundle_es_MX.properties +36 -63
  241. package/src/sap/fe/core/messagebundle_et.properties +36 -63
  242. package/src/sap/fe/core/messagebundle_fi.properties +36 -63
  243. package/src/sap/fe/core/messagebundle_fr.properties +39 -66
  244. package/src/sap/fe/core/messagebundle_fr_CA.properties +36 -63
  245. package/src/sap/fe/core/messagebundle_hi.properties +36 -63
  246. package/src/sap/fe/core/messagebundle_hr.properties +36 -63
  247. package/src/sap/fe/core/messagebundle_hu.properties +35 -62
  248. package/src/sap/fe/core/messagebundle_id.properties +37 -64
  249. package/src/sap/fe/core/messagebundle_it.properties +54 -81
  250. package/src/sap/fe/core/messagebundle_iw.properties +36 -63
  251. package/src/sap/fe/core/messagebundle_ja.properties +36 -63
  252. package/src/sap/fe/core/messagebundle_kk.properties +36 -63
  253. package/src/sap/fe/core/messagebundle_ko.properties +36 -63
  254. package/src/sap/fe/core/messagebundle_lt.properties +36 -63
  255. package/src/sap/fe/core/messagebundle_lv.properties +36 -63
  256. package/src/sap/fe/core/messagebundle_ms.properties +37 -64
  257. package/src/sap/fe/core/messagebundle_nl.properties +37 -64
  258. package/src/sap/fe/core/messagebundle_no.properties +36 -63
  259. package/src/sap/fe/core/messagebundle_pl.properties +37 -64
  260. package/src/sap/fe/core/messagebundle_pt.properties +37 -64
  261. package/src/sap/fe/core/messagebundle_pt_PT.properties +36 -63
  262. package/src/sap/fe/core/messagebundle_ro.properties +36 -63
  263. package/src/sap/fe/core/messagebundle_ru.properties +36 -63
  264. package/src/sap/fe/core/messagebundle_sh.properties +36 -63
  265. package/src/sap/fe/core/messagebundle_sk.properties +36 -63
  266. package/src/sap/fe/core/messagebundle_sl.properties +38 -65
  267. package/src/sap/fe/core/messagebundle_sv.properties +36 -63
  268. package/src/sap/fe/core/messagebundle_th.properties +36 -63
  269. package/src/sap/fe/core/messagebundle_tr.properties +36 -63
  270. package/src/sap/fe/core/messagebundle_uk.properties +37 -64
  271. package/src/sap/fe/core/messagebundle_vi.properties +37 -64
  272. package/src/sap/fe/core/messagebundle_zh_CN.properties +36 -63
  273. package/src/sap/fe/core/messagebundle_zh_TW.properties +37 -64
  274. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +2 -2
  275. package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +5 -5
  276. package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +2 -2
  277. package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +14 -14
  278. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +6 -3
  279. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +12 -10
  280. package/src/sap/fe/core/services/NavigationServiceFactory.js +54 -45
  281. package/src/sap/fe/core/services/NavigationServiceFactory.ts +61 -49
  282. package/src/sap/fe/core/services/ResourceModelServiceFactory.js +2 -2
  283. package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +4 -4
  284. package/src/sap/fe/core/services/RoutingServiceFactory.js +63 -60
  285. package/src/sap/fe/core/services/RoutingServiceFactory.ts +76 -73
  286. package/src/sap/fe/core/services/ShellServicesFactory.js +102 -71
  287. package/src/sap/fe/core/services/ShellServicesFactory.ts +109 -78
  288. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +61 -61
  289. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +102 -92
  290. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +24 -18
  291. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +53 -50
  292. package/src/sap/fe/core/support/CommonHelper.js +3 -2
  293. package/src/sap/fe/core/support/CommonHelper.ts +9 -13
  294. package/src/sap/fe/core/support/Diagnostics.js +1 -1
  295. package/src/sap/fe/core/support/Diagnostics.ts +5 -5
  296. package/src/sap/fe/core/templating/CommonFormatters.js +84 -0
  297. package/src/sap/fe/core/templating/CommonFormatters.ts +86 -0
  298. package/src/sap/fe/core/templating/CriticalityFormatters.js +31 -31
  299. package/src/sap/fe/core/templating/CriticalityFormatters.ts +42 -40
  300. package/src/sap/fe/core/templating/DataFieldFormatters.js +8 -8
  301. package/src/sap/fe/core/templating/DataFieldFormatters.ts +13 -10
  302. package/src/sap/fe/core/templating/DataModelPathHelper.js +16 -15
  303. package/src/sap/fe/core/templating/DataModelPathHelper.ts +42 -32
  304. package/src/sap/fe/core/templating/DisplayModeFormatter.js +1 -1
  305. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +3 -4
  306. package/src/sap/fe/core/templating/EntitySetHelper.js +7 -15
  307. package/src/sap/fe/core/templating/EntitySetHelper.ts +14 -18
  308. package/src/sap/fe/core/templating/FieldControlHelper.js +35 -34
  309. package/src/sap/fe/core/templating/FieldControlHelper.ts +29 -46
  310. package/src/sap/fe/core/templating/FilterHelper.js +12 -11
  311. package/src/sap/fe/core/templating/FilterHelper.ts +17 -16
  312. package/src/sap/fe/core/templating/FilterTemplating.js +1 -1
  313. package/src/sap/fe/core/templating/FilterTemplating.ts +3 -3
  314. package/src/sap/fe/core/templating/PropertyFormatters.js +7 -7
  315. package/src/sap/fe/core/templating/PropertyFormatters.ts +21 -19
  316. package/src/sap/fe/core/templating/PropertyHelper.js +79 -56
  317. package/src/sap/fe/core/templating/PropertyHelper.ts +41 -27
  318. package/src/sap/fe/core/templating/UIFormatters.js +163 -97
  319. package/src/sap/fe/core/templating/UIFormatters.ts +210 -129
  320. package/src/sap/fe/core/type/DateTimeWithTimezone.js +47 -0
  321. package/src/sap/fe/core/type/DateTimeWithTimezone.ts +23 -0
  322. package/src/sap/fe/core/type/Email.js +2 -2
  323. package/src/sap/fe/core/type/Email.ts +2 -2
  324. package/src/sap/fe/core/AnnotationHelper.js +0 -331
  325. package/src/sap/fe/core/AnnotationHelper.ts +0 -321
  326. package/src/sap/fe/core/RouterProxy.js +0 -938
  327. package/src/sap/fe/core/TransactionHelper.js +0 -1577
  328. package/src/sap/fe/core/actions/collaboration/ActivitySync.js +0 -406
  329. package/src/sap/fe/core/actions/collaboration/Manage.js +0 -264
  330. package/src/sap/fe/core/actions/draft.js +0 -665
  331. package/src/sap/fe/core/actions/messageHandling.js +0 -579
  332. package/src/sap/fe/core/actions/nonDraft.js +0 -20
  333. package/src/sap/fe/core/actions/nonDraft.ts +0 -12
  334. package/src/sap/fe/core/actions/operations.js +0 -1096
  335. package/src/sap/fe/core/actions/sticky.js +0 -130
  336. package/src/sap/fe/core/actions/sticky.ts +0 -119
  337. package/src/sap/fe/core/formatters/CriticalityFormatter.js +0 -77
  338. package/src/sap/fe/core/formatters/CriticalityFormatter.ts +0 -58
  339. package/src/sap/fe/core/helpers/BindingExpression.js +0 -1729
@@ -1,26 +1,48 @@
1
1
  import Log from "sap/base/Log";
2
2
  import CommonUtils from "sap/fe/core/CommonUtils";
3
- import { BindingExpression, ExpressionOrPrimitive } from "sap/fe/core/helpers/BindingExpression";
4
- import PageController from "sap/fe/core/PageController";
5
- import { DataModelObjectPath, enhanceDataModelPath } from "sap/fe/core/templating/DataModelPathHelper";
6
- import { hasValueHelpWithFixedValues } from "sap/fe/core/templating/PropertyHelper";
7
- import { FieldProperties } from "sap/fe/macros/field/FieldProperties";
3
+ import {
4
+ BindingToolkitExpression,
5
+ CompiledBindingToolkitExpression,
6
+ compileExpression,
7
+ constant,
8
+ ifElse,
9
+ not,
10
+ or,
11
+ pathInModel
12
+ } from "sap/fe/core/helpers/BindingToolkit";
13
+ import FELibrary from "sap/fe/core/library";
14
+ import type PageController from "sap/fe/core/PageController";
15
+ import type { DataModelObjectPath } from "sap/fe/core/templating/DataModelPathHelper";
16
+ import { enhanceDataModelPath } from "sap/fe/core/templating/DataModelPathHelper";
17
+ import {
18
+ getAssociatedUnitProperty,
19
+ getAssociatedUnitPropertyPath,
20
+ hasCurrency,
21
+ hasUnit,
22
+ hasValueHelp,
23
+ hasValueHelpWithFixedValues
24
+ } from "sap/fe/core/templating/PropertyHelper";
8
25
  import { getTextBinding, setEditStyleProperties } from "sap/fe/macros/field/FieldTemplating";
26
+ import type { FieldProperties } from "sap/fe/macros/internal/Field.metadata";
9
27
  import Button from "sap/m/Button";
10
28
  import Dialog from "sap/m/Dialog";
29
+ import MessageToast from "sap/m/MessageToast";
11
30
  import Core from "sap/ui/core/Core";
12
31
  import Fragment from "sap/ui/core/Fragment";
13
32
  import XMLPreprocessor from "sap/ui/core/util/XMLPreprocessor";
14
33
  import XMLTemplateProcessor from "sap/ui/core/XMLTemplateProcessor";
15
34
  import EditMode from "sap/ui/mdc/enum/EditMode";
16
- import Table from "sap/ui/mdc/Table";
35
+ import type Table from "sap/ui/mdc/Table";
17
36
  import JSONModel from "sap/ui/model/json/JSONModel";
18
- import Context from "sap/ui/model/odata/v4/Context";
19
- import { CoreEx } from "types/extension_types";
20
- import Any, { AnyType } from "../controls/Any";
37
+ import type Context from "sap/ui/model/odata/v4/Context";
38
+ import type ODataListBinding from "sap/ui/model/odata/v4/ODataListBinding";
39
+ import type { CoreEx } from "types/extension_types";
40
+ import type { AnyType } from "../controls/Any";
41
+ import Any from "../controls/Any";
21
42
  import { convertMetaModelContext, getInvolvedDataModelObjects } from "../converters/MetaModelConverter";
22
43
  import { isReadOnlyExpression } from "../templating/FieldControlHelper";
23
44
  import { getEditMode, getRequiredExpression, isCollectionField } from "../templating/UIFormatters";
45
+ import type { InternalModelContext } from "./ModelHelper";
24
46
 
25
47
  /* This class contains helpers to be used for mass edit functionality */
26
48
  type TextArrangementInfo = {
@@ -32,16 +54,22 @@ type TextArrangementInfo = {
32
54
  fullText: string;
33
55
  };
34
56
 
57
+ type BindingInfo = {
58
+ path?: string;
59
+ model?: string | object;
60
+ parameters?: Array<BindingInfo>;
61
+ };
62
+
35
63
  const MassEditHelper = {
36
64
  /**
37
65
  * Initializes the value at final or deepest level path with a blank array.
38
66
  * Return an empty array pointing to the final or deepest level path.
39
67
  *
40
- * @param {string} sPath Property path
41
- * @param {Array} aValues Array instance where the default data needs to be added
42
- * @returns {Array}
68
+ * @param sPath Property path
69
+ * @param aValues Array instance where the default data needs to be added
70
+ * @returns The final path
43
71
  */
44
- initLastLevelOfPropertyPath: function (sPath: string, aValues: any) {
72
+ initLastLevelOfPropertyPath: function (sPath: string, aValues: any /*, transCtx: Context */) {
45
73
  let aFinalPath: any;
46
74
  let index = 0;
47
75
  const aPaths = sPath.split("/");
@@ -53,7 +81,7 @@ const MassEditHelper = {
53
81
  sFullPath = sFullPath + sPropertyPath;
54
82
  index++;
55
83
  } else if (!aFinalPath[sPropertyPath]) {
56
- sFullPath = sFullPath + "/" + sPropertyPath;
84
+ sFullPath = `${sFullPath}/${sPropertyPath}`;
57
85
  if (sFullPath !== sPath) {
58
86
  aFinalPath[sPropertyPath] = {};
59
87
  aFinalPath = aFinalPath[sPropertyPath];
@@ -68,13 +96,13 @@ const MassEditHelper = {
68
96
  /**
69
97
  * Method to get unique values for given array values.
70
98
  *
71
- * @param {string} sValue Property value
72
- * @param {number} index Index of the property value
73
- * @param {Array} self Instance of the array
74
- * @returns {boolean}
99
+ * @param sValue Property value
100
+ * @param index Index of the property value
101
+ * @param self Instance of the array
102
+ * @returns The unique value
75
103
  */
76
104
  getUniqueValues: function (sValue: string, index: number, self: any[]) {
77
- if (sValue) {
105
+ if (sValue != undefined && sValue != null) {
78
106
  return self.indexOf(sValue) === index;
79
107
  }
80
108
  },
@@ -83,9 +111,9 @@ const MassEditHelper = {
83
111
  * Gets the property value for a multi-level path (for example: _Materials/Material_Details gets the value of Material_Details under _Materials Object).
84
112
  * Returns the propertyValue, which can be of any type (string, number, etc..).
85
113
  *
86
- * @param {string} sDataPropertyPath Property path
87
- * @param {object} oValues Object of property values
88
- * @returns {*}
114
+ * @param sDataPropertyPath Property path
115
+ * @param oValues Object of property values
116
+ * @returns The property value
89
117
  */
90
118
  getValueForMultiLevelPath: function (sDataPropertyPath: string, oValues: any) {
91
119
  if (sDataPropertyPath && sDataPropertyPath.indexOf("/") > 0) {
@@ -105,9 +133,9 @@ const MassEditHelper = {
105
133
  * => If propertyValue for all selected contexts is empty, then < Leave Blank > is preselected.
106
134
  *
107
135
  *
108
- * @param {Array} aContexts Contexts for mass edit
109
- * @param {string} sDataPropertyPath Data property path
110
- * @returns {string}
136
+ * @param aContexts Contexts for mass edit
137
+ * @param sDataPropertyPath Data property path
138
+ * @returns The key path
111
139
  */
112
140
  getDefaultSelectionPathComboBox: function (aContexts: any[], sDataPropertyPath: string) {
113
141
  if (sDataPropertyPath && aContexts.length > 0) {
@@ -123,11 +151,11 @@ const MassEditHelper = {
123
151
  });
124
152
  const aUniquePropertyValues = aPropertyValues.filter(MassEditHelper.getUniqueValues);
125
153
  if (aUniquePropertyValues.length > 1) {
126
- return "Default/" + sDataPropertyPath;
154
+ return `Default/${sDataPropertyPath}`;
127
155
  } else if (aUniquePropertyValues.length === 0) {
128
- return "Empty/" + sDataPropertyPath;
156
+ return `Empty/${sDataPropertyPath}`;
129
157
  } else if (aUniquePropertyValues.length === 1) {
130
- return sDataPropertyPath;
158
+ return `${sDataPropertyPath}/${aUniquePropertyValues[0]}`;
131
159
  }
132
160
  }
133
161
  },
@@ -135,9 +163,9 @@ const MassEditHelper = {
135
163
  /**
136
164
  * Checks hidden annotation value [both static and path based] for table's selected context.
137
165
  *
138
- * @param {*} hiddenValue Hidden annotation value / path for field
139
- * @param {Array} aContexts Contexts for mass edit
140
- * @returns {boolean}
166
+ * @param hiddenValue Hidden annotation value / path for field
167
+ * @param aContexts Contexts for mass edit
168
+ * @returns The hidden annotation value
141
169
  */
142
170
  getHiddenValueForContexts: function (hiddenValue: any, aContexts: any[]) {
143
171
  if (hiddenValue && hiddenValue.$Path) {
@@ -174,19 +202,43 @@ const MassEditHelper = {
174
202
  );
175
203
  },
176
204
 
205
+ /**
206
+ * Get text path for the mass edit field.
207
+ *
208
+ * @param property Property path
209
+ * @param textBinding Text Binding Info
210
+ * @param displayMode Display mode
211
+ * @returns Text Property Path if it exists
212
+ */
213
+ getTextPath: function (property: string, textBinding: any, displayMode: string): string | undefined {
214
+ let descriptionPath;
215
+ if (textBinding && (textBinding.path || (textBinding.parameters && textBinding.parameters.length)) && property) {
216
+ if (textBinding.path && displayMode === "Description") {
217
+ descriptionPath = textBinding.path;
218
+ } else if (textBinding.parameters) {
219
+ textBinding.parameters.forEach(function (props: BindingInfo) {
220
+ if (props.path && props.path !== property) {
221
+ descriptionPath = props.path;
222
+ }
223
+ });
224
+ }
225
+ }
226
+ return descriptionPath;
227
+ },
228
+
177
229
  /**
178
230
  * Initializes a JSON Model for properties of dialog fields [label, visiblity, dataproperty, etc.].
179
231
  *
180
- * @param {object} oTable Instance of Table
181
- * @param {Array} aContexts Contexts for mass edit
182
- * @param {Array} aDataArray Array containing data related to the dialog used by both the static and the runtime model
183
- * @returns {object}
232
+ * @param oTable Instance of Table
233
+ * @param aContexts Contexts for mass edit
234
+ * @param aDataArray Array containing data related to the dialog used by both the static and the runtime model
235
+ * @returns The model
184
236
  */
185
237
  prepareDataForDialog: function (oTable: Table, aContexts: any[], aDataArray: any[]) {
186
238
  const oMetaModel = oTable && (oTable.getModel().getMetaModel() as any),
187
239
  sCurrentEntitySetName = oTable.data("metaPath"),
188
240
  aTableFields = MassEditHelper.getTableFields(oTable),
189
- oEntityTypeContext = oMetaModel.getContext(sCurrentEntitySetName + "/@"),
241
+ oEntityTypeContext = oMetaModel.getContext(`${sCurrentEntitySetName}/@`),
190
242
  oEntitySetContext = oMetaModel.getContext(sCurrentEntitySetName),
191
243
  oDataModelObjectPath = getInvolvedDataModelObjects(oEntityTypeContext);
192
244
 
@@ -201,25 +253,12 @@ const MassEditHelper = {
201
253
  aTableFields.forEach(function (oColumnInfo: any) {
202
254
  const sDataPropertyPath = oColumnInfo.dataProperty;
203
255
  if (sDataPropertyPath) {
204
- let oPropertyInfo = sDataPropertyPath && oMetaModel.getObject(sCurrentEntitySetName + "/" + sDataPropertyPath + "@");
205
- bValueHelpEnabled =
206
- sDataPropertyPath &&
207
- oMetaModel.getObject(sCurrentEntitySetName + "/" + sDataPropertyPath + "@") &&
208
- oMetaModel.getObject(sCurrentEntitySetName + "/" + sDataPropertyPath + "@")[
209
- "@com.sap.vocabularies.Common.v1.ValueList"
210
- ];
211
- sUnitPropertyPath =
212
- (oPropertyInfo && oPropertyInfo["@Org.OData.Measures.V1.Unit"] && oPropertyInfo["@Org.OData.Measures.V1.Unit"].$Path) ||
213
- (oPropertyInfo &&
214
- oPropertyInfo["@Org.OData.Measures.V1.ISOCurrency"] &&
215
- oPropertyInfo["@Org.OData.Measures.V1.ISOCurrency"].$Path);
216
- sLabelText = oColumnInfo.label || (oPropertyInfo && oPropertyInfo["@com.sap.vocabularies.Common.v1.Label"]);
217
- bValueHelpEnabledForUnit =
218
- sUnitPropertyPath &&
219
- oMetaModel.getObject(sCurrentEntitySetName + "/" + sUnitPropertyPath + "@") &&
220
- oMetaModel.getObject(sCurrentEntitySetName + "/" + sUnitPropertyPath + "@")[
221
- "@com.sap.vocabularies.Common.v1.ValueList"
222
- ];
256
+ let oPropertyInfo = sDataPropertyPath && oMetaModel.getObject(`${sCurrentEntitySetName}/${sDataPropertyPath}@`);
257
+ sLabelText =
258
+ oColumnInfo.label ||
259
+ (oPropertyInfo && oPropertyInfo["@com.sap.vocabularies.Common.v1.Label"]) ||
260
+ oColumnInfo.dataProperty;
261
+
223
262
  if (oDataModelObjectPath) {
224
263
  oDataModelObjectPath.targetObject = oDataModelObjectPath.targetEntityType.entityProperties.filter(function (
225
264
  oProperty: any
@@ -231,7 +270,7 @@ const MassEditHelper = {
231
270
  oTextBinding = getTextBinding(oDataModelObjectPath, {}, true) || {};
232
271
  const oFieldContext = oMetaModel.getContext(oColumnInfo.annotationPath),
233
272
  oDataFieldConverted = convertMetaModelContext(oFieldContext),
234
- oPropertyContext = oMetaModel.getContext(sCurrentEntitySetName + "/" + sDataPropertyPath + "@"),
273
+ oPropertyContext = oMetaModel.getContext(`${sCurrentEntitySetName}/${sDataPropertyPath}@`),
235
274
  oInterface = oPropertyContext && oPropertyContext.getInterface();
236
275
 
237
276
  let oDataModelPath = getInvolvedDataModelObjects(oFieldContext, oEntitySetContext);
@@ -250,12 +289,14 @@ const MassEditHelper = {
250
289
  return oInterface.getModel();
251
290
  },
252
291
  getPath: function () {
253
- return sCurrentEntitySetName + "/" + sDataPropertyPath;
292
+ return `${sCurrentEntitySetName}/${sDataPropertyPath}`;
254
293
  }
255
294
  };
256
295
  oPropertyInfo =
257
- (oDataFieldConverted && oDataFieldConverted.Value && oDataFieldConverted.Value.$target) ||
258
- (oDataFieldConverted && oDataFieldConverted.Target && oDataFieldConverted.Target.$target);
296
+ oDataFieldConverted._type === "Property"
297
+ ? oDataFieldConverted
298
+ : (oDataFieldConverted && oDataFieldConverted.Value && oDataFieldConverted.Value.$target) ||
299
+ (oDataFieldConverted && oDataFieldConverted.Target && oDataFieldConverted.Target.$target);
259
300
  // Datafield is not included in the FieldControl calculation, needs to be implemented
260
301
 
261
302
  const chartProperty = oPropertyInfo && oPropertyInfo.term && oPropertyInfo.term === "com.sap.vocabularies.UI.v1.Chart";
@@ -266,9 +307,16 @@ const MassEditHelper = {
266
307
  return;
267
308
  }
268
309
 
310
+ // ValueHelp properties
311
+ bValueHelpEnabled = hasValueHelp(oPropertyInfo);
312
+ sUnitPropertyPath =
313
+ ((hasCurrency(oPropertyInfo) || hasUnit(oPropertyInfo)) && getAssociatedUnitPropertyPath(oPropertyInfo)) || "";
314
+ const unitPropertyInfo = sUnitPropertyPath && getAssociatedUnitProperty(oPropertyInfo);
315
+ bValueHelpEnabledForUnit = unitPropertyInfo && hasValueHelp(unitPropertyInfo);
316
+
269
317
  // EditMode and InputType
270
318
  const propertyForFieldControl = oPropertyInfo && oPropertyInfo.Value ? oPropertyInfo.Value : oPropertyInfo;
271
- const expBinding = getEditMode(propertyForFieldControl, oDataModelPath, false, false, oDataFieldConverted, true);
319
+ const expBinding = getEditMode(propertyForFieldControl, oDataModelPath, false, false, oDataFieldConverted, constant(true));
272
320
  const editModeValues = Object.keys(EditMode);
273
321
  const editModeIsStatic = !!expBinding && editModeValues.includes(expBinding as EditMode);
274
322
  const editable = !!expBinding && ((editModeIsStatic && expBinding === EditMode.Editable) || !editModeIsStatic);
@@ -281,15 +329,16 @@ const MassEditHelper = {
281
329
 
282
330
  if (inputType) {
283
331
  const isReadOnly = isReadOnlyExpression(oPropertyInfo);
284
-
332
+ const displayMode = CommonUtils.computeDisplayMode(oPropertyContext.getObject());
285
333
  oResult = {
286
- "label": sLabelText + ":",
334
+ "label": sLabelText,
287
335
  "dataProperty": sDataPropertyPath,
288
336
  "isValueHelpEnabled": bValueHelpEnabled ? bValueHelpEnabled : false,
289
- "unitProperty": sUnitPropertyPath ? sUnitPropertyPath : false,
290
- "isValueHelpEnabledForUnit": bValueHelpEnabledForUnit ? bValueHelpEnabledForUnit : false,
291
- "propertyPathForValueHelp": sCurrentEntitySetName + "/" + sDataPropertyPath,
292
- "propertyPathForValueHelpUnit": sCurrentEntitySetName + "/" + sUnitPropertyPath,
337
+ "unitProperty": sUnitPropertyPath && !sDataPropertyPath.includes("/") ? sUnitPropertyPath : false,
338
+ "isValueHelpEnabledForUnit":
339
+ bValueHelpEnabledForUnit && !sUnitPropertyPath.includes("/") ? bValueHelpEnabledForUnit : false,
340
+ "propertyPathForValueHelp": `${sCurrentEntitySetName}/${sDataPropertyPath}`,
341
+ "propertyPathForValueHelpUnit": sUnitPropertyPath && `${sCurrentEntitySetName}/${sUnitPropertyPath}`,
293
342
  "isFieldRequired": getRequiredExpression(oPropertyInfo, oDataFieldConverted, true),
294
343
  "defaultSelectionPath": sDataPropertyPath
295
344
  ? MassEditHelper.getDefaultSelectionPathComboBox(aContexts, sDataPropertyPath)
@@ -298,11 +347,14 @@ const MassEditHelper = {
298
347
  ? MassEditHelper.getDefaultSelectionPathComboBox(aContexts, sUnitPropertyPath)
299
348
  : false,
300
349
  "entitySet": sCurrentEntitySetName,
301
- "textBinding": oTextBinding,
350
+ "display": displayMode,
351
+ "descriptionPath": MassEditHelper.getTextPath(sDataPropertyPath, oTextBinding, displayMode),
302
352
  "nullable": oPropertyInfo.nullable !== undefined ? oPropertyInfo.nullable : true,
303
353
  "isPropertyReadOnly": isReadOnly !== undefined ? isReadOnly : false,
304
354
  "inputType": inputType,
305
- "editMode": editable ? expBinding : undefined
355
+ "editMode": editable ? expBinding : undefined,
356
+ "unitDataPath": sUnitPropertyPath && "fieldsInfo>/unitData/",
357
+ "valuesPath": "fieldsInfo>/values/"
306
358
  };
307
359
  aDataArray.push(oResult);
308
360
  }
@@ -342,113 +394,147 @@ const MassEditHelper = {
342
394
  "applyButtonText": bDisplayMode
343
395
  ? oResourceBundle.getText("C_MASS_EDIT_SAVE_BUTTON_TEXT")
344
396
  : oResourceBundle.getText("C_MASS_EDIT_APPLY_BUTTON_TEXT"),
345
- "cancelButtonText": oResourceBundle.getText("C_MASS_EDIT_CANCEL_BUTTON_TEXT")
397
+ "useValueHelpValue": "< Use Value Help >",
398
+ "cancelButtonText": oResourceBundle.getText("C_MASS_EDIT_CANCEL_BUTTON_TEXT"),
399
+ "noFields": oResourceBundle.getText("C_MASS_EDIT_NO_EDITABLE_FIELDS"),
400
+ "okButtonText": oResourceBundle.getText("C_COMMON_DIALOG_OK")
346
401
  };
347
402
  },
348
403
 
349
404
  /**
350
405
  * Adds a suffix to the 'keep existing' property of the comboBox.
351
406
  *
352
- * @param {string} sInputType InputType of the field
353
- * @returns {string}
407
+ * @param sInputType InputType of the field
408
+ * @returns The modified string
354
409
  */
355
- getSuffixForKeepExisiting: function (sInputType: string) {
356
- let sResult = "Values";
357
-
358
- switch (sInputType) {
359
- //TODO - Add for other control types as well (Radio Button, Email, Input, MDC Fields, Image etc.)
360
- case "DatePicker":
361
- sResult = "Dates";
362
- break;
363
- case "CheckBox":
364
- sResult = "Settings";
365
- break;
366
- }
367
- return sResult;
368
- },
410
+ // getSuffixForKeepExisiting: function (sInputType: string) {
411
+ // let sResult = "Values";
412
+
413
+ // switch (sInputType) {
414
+ // //TODO - Add for other control types as well (Radio Button, Email, Input, MDC Fields, Image etc.)
415
+ // case "DatePicker":
416
+ // sResult = "Dates";
417
+ // break;
418
+ // case "CheckBox":
419
+ // sResult = "Settings";
420
+ // break;
421
+ // default:
422
+ // sResult = "Values";
423
+ // }
424
+ // return sResult;
425
+ // },
369
426
 
370
427
  /**
371
428
  * Adds default values to the model [Keep Existing Values, Leave Blank].
372
429
  *
373
- * @param {Array} aValues Array instance where the default data needs to be added
374
- * @param {Array} aContexts Contexts for mass edit
375
- * @param {object} oDefaultValues Default values from Application Manifest
376
- * @param {object} oPropertyInfo Property information
377
- * @param {boolean} bUOMField
430
+ * @param aValues Array instance where the default data needs to be added
431
+ * @param oDefaultValues Default values from Application Manifest
432
+ * @param oPropertyInfo Property information
433
+ * @param bUOMField
378
434
  */
379
- setDefaultValuesToDialog: function (aValues: any[], aContexts: any[], oDefaultValues: any, oPropertyInfo: any, bUOMField?: boolean) {
435
+ setDefaultValuesToDialog: function (aValues: any, oDefaultValues: any, oPropertyInfo: any, bUOMField?: boolean) {
380
436
  const sPropertyPath = bUOMField ? oPropertyInfo.unitProperty : oPropertyInfo.dataProperty,
381
437
  sInputType = oPropertyInfo.inputType,
382
438
  bPropertyRequired = oPropertyInfo.isFieldRequired;
383
- const sSuffixForKeepExisting = MassEditHelper.getSuffixForKeepExisiting(sInputType);
384
- //TODO - Add <<Use Value Help or control implmentation>> and related key by checking if value help is enabled for property or Unit.
385
- //TODO - Add option Apply to Empty Fields only for Both Value Help and controls.
386
- const bValueExistsForPropertyPath = aContexts.some(function (oSelectedContext: any) {
387
- return oSelectedContext.getObject(sPropertyPath);
388
- });
389
- if (bValueExistsForPropertyPath) {
390
- if (bPropertyRequired !== "true" && !bUOMField) {
391
- aValues.unshift({ text: oDefaultValues.clearFieldValue, key: "ClearFieldValue/" + sPropertyPath });
392
- }
439
+ // const sSuffixForKeepExisting = MassEditHelper.getSuffixForKeepExisiting(sInputType);
440
+ const sSuffixForKeepExisting = "Values";
441
+ aValues.defaultOptions = aValues.defaultOptions || [];
442
+ const selectOptionsExist = aValues.selectOptions && aValues.selectOptions.length > 0;
443
+ const keepEntry = {
444
+ text: `${oDefaultValues.keepExistingPrefix} ${sSuffixForKeepExisting} >`,
445
+ key: `Default/${sPropertyPath}`
446
+ };
447
+
448
+ if (sInputType === "CheckBox") {
449
+ const falseEntry = { text: "No", key: `${sPropertyPath}/false`, textInfo: { value: false } };
450
+ const truthyEntry = { text: "Yes", key: `${sPropertyPath}/true`, textInfo: { value: true } };
451
+ aValues.unshift(falseEntry);
452
+ aValues.defaultOptions.unshift(falseEntry);
453
+ aValues.unshift(truthyEntry);
454
+ aValues.defaultOptions.unshift(truthyEntry);
455
+ aValues.unshift(keepEntry);
456
+ aValues.defaultOptions.unshift(keepEntry);
393
457
  } else {
394
- aValues.unshift({ text: oDefaultValues.leaveBlankValue, key: "Empty/" + sPropertyPath });
458
+ if (oPropertyInfo.isValueHelpEnabled || (oPropertyInfo.isValueHelpEnabledForUnit && bUOMField)) {
459
+ const vhdEntry = { text: oDefaultValues.useValueHelpValue, key: `UseValueHelpValue/${sPropertyPath}` };
460
+ aValues.unshift(vhdEntry);
461
+ aValues.defaultOptions.unshift(vhdEntry);
462
+ }
463
+ if (selectOptionsExist) {
464
+ if (bPropertyRequired !== "true" && !bUOMField) {
465
+ const clearEntry = { text: oDefaultValues.clearFieldValue, key: `ClearFieldValue/${sPropertyPath}` };
466
+ aValues.unshift(clearEntry);
467
+ aValues.defaultOptions.unshift(clearEntry);
468
+ }
469
+ aValues.unshift(keepEntry);
470
+ aValues.defaultOptions.unshift(keepEntry);
471
+ } else {
472
+ const emptyEntry = { text: oDefaultValues.leaveBlankValue, key: `Default/${sPropertyPath}` };
473
+ aValues.unshift(emptyEntry);
474
+ aValues.defaultOptions.unshift(emptyEntry);
475
+ }
395
476
  }
396
- aValues.unshift({
397
- text: oDefaultValues.keepExistingPrefix + " " + sSuffixForKeepExisting + " >",
398
- key: "Default/" + sPropertyPath
399
- });
400
477
  },
401
478
 
479
+ /**
480
+ * Get text arrangement info for a context property.
481
+ *
482
+ * @param property Property Path
483
+ * @param descriptionPath Path to text association of the property
484
+ * @param displayMode Display mode of the property and text association
485
+ * @param selectedContext Context to find the full text
486
+ * @returns The text arrangement
487
+ */
402
488
  getTextArrangementInfo: function (
403
- sProperty: any,
404
- oTextBinding: any,
405
- sCurrentEntitySet: any,
406
- oSelectedContext: any
407
- ): TextArrangementInfo | undefined {
408
- const oMetaModel = oSelectedContext.getModel().getMetaModel();
409
- const sDisplayMode = CommonUtils.computeDisplayMode(oMetaModel.getObject(sCurrentEntitySet + "/" + sProperty + "@"));
410
- let sDescriptionPath, sValue, sDescriptionValue, sFullText;
411
- if (oTextBinding && (oTextBinding.path || (oTextBinding.parameters && oTextBinding.parameters.length)) && sProperty) {
412
- if (oTextBinding.path) {
413
- if (sDisplayMode === "Description") {
414
- sValue = oSelectedContext.getObject(sProperty);
415
- sDescriptionValue = oSelectedContext.getObject(oTextBinding.path);
416
- sFullText = sDescriptionValue;
417
- } else if (sDisplayMode === "Value") {
418
- sValue = oSelectedContext.getObject(sProperty);
419
- sFullText = sValue;
420
- }
421
- } else if (oTextBinding.parameters) {
422
- oTextBinding.parameters.forEach(function (oProps: any) {
423
- if (oProps.path && oProps.path !== sProperty) {
424
- sDescriptionPath = oProps.path;
425
- }
426
- });
427
- sValue = oSelectedContext.getObject(sProperty);
428
- sDescriptionValue = oSelectedContext.getObject(sDescriptionPath);
429
- if (sDisplayMode === "ValueDescription" && sValue && sDescriptionValue) {
430
- sFullText = sValue + " (" + sDescriptionValue + ")";
431
- } else if (sDisplayMode === "DescriptionValue" && sDescriptionValue && sValue) {
432
- sFullText = sDescriptionValue + " (" + sValue + ")";
433
- }
489
+ property: string,
490
+ descriptionPath: string,
491
+ displayMode: string,
492
+ selectedContext: Context
493
+ ): TextArrangementInfo {
494
+ let value = selectedContext.getObject(property),
495
+ descriptionValue,
496
+ fullText;
497
+ if (descriptionPath && property) {
498
+ switch (displayMode) {
499
+ case "Description":
500
+ descriptionValue = selectedContext.getObject(descriptionPath) || "";
501
+ fullText = descriptionValue;
502
+ break;
503
+ case "Value":
504
+ value = selectedContext.getObject(property) || "";
505
+ fullText = value;
506
+ break;
507
+ case "ValueDescription":
508
+ value = selectedContext.getObject(property) || "";
509
+ descriptionValue = selectedContext.getObject(descriptionPath) || "";
510
+ fullText = descriptionValue ? `${value} (${descriptionValue})` : value;
511
+ break;
512
+ case "DescriptionValue":
513
+ value = selectedContext.getObject(property) || "";
514
+ descriptionValue = selectedContext.getObject(descriptionPath) || "";
515
+ fullText = descriptionValue ? `${descriptionValue} (${value})` : value;
516
+ break;
517
+ default:
518
+ Log.info(`Display Property not applicable: ${property}`);
519
+ break;
434
520
  }
435
- return {
436
- "textArrangement": sDisplayMode,
437
- "valuePath": sProperty,
438
- "descriptionPath": sDescriptionPath,
439
- "value": sValue,
440
- "description": sDescriptionValue,
441
- "fullText": sFullText
442
- };
443
521
  }
444
- return undefined;
522
+
523
+ return {
524
+ "textArrangement": displayMode,
525
+ "valuePath": property,
526
+ "descriptionPath": descriptionPath,
527
+ "value": value,
528
+ "description": descriptionValue,
529
+ "fullText": fullText
530
+ };
445
531
  },
446
532
 
447
533
  /**
448
534
  * Return the visibility valuue for the ManagedObject Any.
449
535
  *
450
- * @param {AnyType} any The ManagedObject Any to be used to calculate the visible value of the binding.
451
- * @returns {boolean} Returns true if the mass edit field is editable.
536
+ * @param any The ManagedObject Any to be used to calculate the visible value of the binding.
537
+ * @returns Returns true if the mass edit field is editable.
452
538
  */
453
539
  isEditable: function (any: AnyType): boolean {
454
540
  const binding = any.getBinding("any");
@@ -459,25 +545,25 @@ const MassEditHelper = {
459
545
  /**
460
546
  * Calculate and update the visibility of mass edit field on change of the ManagedObject Any binding.
461
547
  *
462
- * @param {JSONModel} oDialogDataModel Model to be used runtime.
463
- * @param {string} dataProperty Field name.
548
+ * @param oDialogDataModel Model to be used runtime.
549
+ * @param dataProperty Field name.
464
550
  */
465
551
  onContextEditableChange: function (oDialogDataModel: JSONModel, dataProperty: string): void {
466
- const objectsForVisibility = oDialogDataModel.getProperty("/values/" + dataProperty + "/objectsForVisibility") || [];
552
+ const objectsForVisibility = oDialogDataModel.getProperty(`/values/${dataProperty}/objectsForVisibility`) || [];
467
553
  const editable = objectsForVisibility.some(MassEditHelper.isEditable);
468
554
 
469
555
  if (editable) {
470
- oDialogDataModel.setProperty("/values/" + dataProperty + "/visible", editable);
556
+ oDialogDataModel.setProperty(`/values/${dataProperty}/visible`, editable);
471
557
  }
472
558
  },
473
559
 
474
560
  /**
475
561
  * Update Managed Object Any for visibility of the mass edit fields.
476
562
  *
477
- * @param {AnyType} mOToUse The ManagedObject Any to be used to calculate the visible value of the binding.
478
- * @param {JSONModel} oDialogDataModel Model to be used runtime.
479
- * @param {string} dataProperty Field name.
480
- * @param {any} values Values of the field.
563
+ * @param mOToUse The ManagedObject Any to be used to calculate the visible value of the binding.
564
+ * @param oDialogDataModel Model to be used runtime.
565
+ * @param dataProperty Field name.
566
+ * @param values Values of the field.
481
567
  */
482
568
  updateOnContextChange: function (mOToUse: AnyType, oDialogDataModel: JSONModel, dataProperty: string, values: any) {
483
569
  const binding = mOToUse.getBinding("any");
@@ -491,11 +577,11 @@ const MassEditHelper = {
491
577
  /**
492
578
  * Get bound object to calculate the visibility of contexts.
493
579
  *
494
- * @param {BindingExpression<boolean> | ExpressionOrPrimitive<boolean>} expBinding Binding String object.
495
- * @param {object} context Context the binding value.
496
- * @returns {AnyType} The ManagedObject Any to be used to calculate the visible value of the binding.
580
+ * @param expBinding Binding String object.
581
+ * @param context Context the binding value.
582
+ * @returns The ManagedObject Any to be used to calculate the visible value of the binding.
497
583
  */
498
- getBoundObject: function (expBinding: BindingExpression<string> | ExpressionOrPrimitive<string>, context: Context): AnyType {
584
+ getBoundObject: function (expBinding: CompiledBindingToolkitExpression, context: Context): AnyType {
499
585
  const mOToUse = new Any({ any: expBinding });
500
586
  const model = context.getModel();
501
587
  mOToUse.setModel(model);
@@ -507,15 +593,15 @@ const MassEditHelper = {
507
593
  /**
508
594
  * Get the visibility of the field.
509
595
  *
510
- * @param {BindingExpression<boolean> | ExpressionOrPrimitive<boolean>} expBinding Binding String object.
511
- * @param {JSONModel} oDialogDataModel Model to be used runtime.
512
- * @param {string} dataProperty Field name.
513
- * @param {any} values Values of the field.
514
- * @param {object} context Context the binding value.
515
- * @returns {boolean} Returns true if the mass edit field is editable.
596
+ * @param expBinding Binding String object.
597
+ * @param oDialogDataModel Model to be used runtime.
598
+ * @param dataProperty Field name.
599
+ * @param values Values of the field.
600
+ * @param context Context the binding value.
601
+ * @returns Returns true if the mass edit field is editable.
516
602
  */
517
603
  getFieldVisiblity: function (
518
- expBinding: BindingExpression<string> | ExpressionOrPrimitive<string>,
604
+ expBinding: CompiledBindingToolkitExpression,
519
605
  oDialogDataModel: JSONModel,
520
606
  dataProperty: string,
521
607
  values: any,
@@ -535,165 +621,261 @@ const MassEditHelper = {
535
621
  * => The model consists of values shown in the comboBox of the dialog (Leave Blank, Keep Existing Values, or any property value for the selected context, etc.)
536
622
  * => The model will capture runtime changes in the results property (the value entered in the comboBox).
537
623
  *
538
- * @param {Array} aContexts Contexts for mass edit
539
- * @param {Array} aDataArray Array containing data related to the dialog used by both the static and the runtime model
540
- * @param {object} oDefaultValues Default values from i18n
541
- * @returns {object}
624
+ * @param aContexts Contexts for mass edit
625
+ * @param aDataArray Array containing data related to the dialog used by both the static and the runtime model
626
+ * @param oDefaultValues Default values from i18n
627
+ * @param dialogContext Transient context for mass edit dialog.
628
+ * @returns The runtime model
542
629
  */
543
- setRuntimeModelOnDialog: function (aContexts: any[], aDataArray: any[], oDefaultValues: any) {
630
+ setRuntimeModelOnDialog: function (aContexts: any[], aDataArray: any[], oDefaultValues: any, dialogContext: Context) {
544
631
  const aValues: any[] = [];
545
632
  const aUnitData: any[] = [];
546
633
  const aResults: any[] = [];
547
634
  const aReadOnlyFieldInfo: any[] = [];
548
- const oDistinctValueMap: any = {};
549
- const oData = { "values": aValues, "unitData": aUnitData, "results": aResults, "readablePropertyData": aReadOnlyFieldInfo };
635
+ const oData = {
636
+ "values": aValues,
637
+ "unitData": aUnitData,
638
+ "results": aResults,
639
+ "readablePropertyData": aReadOnlyFieldInfo,
640
+ "selectedKey": undefined,
641
+ "noFields": oDefaultValues.noFields
642
+ };
550
643
  const oDialogDataModel = new JSONModel(oData);
551
- let sPropertyName;
552
- aDataArray.forEach(function (oData: any) {
644
+ aDataArray.forEach(function (oInData: any) {
553
645
  let oTextInfo;
554
- if (oData.dataProperty && oData.dataProperty.indexOf("/") > -1) {
555
- const aFinalPath = MassEditHelper.initLastLevelOfPropertyPath(oData.dataProperty, aValues);
556
- const aPropertyPaths = oData.dataProperty.split("/");
557
- let sPropertyKey;
558
- for (let i = 0; i < aContexts.length; i++) {
559
- const sMultiLevelPathValue = aContexts[i].getObject(oData.dataProperty);
560
- sPropertyKey = oData.dataProperty + "/" + sMultiLevelPathValue;
646
+ let sPropertyKey;
647
+ let sUnitPropertyName;
648
+ const oDistinctValueMap: any = {};
649
+ const oDistinctUnitMap: any = {};
650
+ if (oInData.dataProperty && oInData.dataProperty.indexOf("/") > -1) {
651
+ const aFinalPath = MassEditHelper.initLastLevelOfPropertyPath(oInData.dataProperty, aValues /*, dialogContext */);
652
+ const aPropertyPaths = oInData.dataProperty.split("/");
653
+
654
+ for (const context of aContexts) {
655
+ const sMultiLevelPathValue = context.getObject(oInData.dataProperty);
656
+ sPropertyKey = `${oInData.dataProperty}/${sMultiLevelPathValue}`;
561
657
  if (!oDistinctValueMap[sPropertyKey] && aFinalPath[aPropertyPaths[aPropertyPaths.length - 1]]) {
562
658
  oTextInfo = MassEditHelper.getTextArrangementInfo(
563
- oData.dataProperty,
564
- oData.textBinding,
565
- oData.entitySet,
566
- aContexts[i]
659
+ oInData.dataProperty,
660
+ oInData.descriptionPath,
661
+ oInData.display,
662
+ context
567
663
  );
568
664
  aFinalPath[aPropertyPaths[aPropertyPaths.length - 1]].push({
569
665
  "text": (oTextInfo && oTextInfo.fullText) || sMultiLevelPathValue,
570
- "key": oData.dataProperty,
666
+ "key": sPropertyKey,
571
667
  "textInfo": oTextInfo
572
668
  });
573
669
  oDistinctValueMap[sPropertyKey] = sMultiLevelPathValue;
574
670
  }
575
671
  }
672
+ // if (Object.keys(oDistinctValueMap).length === 1) {
673
+ // dialogContext.setProperty(oData.dataProperty, sPropertyKey && oDistinctValueMap[sPropertyKey]);
674
+ // }
675
+
676
+ aFinalPath[aPropertyPaths[aPropertyPaths.length - 1]].textInfo = {
677
+ descriptionPath: oInData.descriptionPath,
678
+ valuePath: oInData.dataProperty,
679
+ displayMode: oInData.display
680
+ };
576
681
  } else {
577
- aValues[oData.dataProperty] = aValues[oData.dataProperty] || [];
578
- if (oData.unitProperty) {
579
- aUnitData[oData.unitProperty] = aUnitData[oData.unitProperty] || [];
682
+ aValues[oInData.dataProperty] = aValues[oInData.dataProperty] || [];
683
+ aValues[oInData.dataProperty]["selectOptions"] = aValues[oInData.dataProperty]["selectOptions"] || [];
684
+ if (oInData.unitProperty) {
685
+ aUnitData[oInData.unitProperty] = aUnitData[oInData.unitProperty] || [];
686
+ aUnitData[oInData.unitProperty]["selectOptions"] = aUnitData[oInData.unitProperty]["selectOptions"] || [];
580
687
  }
581
- for (let i = 0; i < aContexts.length; i++) {
582
- const oDataObject = aContexts[i].getObject();
583
- sPropertyName = oData.dataProperty + "/" + oDataObject[oData.dataProperty];
584
- if (oData.dataProperty && oDataObject[oData.dataProperty] && !oDistinctValueMap[sPropertyName]) {
585
- oTextInfo = MassEditHelper.getTextArrangementInfo(
586
- oData.dataProperty,
587
- oData.textBinding,
588
- oData.entitySet,
589
- aContexts[i]
590
- );
591
- aValues[oData.dataProperty].push({
592
- "text": (oTextInfo && oTextInfo.fullText) || oDataObject[oData.dataProperty],
593
- "key": oData.dataProperty,
594
- "textInfo": oTextInfo
595
- });
596
- oDistinctValueMap[sPropertyName] = oDataObject[oData.dataProperty];
597
- }
598
- if (oData.unitProperty && oDataObject[oData.unitProperty]) {
599
- sPropertyName = oData.unitProperty + "/" + oDataObject[oData.unitProperty];
600
- if (!oDistinctValueMap[sPropertyName]) {
688
+ for (const context of aContexts) {
689
+ const oDataObject = context.getObject();
690
+ sPropertyKey = `${oInData.dataProperty}/${oDataObject[oInData.dataProperty]}`;
691
+ if (oInData.dataProperty && oDataObject[oInData.dataProperty] && !oDistinctValueMap[sPropertyKey]) {
692
+ if (oInData.inputType != "CheckBox") {
601
693
  oTextInfo = MassEditHelper.getTextArrangementInfo(
602
- oData.unitProperty,
603
- oData.textBinding,
604
- oData.entitySet,
605
- aContexts[i]
694
+ oInData.dataProperty,
695
+ oInData.descriptionPath,
696
+ oInData.display,
697
+ context
606
698
  );
607
- aUnitData[oData.unitProperty].push({
608
- "text": (oTextInfo && oTextInfo.fullText) || oDataObject[oData.unitProperty],
609
- "key": oData.unitProperty,
699
+ const entry = {
700
+ "text": (oTextInfo && oTextInfo.fullText) || oDataObject[oInData.dataProperty],
701
+ "key": sPropertyKey,
610
702
  "textInfo": oTextInfo
611
- });
612
- oDistinctValueMap[sPropertyName] = oDataObject[oData.unitProperty];
703
+ };
704
+ aValues[oInData.dataProperty].push(entry);
705
+ aValues[oInData.dataProperty]["selectOptions"].push(entry);
706
+ }
707
+ oDistinctValueMap[sPropertyKey] = oDataObject[oInData.dataProperty];
708
+ }
709
+ if (oInData.unitProperty && oDataObject[oInData.unitProperty]) {
710
+ sUnitPropertyName = `${oInData.unitProperty}/${oDataObject[oInData.unitProperty]}`;
711
+ if (!oDistinctUnitMap[sUnitPropertyName]) {
712
+ if (oInData.inputType != "CheckBox") {
713
+ oTextInfo = MassEditHelper.getTextArrangementInfo(
714
+ oInData.unitProperty,
715
+ oInData.descriptionPath,
716
+ oInData.display,
717
+ context
718
+ );
719
+ const unitEntry = {
720
+ "text": (oTextInfo && oTextInfo.fullText) || oDataObject[oInData.unitProperty],
721
+ "key": sUnitPropertyName,
722
+ "textInfo": oTextInfo
723
+ };
724
+ aUnitData[oInData.unitProperty].push(unitEntry);
725
+ aUnitData[oInData.unitProperty]["selectOptions"].push(unitEntry);
726
+ }
727
+ oDistinctUnitMap[sUnitPropertyName] = oDataObject[oInData.unitProperty];
613
728
  }
614
729
  }
615
730
  }
731
+ aValues[oInData.dataProperty].textInfo = {
732
+ descriptionPath: oInData.descriptionPath,
733
+ valuePath: oInData.dataProperty,
734
+ displayMode: oInData.display
735
+ };
736
+ if (Object.keys(oDistinctValueMap).length === 1) {
737
+ dialogContext.setProperty(oInData.dataProperty, sPropertyKey && oDistinctValueMap[sPropertyKey]);
738
+ }
739
+ if (Object.keys(oDistinctUnitMap).length === 1) {
740
+ dialogContext.setProperty(oInData.unitProperty, sUnitPropertyName && oDistinctUnitMap[sUnitPropertyName]);
741
+ }
616
742
  }
617
743
  });
618
- aDataArray.forEach(function (oData: any) {
619
- let values: any;
620
- if (oData.dataProperty.indexOf("/") > -1) {
621
- const sMultiLevelPropPathValue = MassEditHelper.getValueForMultiLevelPath(oData.dataProperty, aValues);
744
+ aDataArray.forEach(function (oInData: any) {
745
+ let values: any = {};
746
+ if (oInData.dataProperty.indexOf("/") > -1) {
747
+ const sMultiLevelPropPathValue = MassEditHelper.getValueForMultiLevelPath(oInData.dataProperty, aValues);
622
748
  if (!sMultiLevelPropPathValue) {
623
- sMultiLevelPropPathValue.push({ text: oDefaultValues.leaveBlankValue, key: "Empty/" + oData.dataProperty });
749
+ sMultiLevelPropPathValue.push({ text: oDefaultValues.leaveBlankValue, key: `Empty/${oInData.dataProperty}` });
624
750
  } else {
625
- MassEditHelper.setDefaultValuesToDialog(sMultiLevelPropPathValue, aContexts, oDefaultValues, oData);
751
+ MassEditHelper.setDefaultValuesToDialog(sMultiLevelPropPathValue, oDefaultValues, oInData);
626
752
  }
627
753
  values = sMultiLevelPropPathValue;
628
- } else if (aValues[oData.dataProperty] && aValues[oData.dataProperty].length) {
629
- MassEditHelper.setDefaultValuesToDialog(aValues[oData.dataProperty], aContexts, oDefaultValues, oData);
630
- values = aValues[oData.dataProperty];
754
+ } else if (aValues[oInData.dataProperty]) {
755
+ aValues[oInData.dataProperty] = aValues[oInData.dataProperty] || [];
756
+ MassEditHelper.setDefaultValuesToDialog(aValues[oInData.dataProperty], oDefaultValues, oInData);
757
+ values = aValues[oInData.dataProperty];
631
758
  }
632
- if (aUnitData[oData.unitProperty] && aUnitData[oData.unitProperty].length) {
633
- MassEditHelper.setDefaultValuesToDialog(aUnitData[oData.unitProperty], aContexts, oDefaultValues, oData, true);
759
+
760
+ if (aUnitData[oInData.unitProperty] && aUnitData[oInData.unitProperty].length) {
761
+ MassEditHelper.setDefaultValuesToDialog(aUnitData[oInData.unitProperty], oDefaultValues, oInData, true);
762
+ aUnitData[oInData.unitProperty].textInfo = {};
763
+ aUnitData[oInData.unitProperty].selectedKey = MassEditHelper.getDefaultSelectionPathComboBox(
764
+ aContexts,
765
+ oInData.unitProperty
766
+ );
767
+ aUnitData[oInData.unitProperty].inputType = oInData.inputType;
634
768
  } else if (
635
- (oData.dataProperty && aValues[oData.dataProperty] && !aValues[oData.dataProperty].length) ||
636
- (oData.unitProperty && aUnitData[oData.unitProperty] && !aUnitData[oData.unitProperty].length)
769
+ (oInData.dataProperty && aValues[oInData.dataProperty] && !aValues[oInData.dataProperty].length) ||
770
+ (oInData.unitProperty && aUnitData[oInData.unitProperty] && !aUnitData[oInData.unitProperty].length)
637
771
  ) {
638
772
  const bClearFieldOrBlankValueExists =
639
- aValues[oData.dataProperty] &&
640
- aValues[oData.dataProperty].some(function (obj: any) {
773
+ aValues[oInData.dataProperty] &&
774
+ aValues[oInData.dataProperty].some(function (obj: any) {
641
775
  return obj.text === "< Clear Values >" || obj.text === "< Leave Blank >";
642
776
  });
643
- if (oData.dataProperty && !bClearFieldOrBlankValueExists) {
644
- aValues[oData.dataProperty].push({ text: oDefaultValues.leaveBlankValue, key: "Empty/" + oData.dataProperty });
777
+ if (oInData.dataProperty && !bClearFieldOrBlankValueExists) {
778
+ aValues[oInData.dataProperty].push({ text: oDefaultValues.leaveBlankValue, key: `Empty/${oInData.dataProperty}` });
645
779
  }
646
780
  const bClearFieldOrBlankUnitValueExists =
647
- aUnitData[oData.unitProperty] &&
648
- aUnitData[oData.unitProperty].some(function (obj: any) {
781
+ aUnitData[oInData.unitProperty] &&
782
+ aUnitData[oInData.unitProperty].some(function (obj: any) {
649
783
  return obj.text === "< Clear Values >" || obj.text === "< Leave Blank >";
650
784
  });
651
- if (oData.unitProperty && !bClearFieldOrBlankUnitValueExists) {
652
- aUnitData[oData.unitProperty].push({
653
- text: oDefaultValues.leaveBlankValue,
654
- key: "Empty/" + oData.unitProperty
655
- });
785
+ if (oInData.unitProperty) {
786
+ if (!bClearFieldOrBlankUnitValueExists) {
787
+ aUnitData[oInData.unitProperty].push({
788
+ text: oDefaultValues.leaveBlankValue,
789
+ key: `Empty/${oInData.unitProperty}`
790
+ });
791
+ }
792
+ aUnitData[oInData.unitProperty].textInfo = {};
793
+ aUnitData[oInData.unitProperty].selectedKey = MassEditHelper.getDefaultSelectionPathComboBox(
794
+ aContexts,
795
+ oInData.unitProperty
796
+ );
797
+ aUnitData[oInData.unitProperty].inputType = oInData.inputType;
656
798
  }
657
799
  }
658
- if (oData.isPropertyReadOnly && typeof oData.isPropertyReadOnly === "boolean") {
659
- aReadOnlyFieldInfo.push({ "property": oData.dataProperty, value: oData.isPropertyReadOnly, type: "Default" });
800
+ if (oInData.isPropertyReadOnly && typeof oInData.isPropertyReadOnly === "boolean") {
801
+ aReadOnlyFieldInfo.push({ "property": oInData.dataProperty, value: oInData.isPropertyReadOnly, type: "Default" });
660
802
  } else if (
661
- oData.isPropertyReadOnly &&
662
- oData.isPropertyReadOnly.operands &&
663
- oData.isPropertyReadOnly.operands[0] &&
664
- oData.isPropertyReadOnly.operands[0].operand1 &&
665
- oData.isPropertyReadOnly.operands[0].operand2
803
+ oInData.isPropertyReadOnly &&
804
+ oInData.isPropertyReadOnly.operands &&
805
+ oInData.isPropertyReadOnly.operands[0] &&
806
+ oInData.isPropertyReadOnly.operands[0].operand1 &&
807
+ oInData.isPropertyReadOnly.operands[0].operand2
666
808
  ) {
667
809
  // This needs to be refactored in accordance with the ReadOnlyExpression change
668
810
  aReadOnlyFieldInfo.push({
669
- "property": oData.dataProperty,
670
- propertyPath: oData.isPropertyReadOnly.operands[0].operand1.path,
671
- propertyValue: oData.isPropertyReadOnly.operands[0].operand2.value,
811
+ "property": oInData.dataProperty,
812
+ propertyPath: oInData.isPropertyReadOnly.operands[0].operand1.path,
813
+ propertyValue: oInData.isPropertyReadOnly.operands[0].operand2.value,
672
814
  type: "Path"
673
815
  });
674
816
  }
675
817
 
676
818
  // Setting visbility of the mass edit field.
677
- if (oData.editMode) {
819
+ if (oInData.editMode) {
678
820
  values.visible =
679
- oData.editMode === EditMode.Editable ||
821
+ oInData.editMode === EditMode.Editable ||
680
822
  aContexts.some(
681
- MassEditHelper.getFieldVisiblity.bind(MassEditHelper, oData.editMode, oDialogDataModel, oData.dataProperty, values)
823
+ MassEditHelper.getFieldVisiblity.bind(
824
+ MassEditHelper,
825
+ oInData.editMode,
826
+ oDialogDataModel,
827
+ oInData.dataProperty,
828
+ values
829
+ )
682
830
  );
683
831
  } else {
684
832
  values.visible = true;
685
833
  }
834
+ values.selectedKey = MassEditHelper.getDefaultSelectionPathComboBox(aContexts, oInData.dataProperty);
835
+ values.inputType = oInData.inputType;
836
+ values.unitProperty = oInData.unitProperty;
686
837
  });
838
+
687
839
  return oDialogDataModel;
688
840
  },
841
+ /**
842
+ * Gets transient context for dialog.
843
+ *
844
+ * @param table Instance of Table.
845
+ * @param dialog Mass Edit Dialog.
846
+ * @returns Promise returning instance of dialog.
847
+ */
848
+ getDialogContext: function (table: Table, dialog?: Dialog): Context {
849
+ let transCtx: Context = (dialog && dialog.getBindingContext()) as Context;
850
+
851
+ if (!transCtx) {
852
+ const model = table.getModel();
853
+ const listBinding = table.getRowBinding();
854
+ const transientListBinding = model.bindList(listBinding.getPath(), listBinding.getContext(), [], [], {
855
+ $$updateGroupId: "submitLater"
856
+ }) as ODataListBinding;
857
+ (transientListBinding as any).refreshInternal = function () {
858
+ /* */
859
+ };
860
+ transCtx = transientListBinding.create({}, true);
861
+ }
862
+
863
+ return transCtx;
864
+ },
865
+
866
+ onDialogOpen: function (event: any): void {
867
+ const source = event.getSource();
868
+ const fieldsInfoModel = source.getModel("fieldsInfo");
869
+ fieldsInfoModel.setProperty("/isOpen", true);
870
+ },
689
871
 
690
872
  /**
691
873
  * Create the mass edit dialog.
692
874
  *
693
- * @param {object} oTable Instance of Table
694
- * @param {Array} aContexts Contexts for mass edit
695
- * @param {object} oController Controller for the view
696
- * @returns {object} Promise returning instance of dialog.
875
+ * @param oTable Instance of Table
876
+ * @param aContexts Contexts for mass edit
877
+ * @param oController Controller for the view
878
+ * @returns Promise returning instance of dialog.
697
879
  */
698
880
  createDialog: function (oTable: Table, aContexts: any[], oController: PageController) {
699
881
  const sFragmentName = "sap/fe/core/controls/massEdit/MassEditDialog",
@@ -701,7 +883,8 @@ const MassEditHelper = {
701
883
  oResourceBundle = (Core as CoreEx).getLibraryResourceBundle("sap.fe.core"),
702
884
  oDefaultValues = MassEditHelper.getDefaultTextsForDialog(oResourceBundle, aContexts.length, oTable),
703
885
  oDataFieldModel = MassEditHelper.prepareDataForDialog(oTable, aContexts, aDataArray),
704
- oDialogDataModel = MassEditHelper.setRuntimeModelOnDialog(aContexts, aDataArray, oDefaultValues);
886
+ dialogContext = MassEditHelper.getDialogContext(oTable),
887
+ oDialogDataModel = MassEditHelper.setRuntimeModelOnDialog(aContexts, aDataArray, oDefaultValues, dialogContext);
705
888
 
706
889
  return new Promise(function (resolve: (value: any) => void, reject: (reason?: any) => void) {
707
890
  const oFragment = XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment");
@@ -719,24 +902,32 @@ const MassEditHelper = {
719
902
  }
720
903
  )
721
904
  )
722
- .then(function (oFragment: any) {
723
- return Fragment.load({ definition: oFragment }).then(function (oDialogContent: any) {
905
+ .then(function (oCreatedFragment: any) {
906
+ return Fragment.load({ definition: oCreatedFragment }).then(function (oDialogContent: any) {
907
+ const DraftStatus = FELibrary.DraftStatus;
724
908
  const oDialog = new Dialog({
909
+ resizable: true,
725
910
  title: oDefaultValues.massEditTitle,
726
911
  content: [oDialogContent],
912
+ afterOpen: MassEditHelper.onDialogOpen,
727
913
  beginButton: new Button({
728
- text: oDefaultValues.applyButtonText,
914
+ text: MassEditHelper.helpers.getExpBindingForApplyButtonTxt(oDefaultValues, oDataFieldModel.getObject("/")),
729
915
  type: "Emphasized",
730
916
  press: function (oEvent: any) {
731
- const oDialog = oEvent.getSource().getParent();
732
- const oModel = oDialog.getModel("fieldsInfo");
917
+ (oController.getView()?.getBindingContext("internal") as InternalModelContext)?.setProperty(
918
+ "skipPatchHandlers",
919
+ true
920
+ );
921
+ const oInDialog = oEvent.getSource().getParent();
922
+ const oModel = oInDialog.getModel("fieldsInfo");
733
923
  const aResults = oModel.getProperty("/results");
734
924
  const aPropertyReadableInfo = oModel.getProperty("/readablePropertyData");
735
925
  const changePromise: any[] = [];
736
926
  let bReadOnlyField = false;
737
927
  let groupId;
738
- let index = 0;
739
- aContexts.forEach(function (oSelectedContext: any) {
928
+ //let index = 0;
929
+ const errorValues: any[] = [];
930
+ aContexts.forEach(function (oSelectedContext: any, idx: number) {
740
931
  aResults.forEach(function (oResult: any) {
741
932
  //TODO - Add save implementation for Value Help.
742
933
  if (aPropertyReadableInfo) {
@@ -757,46 +948,126 @@ const MassEditHelper = {
757
948
  }
758
949
  });
759
950
  }
760
- groupId = "$auto." + index;
761
- index += 1;
951
+ groupId = `$auto.${idx}`;
952
+ //index += 1;
953
+ oController._editFlow.setDraftStatus(DraftStatus.Saving);
954
+ //let promiseCount = 0;
762
955
  if (oResult.keyValue && oResult.value !== "Default" && !bReadOnlyField) {
763
- changePromise.push(oSelectedContext.setProperty(oResult.keyValue, oResult.value, groupId));
956
+ changePromise.push(
957
+ oSelectedContext
958
+ .setProperty(oResult.keyValue, oResult.value, groupId)
959
+ .then(function () {
960
+ return oSelectedContext;
961
+ })
962
+ .catch(function (oError: any) {
963
+ errorValues.push(oSelectedContext.getObject());
964
+ Log.error("Mass Edit: Something went wrong in updating entries.", oError);
965
+ })
966
+ );
764
967
  }
765
968
  });
766
969
  });
767
- return Promise.all(changePromise)
768
- .then(function (oRes: any[]) {
769
- const oListBinding = oTable.getRowBinding(),
770
- oExtensionAPI = oController && (oController.getExtensionAPI() as any);
771
- return oExtensionAPI.refresh(oListBinding.getPath()).then(function () {
772
- oDialog.close();
773
- oDialog.destroy();
774
- return oRes;
970
+
971
+ // eslint-disable-next-line promise/catch-or-return
972
+ (Promise as any).allSettled(changePromise).then(function () {
973
+ const oListBinding = oTable.getRowBinding();
974
+ const oExtensionAPI = oController && (oController.getExtensionAPI() as any);
975
+ return oExtensionAPI.refresh(oListBinding.getPath()).then(function () {
976
+ const subtitleColumn = CommonUtils.getMessageColumn(oTable);
977
+ const messages = sap.ui.getCore().getMessageManager().getMessageModel().getData();
978
+ const boundTransitionErrorContexts = [] as any;
979
+ messages.forEach(function (message: any) {
980
+ const messageTargets = message.getTargets();
981
+ if (
982
+ messageTargets &&
983
+ messageTargets.length === 1 &&
984
+ messageTargets[0].length &&
985
+ message.persistent === true
986
+ ) {
987
+ const boundTransitionErrorContext = aContexts.find(function (oContext: any) {
988
+ return message.getTarget().indexOf(oContext.getPath()) !== -1;
989
+ });
990
+ boundTransitionErrorContexts.push(boundTransitionErrorContext);
991
+ message.additionalText = boundTransitionErrorContext
992
+ ? boundTransitionErrorContext.getObject()[subtitleColumn]
993
+ : undefined;
994
+ }
775
995
  });
776
- })
777
- .catch(function (oError: any) {
778
- //TODO - Add error handling part for the Dialog
779
- oDialog.close();
780
- oDialog.destroy();
781
- Log.error("Mass Edit: Something went wrong in updating entries.", oError);
996
+ if (
997
+ aResults.length > 0 &&
998
+ boundTransitionErrorContexts.length === 0 &&
999
+ errorValues.length === 0
1000
+ ) {
1001
+ oController._editFlow.setDraftStatus(DraftStatus.Saved);
1002
+ const successToast = oResourceBundle.getText("C_MASS_EDIT_SUCCESS_TOAST");
1003
+ MessageToast.show(successToast);
1004
+ } else if (
1005
+ errorValues.length + boundTransitionErrorContexts.length <
1006
+ (oTable as any).getSelectedContexts().length
1007
+ ) {
1008
+ oController._editFlow.setDraftStatus(DraftStatus.Saved);
1009
+ } else if (
1010
+ errorValues.length + boundTransitionErrorContexts.length ===
1011
+ (oTable as any).getSelectedContexts().length
1012
+ ) {
1013
+ oController._editFlow.setDraftStatus(DraftStatus.Clear);
1014
+ }
1015
+ oController._editFlow.getMessageHandler().showMessages();
1016
+ if (oInDialog.isOpen()) {
1017
+ oInDialog.close();
1018
+ oInDialog.destroy();
1019
+ (oController.getView()?.getBindingContext("internal") as InternalModelContext)?.setProperty(
1020
+ "skipPatchHandlers",
1021
+ false
1022
+ );
1023
+ }
782
1024
  });
1025
+ });
783
1026
  }
784
1027
  }),
785
1028
  endButton: new Button({
786
1029
  text: oDefaultValues.cancelButtonText,
1030
+ visible: MassEditHelper.helpers.hasEditableFieldsBinding(oDataFieldModel.getObject("/"), true) as any,
787
1031
  press: function (oEvent: any) {
788
- const oDialog = oEvent.getSource().getParent();
789
- oDialog.close();
790
- oDialog.destroy();
1032
+ const oInDialog = oEvent.getSource().getParent();
1033
+ oInDialog.close();
1034
+ oInDialog.destroy();
791
1035
  }
792
1036
  })
793
1037
  });
1038
+ const model = oTable.getModel();
794
1039
  oDialog.setModel(oDialogDataModel, "fieldsInfo");
1040
+ oDialog.setModel(model);
1041
+ oDialog.setBindingContext(dialogContext);
795
1042
  resolve(oDialog);
796
1043
  });
797
1044
  })
798
1045
  .catch(reject);
799
1046
  });
1047
+ },
1048
+
1049
+ helpers: {
1050
+ getBindingExpForHasEditableFields: (fields: any, editable: boolean) => {
1051
+ const totalExp = fields.reduce(
1052
+ (expression: any, field: any) =>
1053
+ or(
1054
+ expression,
1055
+ pathInModel("/values/" + field.dataProperty + "/visible", "fieldsInfo") as BindingToolkitExpression<boolean>
1056
+ ),
1057
+ constant(false)
1058
+ );
1059
+ return editable ? totalExp : not(totalExp);
1060
+ },
1061
+
1062
+ getExpBindingForApplyButtonTxt: (defaultValues: any, fields: boolean) => {
1063
+ const editableExp = MassEditHelper.helpers.getBindingExpForHasEditableFields(fields, true);
1064
+ const totalExp = ifElse(editableExp, constant(defaultValues.applyButtonText), constant(defaultValues.okButtonText));
1065
+ return compileExpression(totalExp);
1066
+ },
1067
+
1068
+ hasEditableFieldsBinding: (fields: any, editable: boolean) => {
1069
+ return compileExpression(MassEditHelper.helpers.getBindingExpForHasEditableFields(fields, editable));
1070
+ }
800
1071
  }
801
1072
  };
802
1073