@sapui5/sap.fe.core 1.99.0 → 1.101.1

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 (289) hide show
  1. package/package.json +6 -4
  2. package/src/sap/fe/core/.library +2 -3
  3. package/src/sap/fe/core/AnnotationHelper.js +43 -92
  4. package/src/sap/fe/core/AnnotationHelper.ts +43 -107
  5. package/src/sap/fe/core/AppComponent.js +381 -399
  6. package/src/sap/fe/core/AppComponent.ts +397 -0
  7. package/src/sap/fe/core/AppStateHandler.js +131 -162
  8. package/src/sap/fe/core/AppStateHandler.ts +2 -2
  9. package/src/sap/fe/core/BaseController.js +82 -58
  10. package/src/sap/fe/core/BaseController.ts +67 -0
  11. package/src/sap/fe/core/CommonUtils.js +179 -31
  12. package/src/sap/fe/core/CommonUtils.ts +295 -125
  13. package/src/sap/fe/core/ExtensionAPI.js +279 -274
  14. package/src/sap/fe/core/ExtensionAPI.ts +242 -0
  15. package/src/sap/fe/core/PageController.js +158 -29
  16. package/src/sap/fe/core/PageController.ts +65 -37
  17. package/src/sap/fe/core/RouterProxy.js +700 -750
  18. package/src/sap/fe/core/RouterProxy.ts +47 -31
  19. package/src/sap/fe/core/Synchronization.js +21 -31
  20. package/src/sap/fe/core/TemplateComponent.js +193 -118
  21. package/src/sap/fe/core/TemplateComponent.ts +104 -109
  22. package/src/sap/fe/core/TemplateModel.js +24 -44
  23. package/src/sap/fe/core/TemplateModel.ts +3 -3
  24. package/src/sap/fe/core/TransactionHelper.js +1368 -1369
  25. package/src/sap/fe/core/TransactionHelper.ts +201 -171
  26. package/src/sap/fe/core/actions/collaboration/ActivitySync.js +406 -0
  27. package/src/sap/fe/core/actions/collaboration/ActivitySync.ts +362 -0
  28. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.js +146 -0
  29. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.ts +129 -0
  30. package/src/sap/fe/core/actions/collaboration/Manage.js +264 -0
  31. package/src/sap/fe/core/actions/collaboration/Manage.ts +246 -0
  32. package/src/sap/fe/core/actions/collaboration/ManageDialog.fragment.xml +100 -0
  33. package/src/sap/fe/core/actions/collaboration/UserDetails.fragment.xml +13 -0
  34. package/src/sap/fe/core/actions/draft.js +324 -220
  35. package/src/sap/fe/core/actions/draft.ts +209 -133
  36. package/src/sap/fe/core/actions/messageHandling.js +79 -48
  37. package/src/sap/fe/core/actions/messageHandling.ts +113 -83
  38. package/src/sap/fe/core/actions/operations.js +37 -18
  39. package/src/sap/fe/core/actions/operations.ts +51 -20
  40. package/src/sap/fe/core/actions/sticky.js +17 -4
  41. package/src/sap/fe/core/actions/sticky.ts +21 -4
  42. package/src/sap/fe/core/buildingBlocks/AttributeModel.js +60 -0
  43. package/src/sap/fe/core/buildingBlocks/AttributeModel.ts +37 -0
  44. package/src/sap/fe/core/buildingBlocks/BuildingBlock.js +165 -0
  45. package/src/sap/fe/core/buildingBlocks/BuildingBlock.ts +178 -0
  46. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.js +707 -0
  47. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.ts +628 -0
  48. package/src/sap/fe/core/buildingBlocks/TraceInfo.js +436 -0
  49. package/src/sap/fe/core/buildingBlocks/TraceInfo.ts +431 -0
  50. package/src/sap/fe/core/controllerextensions/EditFlow.js +1854 -1669
  51. package/src/sap/fe/core/controllerextensions/EditFlow.ts +1792 -0
  52. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +79 -54
  53. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +60 -0
  54. package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +716 -779
  55. package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +785 -0
  56. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +796 -816
  57. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +810 -0
  58. package/src/sap/fe/core/controllerextensions/InternalRouting.js +1056 -1005
  59. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +1001 -0
  60. package/src/sap/fe/core/controllerextensions/KPIManagement.js +498 -532
  61. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +13 -12
  62. package/src/sap/fe/core/controllerextensions/MassEdit.js +141 -169
  63. package/src/sap/fe/core/controllerextensions/MassEdit.ts +155 -0
  64. package/src/sap/fe/core/controllerextensions/MessageHandler.js +221 -244
  65. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +215 -0
  66. package/src/sap/fe/core/controllerextensions/PageReady.js +312 -345
  67. package/src/sap/fe/core/controllerextensions/PageReady.ts +57 -53
  68. package/src/sap/fe/core/controllerextensions/Paginator.js +188 -175
  69. package/src/sap/fe/core/controllerextensions/Paginator.ts +169 -0
  70. package/src/sap/fe/core/controllerextensions/Placeholder.js +157 -149
  71. package/src/sap/fe/core/controllerextensions/Placeholder.ts +149 -0
  72. package/src/sap/fe/core/controllerextensions/Routing.js +144 -125
  73. package/src/sap/fe/core/controllerextensions/Routing.ts +131 -0
  74. package/src/sap/fe/core/controllerextensions/RoutingListener.js +7 -6
  75. package/src/sap/fe/core/controllerextensions/RoutingListener.ts +3 -0
  76. package/src/sap/fe/core/controllerextensions/Share.js +230 -268
  77. package/src/sap/fe/core/controllerextensions/Share.ts +231 -0
  78. package/src/sap/fe/core/controllerextensions/SideEffects.js +603 -644
  79. package/src/sap/fe/core/controllerextensions/SideEffects.ts +68 -68
  80. package/src/sap/fe/core/controllerextensions/ViewState.js +774 -806
  81. package/src/sap/fe/core/controllerextensions/ViewState.ts +796 -0
  82. package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +2 -2
  83. package/src/sap/fe/core/controls/ActionPartial.fragment.xml +2 -2
  84. package/src/sap/fe/core/controls/Any.js +28 -0
  85. package/src/sap/fe/core/controls/Any.ts +30 -0
  86. package/src/sap/fe/core/controls/CommandExecution.js +92 -68
  87. package/src/sap/fe/core/controls/CommandExecution.ts +72 -0
  88. package/src/sap/fe/core/controls/ConditionalWrapper.js +165 -79
  89. package/src/sap/fe/core/controls/ConditionalWrapper.ts +74 -0
  90. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.js +366 -0
  91. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.ts +278 -0
  92. package/src/sap/fe/core/controls/CustomQuickViewPage.js +167 -125
  93. package/src/sap/fe/core/controls/CustomQuickViewPage.ts +116 -0
  94. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossDraft.fragment.xml +44 -5
  95. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +163 -122
  96. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +155 -0
  97. package/src/sap/fe/core/controls/FieldWrapper.js +212 -141
  98. package/src/sap/fe/core/controls/FieldWrapper.ts +104 -0
  99. package/src/sap/fe/core/controls/FileWrapper.js +313 -0
  100. package/src/sap/fe/core/controls/FileWrapper.ts +169 -0
  101. package/src/sap/fe/core/controls/FilterBar.js +197 -159
  102. package/src/sap/fe/core/controls/FilterBar.ts +148 -0
  103. package/src/sap/fe/core/controls/FormElementWrapper.js +100 -39
  104. package/src/sap/fe/core/controls/FormElementWrapper.ts +37 -0
  105. package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +37 -42
  106. package/src/sap/fe/core/controls/MultiValueParameterDelegate.ts +31 -0
  107. package/src/sap/fe/core/controls/filterbar/FilterContainer.js +147 -115
  108. package/src/sap/fe/core/controls/filterbar/FilterContainer.ts +102 -0
  109. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +300 -265
  110. package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +252 -0
  111. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +185 -140
  112. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +125 -0
  113. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +335 -322
  114. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +337 -0
  115. package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +37 -42
  116. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +75 -74
  117. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +71 -0
  118. package/src/sap/fe/core/converters/ConverterContext.js +348 -379
  119. package/src/sap/fe/core/converters/ConverterContext.ts +19 -16
  120. package/src/sap/fe/core/converters/ManifestSettings.js +13 -1
  121. package/src/sap/fe/core/converters/ManifestSettings.ts +17 -2
  122. package/src/sap/fe/core/converters/ManifestWrapper.js +354 -378
  123. package/src/sap/fe/core/converters/ManifestWrapper.ts +10 -0
  124. package/src/sap/fe/core/converters/MetaModelConverter.js +6 -4
  125. package/src/sap/fe/core/converters/MetaModelConverter.ts +5 -2
  126. package/src/sap/fe/core/converters/TemplateConverter.js +1 -1
  127. package/src/sap/fe/core/converters/TemplateConverter.ts +2 -1
  128. package/src/sap/fe/core/converters/annotations/DataField.js +26 -13
  129. package/src/sap/fe/core/converters/annotations/DataField.ts +40 -17
  130. package/src/sap/fe/core/converters/controls/Common/Action.js +10 -10
  131. package/src/sap/fe/core/converters/controls/Common/Action.ts +20 -19
  132. package/src/sap/fe/core/converters/controls/Common/Chart.js +8 -8
  133. package/src/sap/fe/core/converters/controls/Common/Chart.ts +12 -11
  134. package/src/sap/fe/core/converters/controls/Common/Form.js +6 -6
  135. package/src/sap/fe/core/converters/controls/Common/Form.ts +7 -3
  136. package/src/sap/fe/core/converters/controls/Common/KPI.js +1 -1
  137. package/src/sap/fe/core/converters/controls/Common/KPI.ts +2 -2
  138. package/src/sap/fe/core/converters/controls/Common/Table.js +326 -86
  139. package/src/sap/fe/core/converters/controls/Common/Table.ts +384 -167
  140. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +120 -55
  141. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +158 -98
  142. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +206 -223
  143. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +263 -287
  144. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +6 -6
  145. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +20 -18
  146. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +5 -2
  147. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +4 -1
  148. package/src/sap/fe/core/converters/helpers/Aggregation.js +115 -133
  149. package/src/sap/fe/core/converters/helpers/BindingHelper.js +20 -6
  150. package/src/sap/fe/core/converters/helpers/BindingHelper.ts +16 -4
  151. package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +12 -1
  152. package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +11 -0
  153. package/src/sap/fe/core/converters/helpers/Key.js +42 -57
  154. package/src/sap/fe/core/converters/helpers/Key.ts +1 -1
  155. package/src/sap/fe/core/converters/objectPage/FormMenuActions.js +1 -1
  156. package/src/sap/fe/core/converters/objectPage/FormMenuActions.ts +0 -4
  157. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +51 -27
  158. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +69 -43
  159. package/src/sap/fe/core/converters/templates/ListReportConverter.js +42 -25
  160. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +91 -65
  161. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +11 -9
  162. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +8 -8
  163. package/src/sap/fe/core/designtime/AppComponent.designtime.js +92 -98
  164. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +91 -0
  165. package/src/sap/fe/core/formatters/CollaborationFormatter.js +104 -0
  166. package/src/sap/fe/core/formatters/CollaborationFormatter.ts +60 -0
  167. package/src/sap/fe/core/formatters/KPIFormatter.js +3 -12
  168. package/src/sap/fe/core/formatters/KPIFormatter.ts +3 -2
  169. package/src/sap/fe/core/formatters/TableFormatter.js +53 -2
  170. package/src/sap/fe/core/formatters/TableFormatter.ts +51 -0
  171. package/src/sap/fe/core/formatters/ValueFormatter.js +4 -4
  172. package/src/sap/fe/core/formatters/ValueFormatter.ts +4 -7
  173. package/src/sap/fe/core/fpm/Component.js +80 -55
  174. package/src/sap/fe/core/fpm/Component.ts +43 -0
  175. package/src/sap/fe/core/helpers/AppStartupHelper.js +323 -309
  176. package/src/sap/fe/core/helpers/AppStartupHelper.ts +363 -337
  177. package/src/sap/fe/core/helpers/BindingExpression.js +7 -7
  178. package/src/sap/fe/core/helpers/BindingExpression.ts +7 -7
  179. package/src/sap/fe/core/helpers/ClassSupport.js +307 -166
  180. package/src/sap/fe/core/helpers/ClassSupport.ts +348 -155
  181. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +5 -4
  182. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +1 -5
  183. package/src/sap/fe/core/helpers/FPMHelper.js +1 -1
  184. package/src/sap/fe/core/helpers/FPMHelper.ts +1 -1
  185. package/src/sap/fe/core/helpers/MassEditHelper.js +735 -684
  186. package/src/sap/fe/core/helpers/MassEditHelper.ts +803 -0
  187. package/src/sap/fe/core/helpers/ModelHelper.js +53 -1
  188. package/src/sap/fe/core/helpers/ModelHelper.ts +46 -0
  189. package/src/sap/fe/core/helpers/PasteHelper.js +4 -4
  190. package/src/sap/fe/core/helpers/PasteHelper.ts +4 -3
  191. package/src/sap/fe/core/helpers/SemanticDateOperators.js +7 -3
  192. package/src/sap/fe/core/helpers/SemanticDateOperators.ts +7 -1
  193. package/src/sap/fe/core/helpers/SemanticKeyHelper.js +1 -1
  194. package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +1 -1
  195. package/src/sap/fe/core/helpers/StableIdHelper.js +1 -7
  196. package/src/sap/fe/core/helpers/StableIdHelper.ts +0 -4
  197. package/src/sap/fe/core/jsx-runtime/jsx.js +35 -5
  198. package/src/sap/fe/core/jsx-runtime/jsx.ts +22 -8
  199. package/src/sap/fe/core/library.js +425 -451
  200. package/src/sap/fe/core/library.support.js +22 -33
  201. package/src/sap/fe/core/library.support.ts +23 -0
  202. package/src/sap/fe/core/library.ts +420 -0
  203. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +5 -3
  204. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +4 -4
  205. package/src/sap/fe/core/messagebundle.properties +45 -13
  206. package/src/sap/fe/core/messagebundle_ar.properties +29 -7
  207. package/src/sap/fe/core/messagebundle_bg.properties +29 -7
  208. package/src/sap/fe/core/messagebundle_ca.properties +29 -7
  209. package/src/sap/fe/core/messagebundle_cs.properties +29 -7
  210. package/src/sap/fe/core/messagebundle_cy.properties +29 -7
  211. package/src/sap/fe/core/messagebundle_da.properties +29 -7
  212. package/src/sap/fe/core/messagebundle_de.properties +29 -7
  213. package/src/sap/fe/core/messagebundle_el.properties +29 -7
  214. package/src/sap/fe/core/messagebundle_en.properties +29 -7
  215. package/src/sap/fe/core/messagebundle_en_GB.properties +29 -7
  216. package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +29 -7
  217. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +29 -7
  218. package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +29 -7
  219. package/src/sap/fe/core/messagebundle_es.properties +29 -7
  220. package/src/sap/fe/core/messagebundle_es_MX.properties +29 -7
  221. package/src/sap/fe/core/messagebundle_et.properties +29 -7
  222. package/src/sap/fe/core/messagebundle_fi.properties +30 -8
  223. package/src/sap/fe/core/messagebundle_fr.properties +31 -9
  224. package/src/sap/fe/core/messagebundle_fr_CA.properties +31 -9
  225. package/src/sap/fe/core/messagebundle_hi.properties +29 -7
  226. package/src/sap/fe/core/messagebundle_hr.properties +29 -7
  227. package/src/sap/fe/core/messagebundle_hu.properties +29 -7
  228. package/src/sap/fe/core/messagebundle_id.properties +29 -7
  229. package/src/sap/fe/core/messagebundle_it.properties +29 -7
  230. package/src/sap/fe/core/messagebundle_iw.properties +29 -7
  231. package/src/sap/fe/core/messagebundle_ja.properties +28 -6
  232. package/src/sap/fe/core/messagebundle_kk.properties +29 -7
  233. package/src/sap/fe/core/messagebundle_ko.properties +29 -7
  234. package/src/sap/fe/core/messagebundle_lt.properties +29 -7
  235. package/src/sap/fe/core/messagebundle_lv.properties +30 -8
  236. package/src/sap/fe/core/messagebundle_ms.properties +29 -7
  237. package/src/sap/fe/core/messagebundle_nl.properties +29 -7
  238. package/src/sap/fe/core/messagebundle_no.properties +29 -7
  239. package/src/sap/fe/core/messagebundle_pl.properties +29 -7
  240. package/src/sap/fe/core/messagebundle_pt.properties +30 -8
  241. package/src/sap/fe/core/messagebundle_pt_PT.properties +29 -7
  242. package/src/sap/fe/core/messagebundle_ro.properties +29 -7
  243. package/src/sap/fe/core/messagebundle_ru.properties +29 -7
  244. package/src/sap/fe/core/messagebundle_sh.properties +29 -7
  245. package/src/sap/fe/core/messagebundle_sk.properties +29 -7
  246. package/src/sap/fe/core/messagebundle_sl.properties +29 -7
  247. package/src/sap/fe/core/messagebundle_sv.properties +30 -8
  248. package/src/sap/fe/core/messagebundle_th.properties +28 -6
  249. package/src/sap/fe/core/messagebundle_tr.properties +32 -10
  250. package/src/sap/fe/core/messagebundle_uk.properties +29 -7
  251. package/src/sap/fe/core/messagebundle_vi.properties +29 -7
  252. package/src/sap/fe/core/messagebundle_zh_CN.properties +29 -7
  253. package/src/sap/fe/core/messagebundle_zh_TW.properties +29 -7
  254. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +47 -73
  255. package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +1 -1
  256. package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +158 -196
  257. package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +5 -6
  258. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +70 -96
  259. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +7 -6
  260. package/src/sap/fe/core/services/NavigationServiceFactory.js +287 -342
  261. package/src/sap/fe/core/services/NavigationServiceFactory.ts +11 -14
  262. package/src/sap/fe/core/services/ResourceModelServiceFactory.js +70 -105
  263. package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +6 -3
  264. package/src/sap/fe/core/services/RoutingServiceFactory.js +796 -820
  265. package/src/sap/fe/core/services/RoutingServiceFactory.ts +62 -53
  266. package/src/sap/fe/core/services/ShellServicesFactory.js +694 -741
  267. package/src/sap/fe/core/services/ShellServicesFactory.ts +33 -33
  268. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +570 -595
  269. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +23 -4
  270. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +357 -389
  271. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +25 -29
  272. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +43 -5
  273. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +7 -4
  274. package/src/sap/fe/core/support/CommonHelper.js +1 -1
  275. package/src/sap/fe/core/support/CommonHelper.ts +1 -4
  276. package/src/sap/fe/core/support/Diagnostics.js +36 -48
  277. package/src/sap/fe/core/templating/DataModelPathHelper.js +91 -90
  278. package/src/sap/fe/core/templating/DataModelPathHelper.ts +126 -123
  279. package/src/sap/fe/core/templating/DisplayModeFormatter.js +23 -3
  280. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +26 -5
  281. package/src/sap/fe/core/templating/FilterHelper.js +25 -32
  282. package/src/sap/fe/core/templating/FilterHelper.ts +36 -35
  283. package/src/sap/fe/core/templating/PropertyHelper.js +16 -2
  284. package/src/sap/fe/core/templating/PropertyHelper.ts +31 -24
  285. package/src/sap/fe/core/templating/UIFormatters.js +150 -44
  286. package/src/sap/fe/core/templating/UIFormatters.ts +165 -67
  287. package/src/sap/fe/core/type/Email.js +26 -8
  288. package/src/sap/fe/core/type/Email.ts +8 -7
  289. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +0 -75
@@ -0,0 +1,803 @@
1
+ import Log from "sap/base/Log";
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";
8
+ import { getTextBinding, setEditStyleProperties } from "sap/fe/macros/field/FieldTemplating";
9
+ import Button from "sap/m/Button";
10
+ import Dialog from "sap/m/Dialog";
11
+ import Core from "sap/ui/core/Core";
12
+ import Fragment from "sap/ui/core/Fragment";
13
+ import XMLPreprocessor from "sap/ui/core/util/XMLPreprocessor";
14
+ import XMLTemplateProcessor from "sap/ui/core/XMLTemplateProcessor";
15
+ import EditMode from "sap/ui/mdc/enum/EditMode";
16
+ import Table from "sap/ui/mdc/Table";
17
+ 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";
21
+ import { convertMetaModelContext, getInvolvedDataModelObjects } from "../converters/MetaModelConverter";
22
+ import { isReadOnlyExpression } from "../templating/FieldControlHelper";
23
+ import { getEditMode, getRequiredExpression, isCollectionField } from "../templating/UIFormatters";
24
+
25
+ /* This class contains helpers to be used for mass edit functionality */
26
+ type TextArrangementInfo = {
27
+ textArrangement: string;
28
+ valuePath: string;
29
+ descriptionPath?: string;
30
+ value: string;
31
+ description: string;
32
+ fullText: string;
33
+ };
34
+
35
+ const MassEditHelper = {
36
+ /**
37
+ * Initializes the value at final or deepest level path with a blank array.
38
+ * Return an empty array pointing to the final or deepest level path.
39
+ *
40
+ * @param {string} sPath Property path
41
+ * @param {Array} aValues Array instance where the default data needs to be added
42
+ * @returns {Array}
43
+ */
44
+ initLastLevelOfPropertyPath: function (sPath: string, aValues: any) {
45
+ let aFinalPath: any;
46
+ let index = 0;
47
+ const aPaths = sPath.split("/");
48
+ let sFullPath = "";
49
+ aPaths.forEach(function (sPropertyPath: string) {
50
+ if (!aValues[sPropertyPath] && index === 0) {
51
+ aValues[sPropertyPath] = {};
52
+ aFinalPath = aValues[sPropertyPath];
53
+ sFullPath = sFullPath + sPropertyPath;
54
+ index++;
55
+ } else if (!aFinalPath[sPropertyPath]) {
56
+ sFullPath = sFullPath + "/" + sPropertyPath;
57
+ if (sFullPath !== sPath) {
58
+ aFinalPath[sPropertyPath] = {};
59
+ aFinalPath = aFinalPath[sPropertyPath];
60
+ } else {
61
+ aFinalPath[sPropertyPath] = [];
62
+ }
63
+ }
64
+ });
65
+ return aFinalPath;
66
+ },
67
+
68
+ /**
69
+ * Method to get unique values for given array values.
70
+ *
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}
75
+ */
76
+ getUniqueValues: function (sValue: string, index: number, self: any[]) {
77
+ if (sValue) {
78
+ return self.indexOf(sValue) === index;
79
+ }
80
+ },
81
+
82
+ /**
83
+ * Gets the property value for a multi-level path (for example: _Materials/Material_Details gets the value of Material_Details under _Materials Object).
84
+ * Returns the propertyValue, which can be of any type (string, number, etc..).
85
+ *
86
+ * @param {string} sDataPropertyPath Property path
87
+ * @param {object} oValues Object of property values
88
+ * @returns {*}
89
+ */
90
+ getValueForMultiLevelPath: function (sDataPropertyPath: string, oValues: any) {
91
+ if (sDataPropertyPath && sDataPropertyPath.indexOf("/") > 0) {
92
+ const aPropertyPaths = sDataPropertyPath.split("/");
93
+ let Result: any;
94
+ aPropertyPaths.forEach(function (sPath: string) {
95
+ Result = oValues && oValues[sPath] ? oValues[sPath] : Result && Result[sPath];
96
+ });
97
+ return Result;
98
+ }
99
+ },
100
+
101
+ /**
102
+ * Gets the key path for the key of a combo box that must be selected initially when the dialog opens:
103
+ * => If propertyValue for all selected contexts is different, then < Keep Existing Values > is preselected.
104
+ * => If propertyValue for all selected contexts is the same, then the propertyValue is preselected.
105
+ * => If propertyValue for all selected contexts is empty, then < Leave Blank > is preselected.
106
+ *
107
+ *
108
+ * @param {Array} aContexts Contexts for mass edit
109
+ * @param {string} sDataPropertyPath Data property path
110
+ * @returns {string}
111
+ */
112
+ getDefaultSelectionPathComboBox: function (aContexts: any[], sDataPropertyPath: string) {
113
+ if (sDataPropertyPath && aContexts.length > 0) {
114
+ const oSelectedContext = aContexts,
115
+ aPropertyValues: any[] = [];
116
+ oSelectedContext.forEach(function (oContext: any) {
117
+ const oDataObject = oContext.getObject();
118
+ const sMultiLevelPathCondition =
119
+ sDataPropertyPath.indexOf("/") > -1 && oDataObject.hasOwnProperty(sDataPropertyPath.split("/")[0]);
120
+ if (oContext && (oDataObject.hasOwnProperty(sDataPropertyPath) || sMultiLevelPathCondition)) {
121
+ aPropertyValues.push(oContext.getObject(sDataPropertyPath));
122
+ }
123
+ });
124
+ const aUniquePropertyValues = aPropertyValues.filter(MassEditHelper.getUniqueValues);
125
+ if (aUniquePropertyValues.length > 1) {
126
+ return "Default/" + sDataPropertyPath;
127
+ } else if (aUniquePropertyValues.length === 0) {
128
+ return "Empty/" + sDataPropertyPath;
129
+ } else if (aUniquePropertyValues.length === 1) {
130
+ return sDataPropertyPath;
131
+ }
132
+ }
133
+ },
134
+
135
+ /**
136
+ * Checks hidden annotation value [both static and path based] for table's selected context.
137
+ *
138
+ * @param {*} hiddenValue Hidden annotation value / path for field
139
+ * @param {Array} aContexts Contexts for mass edit
140
+ * @returns {boolean}
141
+ */
142
+ getHiddenValueForContexts: function (hiddenValue: any, aContexts: any[]) {
143
+ if (hiddenValue && hiddenValue.$Path) {
144
+ return !aContexts.some(function (oSelectedContext: any) {
145
+ return oSelectedContext.getObject(hiddenValue.$Path) === false;
146
+ });
147
+ }
148
+ return hiddenValue;
149
+ },
150
+
151
+ getInputType: function (propertyInfo: any, dataFieldConverted: any, oDataModelPath: DataModelObjectPath): string {
152
+ const editStyleProperties = {} as FieldProperties;
153
+ let inputType!: string;
154
+ if (propertyInfo) {
155
+ setEditStyleProperties(editStyleProperties, dataFieldConverted, oDataModelPath, true);
156
+ inputType = editStyleProperties?.editStyle || "";
157
+ }
158
+ const isValidForMassEdit =
159
+ inputType &&
160
+ ["DatePicker", "TimePicker", "DateTimePicker", "RatingIndicator"].indexOf(inputType) === -1 &&
161
+ !isCollectionField(oDataModelPath) &&
162
+ !hasValueHelpWithFixedValues(propertyInfo);
163
+
164
+ return (isValidForMassEdit || "") && inputType;
165
+ },
166
+
167
+ getIsFieldGrp: function (dataFieldConverted: any): boolean {
168
+ return (
169
+ dataFieldConverted &&
170
+ dataFieldConverted.$Type === "com.sap.vocabularies.UI.v1.DataFieldForAnnotation" &&
171
+ dataFieldConverted.Target &&
172
+ dataFieldConverted.Target.value &&
173
+ dataFieldConverted.Target.value.indexOf("FieldGroup") > -1
174
+ );
175
+ },
176
+
177
+ /**
178
+ * Initializes a JSON Model for properties of dialog fields [label, visiblity, dataproperty, etc.].
179
+ *
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}
184
+ */
185
+ prepareDataForDialog: function (oTable: Table, aContexts: any[], aDataArray: any[]) {
186
+ const oMetaModel = oTable && (oTable.getModel().getMetaModel() as any),
187
+ sCurrentEntitySetName = oTable.data("metaPath"),
188
+ aTableFields = MassEditHelper.getTableFields(oTable),
189
+ oEntityTypeContext = oMetaModel.getContext(sCurrentEntitySetName + "/@"),
190
+ oEntitySetContext = oMetaModel.getContext(sCurrentEntitySetName),
191
+ oDataModelObjectPath = getInvolvedDataModelObjects(oEntityTypeContext);
192
+
193
+ const oDataFieldModel = new JSONModel();
194
+ let oResult;
195
+ let sLabelText;
196
+ let bValueHelpEnabled;
197
+ let sUnitPropertyPath;
198
+ let bValueHelpEnabledForUnit;
199
+ let oTextBinding;
200
+
201
+ aTableFields.forEach(function (oColumnInfo: any) {
202
+ const sDataPropertyPath = oColumnInfo.dataProperty;
203
+ 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
+ ];
223
+ if (oDataModelObjectPath) {
224
+ oDataModelObjectPath.targetObject = oDataModelObjectPath.targetEntityType.entityProperties.filter(function (
225
+ oProperty: any
226
+ ) {
227
+ return oProperty.name === sDataPropertyPath;
228
+ });
229
+ }
230
+ oDataModelObjectPath.targetObject = oDataModelObjectPath.targetObject[0] || {};
231
+ oTextBinding = getTextBinding(oDataModelObjectPath, {}, true) || {};
232
+ const oFieldContext = oMetaModel.getContext(oColumnInfo.annotationPath),
233
+ oDataFieldConverted = convertMetaModelContext(oFieldContext),
234
+ oPropertyContext = oMetaModel.getContext(sCurrentEntitySetName + "/" + sDataPropertyPath + "@"),
235
+ oInterface = oPropertyContext && oPropertyContext.getInterface();
236
+
237
+ let oDataModelPath = getInvolvedDataModelObjects(oFieldContext, oEntitySetContext);
238
+ if (oDataFieldConverted?.Value?.path?.length > 0) {
239
+ oDataModelPath = enhanceDataModelPath(oDataModelPath, sDataPropertyPath);
240
+ }
241
+ const bHiddenField =
242
+ MassEditHelper.getHiddenValueForContexts(
243
+ oFieldContext && oFieldContext.getObject()["@com.sap.vocabularies.UI.v1.Hidden"],
244
+ aContexts
245
+ ) || false;
246
+ const isImage = oPropertyInfo && oPropertyInfo["@com.sap.vocabularies.UI.v1.IsImageURL"];
247
+
248
+ oInterface.context = {
249
+ getModel: function () {
250
+ return oInterface.getModel();
251
+ },
252
+ getPath: function () {
253
+ return sCurrentEntitySetName + "/" + sDataPropertyPath;
254
+ }
255
+ };
256
+ oPropertyInfo =
257
+ (oDataFieldConverted && oDataFieldConverted.Value && oDataFieldConverted.Value.$target) ||
258
+ (oDataFieldConverted && oDataFieldConverted.Target && oDataFieldConverted.Target.$target);
259
+ // Datafield is not included in the FieldControl calculation, needs to be implemented
260
+
261
+ const chartProperty = oPropertyInfo && oPropertyInfo.term && oPropertyInfo.term === "com.sap.vocabularies.UI.v1.Chart";
262
+ const isAction = !!oDataFieldConverted.Action;
263
+ const isFieldGrp = MassEditHelper.getIsFieldGrp(oDataFieldConverted);
264
+
265
+ if (isImage || bHiddenField || chartProperty || isAction || isFieldGrp) {
266
+ return;
267
+ }
268
+
269
+ // EditMode and InputType
270
+ const propertyForFieldControl = oPropertyInfo && oPropertyInfo.Value ? oPropertyInfo.Value : oPropertyInfo;
271
+ const expBinding = getEditMode(propertyForFieldControl, oDataModelPath, false, false, oDataFieldConverted, true);
272
+ const editModeValues = Object.keys(EditMode);
273
+ const editModeIsStatic = !!expBinding && editModeValues.includes(expBinding as EditMode);
274
+ const editable = !!expBinding && ((editModeIsStatic && expBinding === EditMode.Editable) || !editModeIsStatic);
275
+
276
+ if (!editable) {
277
+ return;
278
+ }
279
+
280
+ const inputType = MassEditHelper.getInputType(oPropertyInfo, oDataFieldConverted, oDataModelPath);
281
+
282
+ if (inputType) {
283
+ const isReadOnly = isReadOnlyExpression(oPropertyInfo);
284
+
285
+ oResult = {
286
+ "label": sLabelText + ":",
287
+ "dataProperty": sDataPropertyPath,
288
+ "isValueHelpEnabled": bValueHelpEnabled ? bValueHelpEnabled : false,
289
+ "unitProperty": sUnitPropertyPath ? sUnitPropertyPath : false,
290
+ "isValueHelpEnabledForUnit": bValueHelpEnabledForUnit ? bValueHelpEnabledForUnit : false,
291
+ "propertyPathForValueHelp": sCurrentEntitySetName + "/" + sDataPropertyPath,
292
+ "propertyPathForValueHelpUnit": sCurrentEntitySetName + "/" + sUnitPropertyPath,
293
+ "isFieldRequired": getRequiredExpression(oPropertyInfo, oDataFieldConverted, true),
294
+ "defaultSelectionPath": sDataPropertyPath
295
+ ? MassEditHelper.getDefaultSelectionPathComboBox(aContexts, sDataPropertyPath)
296
+ : false,
297
+ "defaultSelectionUnitPath": sUnitPropertyPath
298
+ ? MassEditHelper.getDefaultSelectionPathComboBox(aContexts, sUnitPropertyPath)
299
+ : false,
300
+ "entitySet": sCurrentEntitySetName,
301
+ "textBinding": oTextBinding,
302
+ "nullable": oPropertyInfo.nullable !== undefined ? oPropertyInfo.nullable : true,
303
+ "isPropertyReadOnly": isReadOnly !== undefined ? isReadOnly : false,
304
+ "inputType": inputType,
305
+ "editMode": editable ? expBinding : undefined
306
+ };
307
+ aDataArray.push(oResult);
308
+ }
309
+ }
310
+ });
311
+ oDataFieldModel.setData(aDataArray);
312
+ return oDataFieldModel;
313
+ },
314
+
315
+ getTableFields: function (oTable: any) {
316
+ const aColumns = (oTable && oTable.getColumns()) || [];
317
+ const columnsData = oTable && oTable.getParent().getTableDefinition().columns;
318
+ return aColumns.map(function (oColumn: any) {
319
+ const sDataProperty = oColumn && oColumn.getDataProperty(),
320
+ aRealtedColumnInfo =
321
+ columnsData &&
322
+ columnsData.filter(function (oColumnInfo: any) {
323
+ return oColumnInfo.name === sDataProperty && oColumnInfo.type === "Annotation";
324
+ });
325
+ return {
326
+ "dataProperty": sDataProperty,
327
+ "label": oColumn.getHeader(),
328
+ "annotationPath": aRealtedColumnInfo && aRealtedColumnInfo[0] && aRealtedColumnInfo[0].annotationPath
329
+ };
330
+ });
331
+ },
332
+
333
+ getDefaultTextsForDialog: function (oResourceBundle: any, iSelectedContexts: any, oTable: any) {
334
+ // The confirm button text is "Save" for table in Display mode and "Apply" for table in edit mode. This can be later exposed if needed.
335
+ const bDisplayMode = oTable.data("displayModePropertyBinding") === "true";
336
+
337
+ return {
338
+ "keepExistingPrefix": "< Keep",
339
+ "leaveBlankValue": "< Leave Blank >",
340
+ "clearFieldValue": "< Clear Values >",
341
+ "massEditTitle": oResourceBundle.getText("C_MASS_EDIT_DIALOG_TITLE", iSelectedContexts.toString()),
342
+ "applyButtonText": bDisplayMode
343
+ ? oResourceBundle.getText("C_MASS_EDIT_SAVE_BUTTON_TEXT")
344
+ : oResourceBundle.getText("C_MASS_EDIT_APPLY_BUTTON_TEXT"),
345
+ "cancelButtonText": oResourceBundle.getText("C_MASS_EDIT_CANCEL_BUTTON_TEXT")
346
+ };
347
+ },
348
+
349
+ /**
350
+ * Adds a suffix to the 'keep existing' property of the comboBox.
351
+ *
352
+ * @param {string} sInputType InputType of the field
353
+ * @returns {string}
354
+ */
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
+ },
369
+
370
+ /**
371
+ * Adds default values to the model [Keep Existing Values, Leave Blank].
372
+ *
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
378
+ */
379
+ setDefaultValuesToDialog: function (aValues: any[], aContexts: any[], oDefaultValues: any, oPropertyInfo: any, bUOMField?: boolean) {
380
+ const sPropertyPath = bUOMField ? oPropertyInfo.unitProperty : oPropertyInfo.dataProperty,
381
+ sInputType = oPropertyInfo.inputType,
382
+ 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
+ }
393
+ } else {
394
+ aValues.unshift({ text: oDefaultValues.leaveBlankValue, key: "Empty/" + sPropertyPath });
395
+ }
396
+ aValues.unshift({
397
+ text: oDefaultValues.keepExistingPrefix + " " + sSuffixForKeepExisting + " >",
398
+ key: "Default/" + sPropertyPath
399
+ });
400
+ },
401
+
402
+ 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
+ }
434
+ }
435
+ return {
436
+ "textArrangement": sDisplayMode,
437
+ "valuePath": sProperty,
438
+ "descriptionPath": sDescriptionPath,
439
+ "value": sValue,
440
+ "description": sDescriptionValue,
441
+ "fullText": sFullText
442
+ };
443
+ }
444
+ return undefined;
445
+ },
446
+
447
+ /**
448
+ * Return the visibility valuue for the ManagedObject Any.
449
+ *
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.
452
+ */
453
+ isEditable: function (any: AnyType): boolean {
454
+ const binding = any.getBinding("any");
455
+ const value = (binding as any).getExternalValue();
456
+ return value === EditMode.Editable;
457
+ },
458
+
459
+ /**
460
+ * Calculate and update the visibility of mass edit field on change of the ManagedObject Any binding.
461
+ *
462
+ * @param {JSONModel} oDialogDataModel Model to be used runtime.
463
+ * @param {string} dataProperty Field name.
464
+ */
465
+ onContextEditableChange: function (oDialogDataModel: JSONModel, dataProperty: string): void {
466
+ const objectsForVisibility = oDialogDataModel.getProperty("/values/" + dataProperty + "/objectsForVisibility") || [];
467
+ const editable = objectsForVisibility.some(MassEditHelper.isEditable);
468
+
469
+ if (editable) {
470
+ oDialogDataModel.setProperty("/values/" + dataProperty + "/visible", editable);
471
+ }
472
+ },
473
+
474
+ /**
475
+ * Update Managed Object Any for visibility of the mass edit fields.
476
+ *
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.
481
+ */
482
+ updateOnContextChange: function (mOToUse: AnyType, oDialogDataModel: JSONModel, dataProperty: string, values: any) {
483
+ const binding = mOToUse.getBinding("any");
484
+
485
+ values.objectsForVisibility = values.objectsForVisibility || [];
486
+ values.objectsForVisibility.push(mOToUse);
487
+
488
+ binding.attachChange(MassEditHelper.onContextEditableChange.bind(null, oDialogDataModel, dataProperty));
489
+ },
490
+
491
+ /**
492
+ * Get bound object to calculate the visibility of contexts.
493
+ *
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.
497
+ */
498
+ getBoundObject: function (expBinding: BindingExpression<string> | ExpressionOrPrimitive<string>, context: Context): AnyType {
499
+ const mOToUse = new Any({ any: expBinding });
500
+ const model = context.getModel();
501
+ mOToUse.setModel(model);
502
+ mOToUse.setBindingContext(context);
503
+
504
+ return mOToUse;
505
+ },
506
+
507
+ /**
508
+ * Get the visibility of the field.
509
+ *
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.
516
+ */
517
+ getFieldVisiblity: function (
518
+ expBinding: BindingExpression<string> | ExpressionOrPrimitive<string>,
519
+ oDialogDataModel: JSONModel,
520
+ dataProperty: string,
521
+ values: any,
522
+ context: Context
523
+ ): boolean {
524
+ const mOToUse = MassEditHelper.getBoundObject(expBinding, context);
525
+ const isContextEditable = MassEditHelper.isEditable(mOToUse);
526
+
527
+ if (!isContextEditable) {
528
+ MassEditHelper.updateOnContextChange(mOToUse, oDialogDataModel, dataProperty, values);
529
+ }
530
+ return isContextEditable;
531
+ },
532
+
533
+ /**
534
+ * Initializes a runtime model:
535
+ * => 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
+ * => The model will capture runtime changes in the results property (the value entered in the comboBox).
537
+ *
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}
542
+ */
543
+ setRuntimeModelOnDialog: function (aContexts: any[], aDataArray: any[], oDefaultValues: any) {
544
+ const aValues: any[] = [];
545
+ const aUnitData: any[] = [];
546
+ const aResults: any[] = [];
547
+ const aReadOnlyFieldInfo: any[] = [];
548
+ const oDistinctValueMap: any = {};
549
+ const oData = { "values": aValues, "unitData": aUnitData, "results": aResults, "readablePropertyData": aReadOnlyFieldInfo };
550
+ const oDialogDataModel = new JSONModel(oData);
551
+ let sPropertyName;
552
+ aDataArray.forEach(function (oData: any) {
553
+ 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;
561
+ if (!oDistinctValueMap[sPropertyKey] && aFinalPath[aPropertyPaths[aPropertyPaths.length - 1]]) {
562
+ oTextInfo = MassEditHelper.getTextArrangementInfo(
563
+ oData.dataProperty,
564
+ oData.textBinding,
565
+ oData.entitySet,
566
+ aContexts[i]
567
+ );
568
+ aFinalPath[aPropertyPaths[aPropertyPaths.length - 1]].push({
569
+ "text": (oTextInfo && oTextInfo.fullText) || sMultiLevelPathValue,
570
+ "key": oData.dataProperty,
571
+ "textInfo": oTextInfo
572
+ });
573
+ oDistinctValueMap[sPropertyKey] = sMultiLevelPathValue;
574
+ }
575
+ }
576
+ } else {
577
+ aValues[oData.dataProperty] = aValues[oData.dataProperty] || [];
578
+ if (oData.unitProperty) {
579
+ aUnitData[oData.unitProperty] = aUnitData[oData.unitProperty] || [];
580
+ }
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]) {
601
+ oTextInfo = MassEditHelper.getTextArrangementInfo(
602
+ oData.unitProperty,
603
+ oData.textBinding,
604
+ oData.entitySet,
605
+ aContexts[i]
606
+ );
607
+ aUnitData[oData.unitProperty].push({
608
+ "text": (oTextInfo && oTextInfo.fullText) || oDataObject[oData.unitProperty],
609
+ "key": oData.unitProperty,
610
+ "textInfo": oTextInfo
611
+ });
612
+ oDistinctValueMap[sPropertyName] = oDataObject[oData.unitProperty];
613
+ }
614
+ }
615
+ }
616
+ }
617
+ });
618
+ aDataArray.forEach(function (oData: any) {
619
+ let values: any;
620
+ if (oData.dataProperty.indexOf("/") > -1) {
621
+ const sMultiLevelPropPathValue = MassEditHelper.getValueForMultiLevelPath(oData.dataProperty, aValues);
622
+ if (!sMultiLevelPropPathValue) {
623
+ sMultiLevelPropPathValue.push({ text: oDefaultValues.leaveBlankValue, key: "Empty/" + oData.dataProperty });
624
+ } else {
625
+ MassEditHelper.setDefaultValuesToDialog(sMultiLevelPropPathValue, aContexts, oDefaultValues, oData);
626
+ }
627
+ 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];
631
+ }
632
+ if (aUnitData[oData.unitProperty] && aUnitData[oData.unitProperty].length) {
633
+ MassEditHelper.setDefaultValuesToDialog(aUnitData[oData.unitProperty], aContexts, oDefaultValues, oData, true);
634
+ } else if (
635
+ (oData.dataProperty && aValues[oData.dataProperty] && !aValues[oData.dataProperty].length) ||
636
+ (oData.unitProperty && aUnitData[oData.unitProperty] && !aUnitData[oData.unitProperty].length)
637
+ ) {
638
+ const bClearFieldOrBlankValueExists =
639
+ aValues[oData.dataProperty] &&
640
+ aValues[oData.dataProperty].some(function (obj: any) {
641
+ return obj.text === "< Clear Values >" || obj.text === "< Leave Blank >";
642
+ });
643
+ if (oData.dataProperty && !bClearFieldOrBlankValueExists) {
644
+ aValues[oData.dataProperty].push({ text: oDefaultValues.leaveBlankValue, key: "Empty/" + oData.dataProperty });
645
+ }
646
+ const bClearFieldOrBlankUnitValueExists =
647
+ aUnitData[oData.unitProperty] &&
648
+ aUnitData[oData.unitProperty].some(function (obj: any) {
649
+ return obj.text === "< Clear Values >" || obj.text === "< Leave Blank >";
650
+ });
651
+ if (oData.unitProperty && !bClearFieldOrBlankUnitValueExists) {
652
+ aUnitData[oData.unitProperty].push({
653
+ text: oDefaultValues.leaveBlankValue,
654
+ key: "Empty/" + oData.unitProperty
655
+ });
656
+ }
657
+ }
658
+ if (oData.isPropertyReadOnly && typeof oData.isPropertyReadOnly === "boolean") {
659
+ aReadOnlyFieldInfo.push({ "property": oData.dataProperty, value: oData.isPropertyReadOnly, type: "Default" });
660
+ } 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
666
+ ) {
667
+ // This needs to be refactored in accordance with the ReadOnlyExpression change
668
+ aReadOnlyFieldInfo.push({
669
+ "property": oData.dataProperty,
670
+ propertyPath: oData.isPropertyReadOnly.operands[0].operand1.path,
671
+ propertyValue: oData.isPropertyReadOnly.operands[0].operand2.value,
672
+ type: "Path"
673
+ });
674
+ }
675
+
676
+ // Setting visbility of the mass edit field.
677
+ if (oData.editMode) {
678
+ values.visible =
679
+ oData.editMode === EditMode.Editable ||
680
+ aContexts.some(
681
+ MassEditHelper.getFieldVisiblity.bind(MassEditHelper, oData.editMode, oDialogDataModel, oData.dataProperty, values)
682
+ );
683
+ } else {
684
+ values.visible = true;
685
+ }
686
+ });
687
+ return oDialogDataModel;
688
+ },
689
+
690
+ /**
691
+ * Create the mass edit dialog.
692
+ *
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.
697
+ */
698
+ createDialog: function (oTable: Table, aContexts: any[], oController: PageController) {
699
+ const sFragmentName = "sap/fe/core/controls/massEdit/MassEditDialog",
700
+ aDataArray: any[] = [],
701
+ oResourceBundle = (Core as CoreEx).getLibraryResourceBundle("sap.fe.core"),
702
+ oDefaultValues = MassEditHelper.getDefaultTextsForDialog(oResourceBundle, aContexts.length, oTable),
703
+ oDataFieldModel = MassEditHelper.prepareDataForDialog(oTable, aContexts, aDataArray),
704
+ oDialogDataModel = MassEditHelper.setRuntimeModelOnDialog(aContexts, aDataArray, oDefaultValues);
705
+
706
+ return new Promise(function (resolve: (value: any) => void, reject: (reason?: any) => void) {
707
+ const oFragment = XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment");
708
+ return Promise.resolve(
709
+ XMLPreprocessor.process(
710
+ oFragment,
711
+ { name: sFragmentName },
712
+ {
713
+ bindingContexts: {
714
+ dataFieldModel: oDataFieldModel.createBindingContext("/")
715
+ },
716
+ models: {
717
+ dataFieldModel: oDataFieldModel
718
+ }
719
+ }
720
+ )
721
+ )
722
+ .then(function (oFragment: any) {
723
+ return Fragment.load({ definition: oFragment }).then(function (oDialogContent: any) {
724
+ const oDialog = new Dialog({
725
+ title: oDefaultValues.massEditTitle,
726
+ content: [oDialogContent],
727
+ beginButton: new Button({
728
+ text: oDefaultValues.applyButtonText,
729
+ type: "Emphasized",
730
+ press: function (oEvent: any) {
731
+ const oDialog = oEvent.getSource().getParent();
732
+ const oModel = oDialog.getModel("fieldsInfo");
733
+ const aResults = oModel.getProperty("/results");
734
+ const aPropertyReadableInfo = oModel.getProperty("/readablePropertyData");
735
+ const changePromise: any[] = [];
736
+ let bReadOnlyField = false;
737
+ let groupId;
738
+ let index = 0;
739
+ aContexts.forEach(function (oSelectedContext: any) {
740
+ aResults.forEach(function (oResult: any) {
741
+ //TODO - Add save implementation for Value Help.
742
+ if (aPropertyReadableInfo) {
743
+ bReadOnlyField = aPropertyReadableInfo.some(function (oPropertyInfo: any) {
744
+ if (oResult.keyValue === oPropertyInfo.property) {
745
+ if (oPropertyInfo.type === "Default") {
746
+ return oPropertyInfo.value === true;
747
+ } else if (
748
+ oPropertyInfo.type === "Path" &&
749
+ oPropertyInfo.propertyValue &&
750
+ oPropertyInfo.propertyPath
751
+ ) {
752
+ return (
753
+ oSelectedContext.getObject(oPropertyInfo.propertyPath) ===
754
+ oPropertyInfo.propertyValue
755
+ );
756
+ }
757
+ }
758
+ });
759
+ }
760
+ groupId = "$auto." + index;
761
+ index += 1;
762
+ if (oResult.keyValue && oResult.value !== "Default" && !bReadOnlyField) {
763
+ changePromise.push(oSelectedContext.setProperty(oResult.keyValue, oResult.value, groupId));
764
+ }
765
+ });
766
+ });
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;
775
+ });
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);
782
+ });
783
+ }
784
+ }),
785
+ endButton: new Button({
786
+ text: oDefaultValues.cancelButtonText,
787
+ press: function (oEvent: any) {
788
+ const oDialog = oEvent.getSource().getParent();
789
+ oDialog.close();
790
+ oDialog.destroy();
791
+ }
792
+ })
793
+ });
794
+ oDialog.setModel(oDialogDataModel, "fieldsInfo");
795
+ resolve(oDialog);
796
+ });
797
+ })
798
+ .catch(reject);
799
+ });
800
+ }
801
+ };
802
+
803
+ export default MassEditHelper;