@sapui5/sap.fe.core 1.97.0 → 1.100.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (306) hide show
  1. package/package.json +7 -4
  2. package/src/sap/fe/core/.library +1 -1
  3. package/src/sap/fe/core/AnnotationHelper.js +309 -405
  4. package/src/sap/fe/core/AnnotationHelper.ts +315 -0
  5. package/src/sap/fe/core/AppComponent.js +389 -397
  6. package/src/sap/fe/core/AppComponent.ts +403 -0
  7. package/src/sap/fe/core/AppStateHandler.js +198 -181
  8. package/src/sap/fe/core/AppStateHandler.ts +171 -0
  9. package/src/sap/fe/core/BaseController.js +83 -58
  10. package/src/sap/fe/core/BaseController.ts +68 -0
  11. package/src/sap/fe/core/BusyLocker.js +105 -121
  12. package/src/sap/fe/core/BusyLocker.ts +98 -0
  13. package/src/sap/fe/core/CommonUtils.js +2164 -2379
  14. package/src/sap/fe/core/CommonUtils.ts +2177 -0
  15. package/src/sap/fe/core/ExtensionAPI.js +279 -266
  16. package/src/sap/fe/core/ExtensionAPI.ts +250 -0
  17. package/src/sap/fe/core/PageController.js +218 -125
  18. package/src/sap/fe/core/PageController.ts +129 -0
  19. package/src/sap/fe/core/RouterProxy.js +924 -807
  20. package/src/sap/fe/core/RouterProxy.ts +840 -0
  21. package/src/sap/fe/core/Synchronization.js +41 -35
  22. package/src/sap/fe/core/Synchronization.ts +29 -0
  23. package/src/sap/fe/core/TemplateComponent.js +173 -155
  24. package/src/sap/fe/core/TemplateComponent.ts +173 -0
  25. package/src/sap/fe/core/TemplateModel.js +79 -54
  26. package/src/sap/fe/core/TemplateModel.ts +63 -0
  27. package/src/sap/fe/core/TransactionHelper.js +1560 -1579
  28. package/src/sap/fe/core/TransactionHelper.ts +1717 -0
  29. package/src/sap/fe/core/actions/collaboration/ActivitySync.js +392 -0
  30. package/src/sap/fe/core/actions/collaboration/ActivitySync.ts +355 -0
  31. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.js +136 -0
  32. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.ts +119 -0
  33. package/src/sap/fe/core/actions/collaboration/Manage.js +262 -0
  34. package/src/sap/fe/core/actions/collaboration/Manage.ts +244 -0
  35. package/src/sap/fe/core/actions/collaboration/ManageDialog.fragment.xml +103 -0
  36. package/src/sap/fe/core/actions/collaboration/UserDetails.fragment.xml +13 -0
  37. package/src/sap/fe/core/actions/draft.js +521 -581
  38. package/src/sap/fe/core/actions/draft.ts +566 -0
  39. package/src/sap/fe/core/actions/messageHandling.js +564 -511
  40. package/src/sap/fe/core/actions/messageHandling.ts +552 -0
  41. package/src/sap/fe/core/actions/nonDraft.js +17 -19
  42. package/src/sap/fe/core/actions/nonDraft.ts +12 -0
  43. package/src/sap/fe/core/actions/operations.js +1093 -1211
  44. package/src/sap/fe/core/actions/operations.ts +1192 -0
  45. package/src/sap/fe/core/actions/sticky.js +114 -104
  46. package/src/sap/fe/core/actions/sticky.ts +119 -0
  47. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +70 -66
  48. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.ts +65 -0
  49. package/src/sap/fe/core/controllerextensions/EditFlow.js +1594 -1701
  50. package/src/sap/fe/core/controllerextensions/EditFlow.ts +1672 -0
  51. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +80 -54
  52. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +61 -0
  53. package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +719 -505
  54. package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +783 -0
  55. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +797 -813
  56. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +803 -0
  57. package/src/sap/fe/core/controllerextensions/InternalRouting.js +1005 -973
  58. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +978 -0
  59. package/src/sap/fe/core/controllerextensions/KPIManagement.js +530 -476
  60. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +137 -46
  61. package/src/sap/fe/core/controllerextensions/MassEdit.js +144 -0
  62. package/src/sap/fe/core/controllerextensions/MassEdit.ts +156 -0
  63. package/src/sap/fe/core/controllerextensions/MessageHandler.js +234 -232
  64. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +225 -0
  65. package/src/sap/fe/core/controllerextensions/PageReady.js +302 -337
  66. package/src/sap/fe/core/controllerextensions/PageReady.ts +23 -17
  67. package/src/sap/fe/core/controllerextensions/Paginator.js +189 -148
  68. package/src/sap/fe/core/controllerextensions/Paginator.ts +163 -0
  69. package/src/sap/fe/core/controllerextensions/Placeholder.js +158 -146
  70. package/src/sap/fe/core/controllerextensions/Placeholder.ts +151 -0
  71. package/src/sap/fe/core/controllerextensions/Routing.js +145 -106
  72. package/src/sap/fe/core/controllerextensions/Routing.ts +132 -0
  73. package/src/sap/fe/core/controllerextensions/RoutingListener.js +8 -6
  74. package/src/sap/fe/core/controllerextensions/RoutingListener.ts +3 -0
  75. package/src/sap/fe/core/controllerextensions/Share.js +220 -244
  76. package/src/sap/fe/core/controllerextensions/Share.ts +231 -0
  77. package/src/sap/fe/core/controllerextensions/SideEffects.js +593 -634
  78. package/src/sap/fe/core/controllerextensions/SideEffects.ts +29 -27
  79. package/src/sap/fe/core/controllerextensions/ViewState.js +789 -806
  80. package/src/sap/fe/core/controllerextensions/ViewState.ts +805 -0
  81. package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +4 -3
  82. package/src/sap/fe/core/controls/ActionPartial.fragment.xml +2 -2
  83. package/src/sap/fe/core/controls/CommandExecution.js +68 -66
  84. package/src/sap/fe/core/controls/CommandExecution.ts +72 -0
  85. package/src/sap/fe/core/controls/ConditionalWrapper.js +91 -75
  86. package/src/sap/fe/core/controls/ConditionalWrapper.ts +83 -0
  87. package/src/sap/fe/core/controls/CustomQuickViewPage.js +131 -125
  88. package/src/sap/fe/core/controls/CustomQuickViewPage.ts +126 -0
  89. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +105 -110
  90. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +101 -0
  91. package/src/sap/fe/core/controls/FieldWrapper.js +122 -140
  92. package/src/sap/fe/core/controls/FieldWrapper.ts +115 -0
  93. package/src/sap/fe/core/controls/FilterBar.js +163 -159
  94. package/src/sap/fe/core/controls/FilterBar.ts +143 -0
  95. package/src/sap/fe/core/controls/FormElementWrapper.js +46 -44
  96. package/src/sap/fe/core/controls/FormElementWrapper.ts +40 -0
  97. package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +38 -42
  98. package/src/sap/fe/core/controls/MultiValueParameterDelegate.ts +31 -0
  99. package/src/sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog.fragment.xml +2 -1
  100. package/src/sap/fe/core/controls/filterbar/FilterContainer.js +127 -116
  101. package/src/sap/fe/core/controls/filterbar/FilterContainer.ts +98 -0
  102. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +242 -255
  103. package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +245 -0
  104. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +151 -141
  105. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +125 -0
  106. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +336 -322
  107. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +337 -0
  108. package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +106 -0
  109. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +79 -0
  110. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +70 -0
  111. package/src/sap/fe/core/converters/ConverterContext.js +348 -367
  112. package/src/sap/fe/core/converters/ConverterContext.ts +33 -19
  113. package/src/sap/fe/core/converters/ManifestSettings.js +12 -1
  114. package/src/sap/fe/core/converters/ManifestSettings.ts +16 -1
  115. package/src/sap/fe/core/converters/ManifestWrapper.js +354 -354
  116. package/src/sap/fe/core/converters/ManifestWrapper.ts +34 -6
  117. package/src/sap/fe/core/converters/MetaModelConverter.js +72 -9
  118. package/src/sap/fe/core/converters/MetaModelConverter.ts +75 -16
  119. package/src/sap/fe/core/converters/TemplateConverter.js +1 -1
  120. package/src/sap/fe/core/converters/TemplateConverter.ts +4 -3
  121. package/src/sap/fe/core/converters/annotations/DataField.js +28 -14
  122. package/src/sap/fe/core/converters/annotations/DataField.ts +38 -14
  123. package/src/sap/fe/core/converters/common/AnnotationConverter.js +33 -21
  124. package/src/sap/fe/core/converters/controls/Common/Action.js +11 -2
  125. package/src/sap/fe/core/converters/controls/Common/Action.ts +8 -2
  126. package/src/sap/fe/core/converters/controls/Common/Chart.js +5 -3
  127. package/src/sap/fe/core/converters/controls/Common/Chart.ts +11 -3
  128. package/src/sap/fe/core/converters/controls/Common/DataVisualization.js +3 -3
  129. package/src/sap/fe/core/converters/controls/Common/DataVisualization.ts +2 -2
  130. package/src/sap/fe/core/converters/controls/Common/Form.js +21 -11
  131. package/src/sap/fe/core/converters/controls/Common/Form.ts +28 -6
  132. package/src/sap/fe/core/converters/controls/Common/KPI.js +69 -4
  133. package/src/sap/fe/core/converters/controls/Common/KPI.ts +75 -2
  134. package/src/sap/fe/core/converters/controls/Common/Table.js +507 -408
  135. package/src/sap/fe/core/converters/controls/Common/Table.ts +618 -500
  136. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +592 -0
  137. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +718 -0
  138. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +465 -59
  139. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +462 -72
  140. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.js +2 -2
  141. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.ts +1 -1
  142. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +17 -9
  143. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +24 -9
  144. package/src/sap/fe/core/converters/helpers/Aggregation.js +118 -121
  145. package/src/sap/fe/core/converters/helpers/Aggregation.ts +28 -5
  146. package/src/sap/fe/core/converters/helpers/BindingHelper.js +20 -6
  147. package/src/sap/fe/core/converters/helpers/BindingHelper.ts +16 -4
  148. package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +12 -1
  149. package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +11 -0
  150. package/src/sap/fe/core/converters/helpers/IssueManager.js +7 -1
  151. package/src/sap/fe/core/converters/helpers/IssueManager.ts +6 -0
  152. package/src/sap/fe/core/converters/helpers/Key.js +42 -57
  153. package/src/sap/fe/core/converters/helpers/Key.ts +1 -1
  154. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +28 -7
  155. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +23 -6
  156. package/src/sap/fe/core/converters/templates/ListReportConverter.js +20 -7
  157. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +36 -14
  158. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +7 -5
  159. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +5 -1
  160. package/src/sap/fe/core/designtime/AppComponent.designtime.js +93 -90
  161. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +91 -0
  162. package/src/sap/fe/core/formatters/CollaborationFormatter.js +104 -0
  163. package/src/sap/fe/core/formatters/CollaborationFormatter.ts +60 -0
  164. package/src/sap/fe/core/formatters/CriticalityFormatter.js +1 -1
  165. package/src/sap/fe/core/formatters/CriticalityFormatter.ts +1 -1
  166. package/src/sap/fe/core/formatters/FPMFormatter.js +1 -1
  167. package/src/sap/fe/core/formatters/FPMFormatter.ts +4 -10
  168. package/src/sap/fe/core/formatters/KPIFormatter.js +1 -1
  169. package/src/sap/fe/core/formatters/KPIFormatter.ts +3 -1
  170. package/src/sap/fe/core/formatters/TableFormatter.js +91 -29
  171. package/src/sap/fe/core/formatters/TableFormatter.ts +94 -28
  172. package/src/sap/fe/core/formatters/ValueFormatter.js +30 -5
  173. package/src/sap/fe/core/formatters/ValueFormatter.ts +30 -7
  174. package/src/sap/fe/core/fpm/Component.js +51 -54
  175. package/src/sap/fe/core/fpm/Component.ts +48 -0
  176. package/src/sap/fe/core/helpers/AppStartupHelper.js +373 -0
  177. package/src/sap/fe/core/helpers/AppStartupHelper.ts +417 -0
  178. package/src/sap/fe/core/helpers/BindingExpression.js +489 -442
  179. package/src/sap/fe/core/helpers/BindingExpression.ts +486 -469
  180. package/src/sap/fe/core/helpers/ClassSupport.js +212 -76
  181. package/src/sap/fe/core/helpers/ClassSupport.ts +198 -71
  182. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +64 -59
  183. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +52 -0
  184. package/src/sap/fe/core/helpers/EditState.js +81 -84
  185. package/src/sap/fe/core/helpers/EditState.ts +81 -0
  186. package/src/sap/fe/core/helpers/ExcelFormatHelper.js +62 -48
  187. package/src/sap/fe/core/helpers/ExcelFormatHelper.ts +49 -0
  188. package/src/sap/fe/core/helpers/FPMHelper.js +52 -56
  189. package/src/sap/fe/core/helpers/FPMHelper.ts +62 -0
  190. package/src/sap/fe/core/helpers/KeepAliveHelper.js +4 -5
  191. package/src/sap/fe/core/helpers/KeepAliveHelper.ts +10 -10
  192. package/src/sap/fe/core/helpers/MassEditHelper.js +604 -0
  193. package/src/sap/fe/core/helpers/MassEditHelper.ts +699 -0
  194. package/src/sap/fe/core/helpers/ModelHelper.js +253 -225
  195. package/src/sap/fe/core/helpers/ModelHelper.ts +250 -0
  196. package/src/sap/fe/core/helpers/PasteHelper.js +210 -132
  197. package/src/sap/fe/core/helpers/PasteHelper.ts +196 -0
  198. package/src/sap/fe/core/helpers/SemanticDateOperators.js +336 -313
  199. package/src/sap/fe/core/helpers/SemanticDateOperators.ts +334 -0
  200. package/src/sap/fe/core/helpers/SemanticKeyHelper.js +66 -67
  201. package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +73 -0
  202. package/src/sap/fe/core/helpers/StableIdHelper.js +4 -7
  203. package/src/sap/fe/core/helpers/StableIdHelper.ts +2 -6
  204. package/src/sap/fe/core/jsx-runtime/jsx.js +1 -1
  205. package/src/sap/fe/core/jsx-runtime/jsx.ts +1 -1
  206. package/src/sap/fe/core/library.js +427 -425
  207. package/src/sap/fe/core/library.support.js +23 -27
  208. package/src/sap/fe/core/library.support.ts +23 -0
  209. package/src/sap/fe/core/library.ts +420 -0
  210. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +64 -0
  211. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +69 -0
  212. package/src/sap/fe/core/messagebundle.properties +78 -13
  213. package/src/sap/fe/core/messagebundle_ar.properties +58 -7
  214. package/src/sap/fe/core/messagebundle_bg.properties +58 -7
  215. package/src/sap/fe/core/messagebundle_ca.properties +58 -7
  216. package/src/sap/fe/core/messagebundle_cs.properties +59 -8
  217. package/src/sap/fe/core/messagebundle_cy.properties +58 -7
  218. package/src/sap/fe/core/messagebundle_da.properties +58 -7
  219. package/src/sap/fe/core/messagebundle_de.properties +58 -7
  220. package/src/sap/fe/core/messagebundle_el.properties +58 -7
  221. package/src/sap/fe/core/messagebundle_en.properties +57 -6
  222. package/src/sap/fe/core/messagebundle_en_GB.properties +57 -6
  223. package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +61 -6
  224. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +58 -7
  225. package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +58 -7
  226. package/src/sap/fe/core/messagebundle_es.properties +58 -7
  227. package/src/sap/fe/core/messagebundle_es_MX.properties +58 -7
  228. package/src/sap/fe/core/messagebundle_et.properties +58 -7
  229. package/src/sap/fe/core/messagebundle_fi.properties +60 -9
  230. package/src/sap/fe/core/messagebundle_fr.properties +64 -13
  231. package/src/sap/fe/core/messagebundle_fr_CA.properties +59 -8
  232. package/src/sap/fe/core/messagebundle_hi.properties +58 -7
  233. package/src/sap/fe/core/messagebundle_hr.properties +58 -7
  234. package/src/sap/fe/core/messagebundle_hu.properties +59 -8
  235. package/src/sap/fe/core/messagebundle_id.properties +61 -10
  236. package/src/sap/fe/core/messagebundle_it.properties +58 -7
  237. package/src/sap/fe/core/messagebundle_iw.properties +58 -7
  238. package/src/sap/fe/core/messagebundle_ja.properties +58 -7
  239. package/src/sap/fe/core/messagebundle_kk.properties +58 -7
  240. package/src/sap/fe/core/messagebundle_ko.properties +58 -7
  241. package/src/sap/fe/core/messagebundle_lt.properties +58 -7
  242. package/src/sap/fe/core/messagebundle_lv.properties +59 -8
  243. package/src/sap/fe/core/messagebundle_ms.properties +58 -7
  244. package/src/sap/fe/core/messagebundle_nl.properties +58 -7
  245. package/src/sap/fe/core/messagebundle_no.properties +58 -7
  246. package/src/sap/fe/core/messagebundle_pl.properties +58 -7
  247. package/src/sap/fe/core/messagebundle_pt.properties +59 -8
  248. package/src/sap/fe/core/messagebundle_pt_PT.properties +58 -7
  249. package/src/sap/fe/core/messagebundle_ro.properties +58 -7
  250. package/src/sap/fe/core/messagebundle_ru.properties +58 -7
  251. package/src/sap/fe/core/messagebundle_sh.properties +58 -7
  252. package/src/sap/fe/core/messagebundle_sk.properties +58 -7
  253. package/src/sap/fe/core/messagebundle_sl.properties +58 -7
  254. package/src/sap/fe/core/messagebundle_sv.properties +59 -8
  255. package/src/sap/fe/core/messagebundle_th.properties +58 -7
  256. package/src/sap/fe/core/messagebundle_tr.properties +60 -9
  257. package/src/sap/fe/core/messagebundle_uk.properties +58 -7
  258. package/src/sap/fe/core/messagebundle_vi.properties +58 -7
  259. package/src/sap/fe/core/messagebundle_zh_CN.properties +58 -7
  260. package/src/sap/fe/core/messagebundle_zh_TW.properties +58 -7
  261. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +45 -71
  262. package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +3 -1
  263. package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +231 -202
  264. package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +212 -0
  265. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +67 -92
  266. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +10 -6
  267. package/src/sap/fe/core/services/NavigationServiceFactory.js +351 -300
  268. package/src/sap/fe/core/services/NavigationServiceFactory.ts +313 -0
  269. package/src/sap/fe/core/services/ResourceModelServiceFactory.js +114 -81
  270. package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +83 -0
  271. package/src/sap/fe/core/services/RoutingServiceFactory.js +927 -1152
  272. package/src/sap/fe/core/services/RoutingServiceFactory.ts +898 -0
  273. package/src/sap/fe/core/services/ShellServicesFactory.js +649 -707
  274. package/src/sap/fe/core/services/ShellServicesFactory.ts +52 -15
  275. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +569 -637
  276. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +78 -102
  277. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +429 -478
  278. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +460 -0
  279. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +10 -8
  280. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +8 -0
  281. package/src/sap/fe/core/support/AnnotationIssue.support.js +15 -3
  282. package/src/sap/fe/core/support/AnnotationIssue.support.ts +16 -2
  283. package/src/sap/fe/core/support/CollectionFacetUnsupportedLevel.support.js +2 -2
  284. package/src/sap/fe/core/support/CollectionFacetUnsupportedLevel.support.ts +1 -1
  285. package/src/sap/fe/core/support/CommonHelper.js +1 -1
  286. package/src/sap/fe/core/support/CommonHelper.ts +1 -1
  287. package/src/sap/fe/core/support/Diagnostics.js +36 -48
  288. package/src/sap/fe/core/support/InvalidAnnotationColumnKey.support.js +38 -0
  289. package/src/sap/fe/core/support/InvalidAnnotationColumnKey.support.ts +18 -0
  290. package/src/sap/fe/core/templating/DataModelPathHelper.js +97 -127
  291. package/src/sap/fe/core/templating/DataModelPathHelper.ts +112 -135
  292. package/src/sap/fe/core/templating/DisplayModeFormatter.js +114 -0
  293. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +86 -0
  294. package/src/sap/fe/core/templating/FieldControlHelper.js +8 -8
  295. package/src/sap/fe/core/templating/FieldControlHelper.ts +25 -7
  296. package/src/sap/fe/core/templating/FilterHelper.js +140 -78
  297. package/src/sap/fe/core/templating/FilterHelper.ts +149 -78
  298. package/src/sap/fe/core/templating/PropertyHelper.js +3 -3
  299. package/src/sap/fe/core/templating/PropertyHelper.ts +2 -2
  300. package/src/sap/fe/core/templating/UIFormatters.js +76 -135
  301. package/src/sap/fe/core/templating/UIFormatters.ts +76 -99
  302. package/src/sap/fe/core/type/Email.js +1 -1
  303. package/src/sap/fe/core/type/Email.ts +4 -6
  304. package/ui5.yaml +0 -3
  305. package/src/sap/fe/core/controls/filterbar.d.js +0 -8
  306. package/src/sap/fe/core/controls/filterbar.d.ts +0 -0
@@ -0,0 +1,2177 @@
1
+ import View from "sap/ui/core/mvc/View";
2
+ import Component from "sap/ui/core/Component";
3
+ import MessageBox from "sap/m/MessageBox";
4
+ import Log from "sap/base/Log";
5
+ import library from "sap/fe/core/library";
6
+ import ModelHelper from "sap/fe/core/helpers/ModelHelper";
7
+ import SemanticDateOperators from "sap/fe/core/helpers/SemanticDateOperators";
8
+ import mergeObjects from "sap/base/util/merge";
9
+ import XMLTemplateProcessor from "sap/ui/core/XMLTemplateProcessor";
10
+ import XMLPreprocessor from "sap/ui/core/util/XMLPreprocessor";
11
+ import Fragment from "sap/ui/core/Fragment";
12
+ import ODataMetaModel from "sap/ui/model/odata/v4/ODataMetaModel";
13
+ import ResourceBundle from "sap/base/i18n/ResourceBundle";
14
+ import { bindingExpression, compileBinding, constant, transformRecursively } from "sap/fe/core/helpers/BindingExpression";
15
+ import { getConditions } from "./templating/FilterHelper";
16
+ import AppComponent from "sap/fe/core/AppComponent";
17
+ import JSONModel from "sap/ui/model/json/JSONModel";
18
+ import { generate } from "sap/fe/core/helpers/StableIdHelper";
19
+ import ODataModel from "sap/ui/model/odata/v4/ODataModel";
20
+ import Control from "sap/ui/core/Control";
21
+ import FilterOperatorUtil from "sap/ui/mdc/condition/FilterOperatorUtil";
22
+ import TypeUtil from "sap/ui/mdc/odata/v4/TypeUtil";
23
+ import { IssueCategory, IssueSeverity, IssueCategoryType } from "sap/fe/core/converters/helpers/IssueManager";
24
+ import { isConnected, disconnect } from "sap/fe/core/actions/collaboration/ActivitySync";
25
+ import Context from "sap/ui/model/Context";
26
+ import { performAfterDiscardorKeepDraft } from "./controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler";
27
+ import Button from "sap/m/Button";
28
+ import Dialog from "sap/m/Dialog";
29
+ import Bar from "sap/m/Bar";
30
+ import Title from "sap/m/Title";
31
+ import messageHandling from "./actions/messageHandling";
32
+
33
+ const ProgrammingModel = library.ProgrammingModel;
34
+ const aValidTypes = [
35
+ "Edm.Boolean",
36
+ "Edm.Byte",
37
+ "Edm.Date",
38
+ "Edm.DateTime",
39
+ "Edm.DateTimeOffset",
40
+ "Edm.Decimal",
41
+ "Edm.Double",
42
+ "Edm.Float",
43
+ "Edm.Guid",
44
+ "Edm.Int16",
45
+ "Edm.Int32",
46
+ "Edm.Int64",
47
+ "Edm.SByte",
48
+ "Edm.Single",
49
+ "Edm.String",
50
+ "Edm.Time",
51
+ "Edm.TimeOfDay"
52
+ ];
53
+
54
+ function normalizeSearchTerm(sSearchTerm: string) {
55
+ if (!sSearchTerm) {
56
+ return undefined;
57
+ }
58
+
59
+ return sSearchTerm
60
+ .replace(/"/g, " ")
61
+ .split(/\s+/)
62
+ .reduce(function(sNormalized: string | undefined, sCurrentWord: string) {
63
+ if (sCurrentWord !== "") {
64
+ sNormalized = (sNormalized ? sNormalized + " " : "") + '"' + sCurrentWord + '"';
65
+ }
66
+ return sNormalized;
67
+ }, undefined);
68
+ }
69
+
70
+ function getPropertyDataType(oNavigationContext: any) {
71
+ let sDataType = oNavigationContext.getProperty("$Type");
72
+ // if $kind exists, it's not a DataField and we have the final type already
73
+ if (!oNavigationContext.getProperty("$kind")) {
74
+ switch (sDataType) {
75
+ case "com.sap.vocabularies.UI.v1.DataFieldForAction":
76
+ case "com.sap.vocabularies.UI.v1.DataFieldForIntentBasedNavigation":
77
+ sDataType = undefined;
78
+ break;
79
+
80
+ case "com.sap.vocabularies.UI.v1.DataField":
81
+ case "com.sap.vocabularies.UI.v1.DataFieldWithNavigationPath":
82
+ case "com.sap.vocabularies.UI.v1.DataFieldWithUrl":
83
+ case "com.sap.vocabularies.UI.v1.DataFieldWithIntentBasedNavigation":
84
+ case "com.sap.vocabularies.UI.v1.DataFieldWithAction":
85
+ sDataType = oNavigationContext.getProperty("Value/$Path/$Type");
86
+ break;
87
+
88
+ case "com.sap.vocabularies.UI.v1.DataFieldForAnnotation":
89
+ default:
90
+ const sAnnotationPath = oNavigationContext.getProperty("Target/$AnnotationPath");
91
+ if (sAnnotationPath) {
92
+ if (sAnnotationPath.indexOf("com.sap.vocabularies.Communication.v1.Contact") > -1) {
93
+ sDataType = oNavigationContext.getProperty("Target/$AnnotationPath/fn/$Path/$Type");
94
+ } else if (sAnnotationPath.indexOf("com.sap.vocabularies.UI.v1.DataPoint") > -1) {
95
+ sDataType = oNavigationContext.getProperty("Value/$Path/$Type");
96
+ } else {
97
+ // e.g. FieldGroup or Chart
98
+ sDataType = undefined;
99
+ }
100
+ } else {
101
+ sDataType = undefined;
102
+ }
103
+ break;
104
+ }
105
+ }
106
+
107
+ return sDataType;
108
+ }
109
+ function fnHasTransientContexts(oListBinding: any) {
110
+ let bHasTransientContexts = false;
111
+ if (oListBinding) {
112
+ oListBinding.getCurrentContexts().forEach(function(oContext: any) {
113
+ if (oContext && oContext.isTransient()) {
114
+ bHasTransientContexts = true;
115
+ }
116
+ });
117
+ }
118
+ return bHasTransientContexts;
119
+ }
120
+ function getSearchRestrictions(sFullPath: any, oMetaModel: any) {
121
+ let i = 0;
122
+ const aNavigationParts = sFullPath.split("/$NavigationPropertyBinding/");
123
+ for (let sPath = aNavigationParts[0]; i < aNavigationParts.length - 1; i++) {
124
+ const oNavigationRestrictions = getNavigationRestrictions(oMetaModel, sPath, aNavigationParts[i + 1]);
125
+ if (oNavigationRestrictions && oNavigationRestrictions["SearchRestrictions"]) {
126
+ return oNavigationRestrictions["SearchRestrictions"];
127
+ }
128
+ sPath = sPath + "/$NavigationPropertyBinding/" + aNavigationParts[i];
129
+ }
130
+ return oMetaModel.getObject(sFullPath + "@Org.OData.Capabilities.V1.SearchRestrictions");
131
+ }
132
+ function getNavigationRestrictions(oModel: any, sEntitySetPath: any, sNavigationPath: any) {
133
+ const oNavigationRestrictions = oModel.getObject(sEntitySetPath + "@Org.OData.Capabilities.V1.NavigationRestrictions");
134
+ const aRestrictedProperties = oNavigationRestrictions && oNavigationRestrictions.RestrictedProperties;
135
+ return (
136
+ aRestrictedProperties &&
137
+ aRestrictedProperties.find(function(oRestrictedProperty: any) {
138
+ return (
139
+ oRestrictedProperty &&
140
+ oRestrictedProperty.NavigationProperty &&
141
+ oRestrictedProperty.NavigationProperty.$NavigationPropertyPath === sNavigationPath
142
+ );
143
+ })
144
+ );
145
+ }
146
+ function _isInNonFilterableProperties(oModel: any, sEntitySetPath: any, sContextPath: any) {
147
+ let bIsNotFilterable = false;
148
+ const oAnnotation = oModel.getObject(sEntitySetPath + "@Org.OData.Capabilities.V1.FilterRestrictions");
149
+ if (oAnnotation && oAnnotation.NonFilterableProperties) {
150
+ bIsNotFilterable = oAnnotation.NonFilterableProperties.some(function(property: any) {
151
+ return property.$NavigationPropertyPath === sContextPath || property.$PropertyPath === sContextPath;
152
+ });
153
+ }
154
+ return bIsNotFilterable;
155
+ }
156
+ // TODO rework this!
157
+ function _isContextPathFilterable(oModel: any, sEntitySetPath: any, sContexPath: any) {
158
+ const sFullPath = sEntitySetPath + "/" + sContexPath,
159
+ aESParts = sFullPath.split("/").splice(0, 2),
160
+ aContext = sFullPath.split("/").splice(2);
161
+ let bIsNotFilterable = false,
162
+ sContext = "";
163
+
164
+ sEntitySetPath = aESParts.join("/");
165
+
166
+ bIsNotFilterable = aContext.some(function(item: string, index: number, array: string[]) {
167
+ if (sContext.length > 0) {
168
+ sContext += "/" + item;
169
+ } else {
170
+ sContext = item;
171
+ }
172
+ if (index === array.length - 2) {
173
+ // In case of "/Customer/Set/Property" this is to check navigation restrictions of "Customer" for non-filterable properties in "Set"
174
+ const oNavigationRestrictions = getNavigationRestrictions(oModel, sEntitySetPath, item);
175
+ const oFilterRestrictions = oNavigationRestrictions && oNavigationRestrictions.FilterRestrictions;
176
+ const aNonFilterableProperties = oFilterRestrictions && oFilterRestrictions.NonFilterableProperties;
177
+ const sTargetPropertyPath = array[array.length - 1];
178
+ if (
179
+ aNonFilterableProperties &&
180
+ aNonFilterableProperties.find(function(oPropertyPath: any) {
181
+ return oPropertyPath.$PropertyPath === sTargetPropertyPath;
182
+ })
183
+ ) {
184
+ return true;
185
+ }
186
+ }
187
+ if (index === array.length - 1) {
188
+ //last path segment
189
+ bIsNotFilterable = _isInNonFilterableProperties(oModel, sEntitySetPath, sContext);
190
+ } else if (oModel.getObject(sEntitySetPath + "/$NavigationPropertyBinding/" + item)) {
191
+ //check existing context path and initialize it
192
+ bIsNotFilterable = _isInNonFilterableProperties(oModel, sEntitySetPath, sContext);
193
+ sContext = "";
194
+ //set the new EntitySet
195
+ sEntitySetPath = "/" + oModel.getObject(sEntitySetPath + "/$NavigationPropertyBinding/" + item);
196
+ }
197
+ return bIsNotFilterable === true;
198
+ });
199
+ return bIsNotFilterable;
200
+ }
201
+ // TODO check used places and rework this
202
+ function isPropertyFilterable(oModel: ODataMetaModel, sEntitySetPath: string, sProperty: string, bSkipHiddenFilter: boolean) {
203
+ if (typeof sProperty !== "string") {
204
+ throw new Error("sProperty parameter must be a string");
205
+ }
206
+ let bIsFilterable;
207
+
208
+ // Parameters should be rendered as filterfields
209
+ if (oModel.getObject(sEntitySetPath + "/@com.sap.vocabularies.Common.v1.ResultContext") === true) {
210
+ return true;
211
+ }
212
+
213
+ const oNavigationContext = oModel.createBindingContext(sEntitySetPath + "/" + sProperty) as Context;
214
+
215
+ if (oNavigationContext.getProperty("@com.sap.vocabularies.UI.v1.Hidden") === true) {
216
+ return false;
217
+ }
218
+
219
+ if (!bSkipHiddenFilter && oNavigationContext.getProperty("@com.sap.vocabularies.UI.v1.HiddenFilter")) {
220
+ return false;
221
+ }
222
+
223
+ if (sEntitySetPath.split("/").length === 2 && sProperty.indexOf("/") < 0) {
224
+ // there is no navigation in entitySet path and property path
225
+ bIsFilterable = !_isInNonFilterableProperties(oModel, sEntitySetPath, sProperty);
226
+ } else {
227
+ bIsFilterable = !_isContextPathFilterable(oModel, sEntitySetPath, sProperty);
228
+ }
229
+ // check if type can be used for filtering
230
+ if (bIsFilterable && oNavigationContext) {
231
+ const sPropertyDataType = getPropertyDataType(oNavigationContext);
232
+ if (sPropertyDataType) {
233
+ bIsFilterable = aValidTypes.indexOf(sPropertyDataType) !== -1;
234
+ } else {
235
+ bIsFilterable = false;
236
+ }
237
+ }
238
+
239
+ return bIsFilterable;
240
+ }
241
+ function getShellServices(oControl: any) {
242
+ return getAppComponent(oControl).getShellServices();
243
+ }
244
+ function getHash() {
245
+ const sHash = window.location.hash;
246
+ return sHash.split("&")[0];
247
+ }
248
+ function _getSOIntents(oObjectPageLayout: any, oSemanticObject: any, oParam: any) {
249
+ const oShellServiceHelper = CommonUtils.getShellServices(oObjectPageLayout);
250
+ return oShellServiceHelper.getLinks({
251
+ semanticObject: oSemanticObject,
252
+ params: oParam
253
+ });
254
+ }
255
+ // TO-DO add this as part of applySemanticObjectmappings logic in IntentBasednavigation controller extension
256
+ function _createMappings(oMapping: any) {
257
+ const aSOMappings = [];
258
+ const aMappingKeys = Object.keys(oMapping);
259
+ let oSemanticMapping;
260
+ for (let i = 0; i < aMappingKeys.length; i++) {
261
+ oSemanticMapping = {
262
+ "LocalProperty": {
263
+ "$PropertyPath": aMappingKeys[i]
264
+ },
265
+ "SemanticObjectProperty": oMapping[aMappingKeys[i]]
266
+ };
267
+ aSOMappings.push(oSemanticMapping);
268
+ }
269
+
270
+ return aSOMappings;
271
+ }
272
+ /**
273
+ * @param aLinks
274
+ * @param aExcludedActions
275
+ * @param oTargetParams
276
+ * @param aItems
277
+ */
278
+ function _getRelatedAppsMenuItems(aLinks: any, aExcludedActions: any, oTargetParams: any, aItems: any) {
279
+ for (let i = 0; i < aLinks.length; i++) {
280
+ const oLink = aLinks[i];
281
+ const sIntent = oLink.intent;
282
+ const sAction = sIntent.split("-")[1].split("?")[0];
283
+ if (aExcludedActions && aExcludedActions.indexOf(sAction) === -1) {
284
+ aItems.push({
285
+ text: oLink.text,
286
+ targetSemObject: sIntent.split("#")[1].split("-")[0],
287
+ targetAction: sAction.split("~")[0],
288
+ targetParams: oTargetParams
289
+ });
290
+ }
291
+ }
292
+ }
293
+ /**
294
+ * @param oAdditionalSemanticObjects
295
+ * @param oBindingContext
296
+ * @param aManifestSOItems
297
+ * @param aLinks
298
+ */
299
+ function _getRelatedIntents(oAdditionalSemanticObjects: any, oBindingContext: any, aManifestSOItems: any, aLinks: any) {
300
+ if (aLinks && aLinks.length > 0) {
301
+ const aExcludedActions = oAdditionalSemanticObjects.unavailableActions ? oAdditionalSemanticObjects.unavailableActions : [];
302
+ const aSOMappings = oAdditionalSemanticObjects.mapping ? _createMappings(oAdditionalSemanticObjects.mapping) : [];
303
+ const oTargetParams = { navigationContexts: oBindingContext, semanticObjectMapping: aSOMappings };
304
+ _getRelatedAppsMenuItems(aLinks, aExcludedActions, oTargetParams, aManifestSOItems);
305
+ }
306
+ }
307
+ function updateRelateAppsModel(
308
+ this: any,
309
+ oBindingContext: any,
310
+ oEntry: any,
311
+ oObjectPageLayout: any,
312
+ aSemKeys: any,
313
+ oMetaModel: any,
314
+ oMetaPath: any
315
+ ) {
316
+ const oShellServiceHelper = getShellServices(oObjectPageLayout);
317
+ const oParam: any = {};
318
+ let sCurrentSemObj = "",
319
+ sCurrentAction = "";
320
+ let oSemanticObjectAnnotations;
321
+ let aRelatedAppsMenuItems: any[] = [];
322
+ let aExcludedActions: any[] = [];
323
+
324
+ if (oEntry) {
325
+ if (aSemKeys && aSemKeys.length > 0) {
326
+ for (let j = 0; j < aSemKeys.length; j++) {
327
+ const sSemKey = aSemKeys[j].$PropertyPath;
328
+ if (!oParam[sSemKey]) {
329
+ oParam[sSemKey] = { value: oEntry[sSemKey] };
330
+ }
331
+ }
332
+ } else {
333
+ // fallback to Technical Keys if no Semantic Key is present
334
+ const aTechnicalKeys = oMetaModel.getObject(oMetaPath + "/$Type/$Key");
335
+ for (const key in aTechnicalKeys) {
336
+ const sObjKey = aTechnicalKeys[key];
337
+ if (!oParam[sObjKey]) {
338
+ oParam[sObjKey] = { value: oEntry[sObjKey] };
339
+ }
340
+ }
341
+ }
342
+ }
343
+ // Logic to read additional SO from manifest and updated relatedapps model
344
+
345
+ const oManifestData = getTargetView(oObjectPageLayout).getViewData();
346
+ const aManifestSOItems: any[] = [];
347
+ if (oManifestData.additionalSemanticObjects) {
348
+ const aManifestSOKeys = Object.keys(oManifestData.additionalSemanticObjects);
349
+ for (let key = 0; key < aManifestSOKeys.length; key++) {
350
+ _getSOIntents(oObjectPageLayout, aManifestSOKeys[key], oParam)
351
+ .then(
352
+ _getRelatedIntents.bind(
353
+ this as any,
354
+ oManifestData.additionalSemanticObjects[aManifestSOKeys[key]],
355
+ oBindingContext,
356
+ aManifestSOItems
357
+ )
358
+ )
359
+ .catch(function(oError: any) {
360
+ Log.error("Error while retrieving SO Intents", oError);
361
+ });
362
+ }
363
+ }
364
+
365
+ function fnGetParseShellHashAndGetLinks() {
366
+ const oParsedUrl = oShellServiceHelper.parseShellHash(document.location.hash);
367
+ sCurrentSemObj = oParsedUrl.semanticObject; // Current Semantic Object
368
+ sCurrentAction = oParsedUrl.action;
369
+ return _getSOIntents(oObjectPageLayout, sCurrentSemObj, oParam);
370
+ }
371
+
372
+ fnGetParseShellHashAndGetLinks()
373
+ .then(function(aLinks: any) {
374
+ if (aLinks && aLinks.length > 0) {
375
+ const oTargetParams: any = {};
376
+ const aAnnotationsSOItems: any[] = [];
377
+ const sEntitySetPath = oMetaPath + "@";
378
+ const sEntityTypePath = oMetaPath + "/@";
379
+ const oEntitySetAnnotations = oMetaModel.getObject(sEntitySetPath);
380
+ oSemanticObjectAnnotations = _getSemanticObjectAnnotations(oEntitySetAnnotations, sCurrentSemObj);
381
+ if (!oSemanticObjectAnnotations.bHasEntitySetSO) {
382
+ const oEntityTypeAnnotations = oMetaModel.getObject(sEntityTypePath);
383
+ oSemanticObjectAnnotations = _getSemanticObjectAnnotations(oEntityTypeAnnotations, sCurrentSemObj);
384
+ }
385
+ aExcludedActions = oSemanticObjectAnnotations.aUnavailableActions;
386
+ //Skip same application from Related Apps
387
+ aExcludedActions.push(sCurrentAction);
388
+ oTargetParams.navigationContexts = oBindingContext;
389
+ oTargetParams.semanticObjectMapping = oSemanticObjectAnnotations.aMappings;
390
+ _getRelatedAppsMenuItems(aLinks, aExcludedActions, oTargetParams, aAnnotationsSOItems);
391
+ aRelatedAppsMenuItems = aAnnotationsSOItems.concat(aManifestSOItems);
392
+ // If no app in list, related apps button will be hidden
393
+ oObjectPageLayout.getBindingContext("internal").setProperty("relatedApps/visibility", aRelatedAppsMenuItems.length > 0);
394
+ oObjectPageLayout.getBindingContext("internal").setProperty("relatedApps/items", aRelatedAppsMenuItems);
395
+ } else {
396
+ oObjectPageLayout.getBindingContext("internal").setProperty("relatedApps/visibility", false);
397
+ }
398
+ })
399
+ .catch(function(oError: any) {
400
+ Log.error("Cannot read links", oError);
401
+ });
402
+ return aRelatedAppsMenuItems;
403
+ }
404
+ function _getSemanticObjectAnnotations(oEntityAnnotations: any, sCurrentSemObj: any) {
405
+ const oSemanticObjectAnnotations = {
406
+ bHasEntitySetSO: false,
407
+ aUnavailableActions: [],
408
+ aMappings: []
409
+ };
410
+ let sAnnotationMappingTerm, sAnnotationActionTerm;
411
+ let sQualifier;
412
+ for (const key in oEntityAnnotations) {
413
+ if (key.indexOf("com.sap.vocabularies.Common.v1.SemanticObject") > -1 && oEntityAnnotations[key] === sCurrentSemObj) {
414
+ oSemanticObjectAnnotations.bHasEntitySetSO = true;
415
+ sAnnotationMappingTerm = "@com.sap.vocabularies.Common.v1.SemanticObjectMapping";
416
+ sAnnotationActionTerm = "@com.sap.vocabularies.Common.v1.SemanticObjectUnavailableActions";
417
+
418
+ if (key.indexOf("#") > -1) {
419
+ sQualifier = key.split("#")[1];
420
+ sAnnotationMappingTerm = sAnnotationMappingTerm + "#" + sQualifier;
421
+ sAnnotationActionTerm = sAnnotationActionTerm + "#" + sQualifier;
422
+ }
423
+
424
+ oSemanticObjectAnnotations.aMappings = oSemanticObjectAnnotations.aMappings.concat(oEntityAnnotations[sAnnotationMappingTerm]);
425
+ oSemanticObjectAnnotations.aUnavailableActions = oSemanticObjectAnnotations.aUnavailableActions.concat(
426
+ oEntityAnnotations[sAnnotationActionTerm]
427
+ );
428
+
429
+ break;
430
+ }
431
+ }
432
+ return oSemanticObjectAnnotations;
433
+ }
434
+ function fnUpdateRelatedAppsDetails(oObjectPageLayout: any) {
435
+ const oMetaModel = oObjectPageLayout.getModel().getMetaModel();
436
+ const oBindingContext = oObjectPageLayout.getBindingContext();
437
+ const oPath = oBindingContext && oBindingContext.getPath();
438
+ const oMetaPath = oMetaModel.getMetaPath(oPath);
439
+ // Semantic Key Vocabulary
440
+ const sSemanticKeyVocabulary = oMetaPath + "/" + "@com.sap.vocabularies.Common.v1.SemanticKey";
441
+ //Semantic Keys
442
+ const aSemKeys = oMetaModel.getObject(sSemanticKeyVocabulary);
443
+ // Unavailable Actions
444
+ const oEntry = oBindingContext.getObject();
445
+ if (!oEntry) {
446
+ oBindingContext
447
+ .requestObject()
448
+ .then(function(oEntry: any) {
449
+ return updateRelateAppsModel(oBindingContext, oEntry, oObjectPageLayout, aSemKeys, oMetaModel, oMetaPath);
450
+ })
451
+ .catch(function(oError: any) {
452
+ Log.error("Cannot update the related app details", oError);
453
+ });
454
+ } else {
455
+ return updateRelateAppsModel(oBindingContext, oEntry, oObjectPageLayout, aSemKeys, oMetaModel, oMetaPath);
456
+ }
457
+ }
458
+ /**
459
+ * @param oButton
460
+ */
461
+ function fnFireButtonPress(oButton: any) {
462
+ const aAuthorizedTypes = ["sap.m.Button", "sap.m.OverflowToolbarButton"];
463
+ if (oButton && aAuthorizedTypes.indexOf(oButton.getMetadata().getName()) !== -1 && oButton.getVisible() && oButton.getEnabled()) {
464
+ oButton.firePress();
465
+ }
466
+ }
467
+ function fnResolveStringtoBoolean(sValue: any) {
468
+ if (sValue === "true" || sValue === true) {
469
+ return true;
470
+ } else {
471
+ return false;
472
+ }
473
+ }
474
+ function getAppComponent(oControl: any): AppComponent {
475
+ if (oControl.isA("sap.fe.core.AppComponent")) {
476
+ return oControl;
477
+ }
478
+ const oOwner = Component.getOwnerComponentFor(oControl);
479
+ if (!oOwner) {
480
+ return oControl;
481
+ } else {
482
+ return getAppComponent(oOwner);
483
+ }
484
+ }
485
+ function getTargetView(oControl: any) {
486
+ if (oControl && oControl.isA("sap.ui.core.ComponentContainer")) {
487
+ oControl = oControl.getComponentInstance();
488
+ oControl = oControl && oControl.getRootControl();
489
+ }
490
+ while (oControl && !(oControl instanceof View)) {
491
+ oControl = oControl.getParent();
492
+ }
493
+ return oControl;
494
+ }
495
+ /**
496
+ * @param fnProcessFunction
497
+ * @param fnCancelFunction
498
+ * @param oContext
499
+ * @param oController
500
+ * @param bSkipBindingToView
501
+ */
502
+ function fnProcessDataLossOrDraftDiscardConfirmation(
503
+ fnProcessFunction: any,
504
+ fnCancelFunction: any,
505
+ oContext: any,
506
+ oController: any,
507
+ bSkipBindingToView?: boolean
508
+ ) {
509
+ const oModel = oContext.getModel();
510
+ let _bIsModified = false;
511
+ const draftDataContext = oModel.bindContext(oContext.getPath() + "/DraftAdministrativeData").getBoundContext();
512
+
513
+ const collaborationConnected = isConnected(oController.getView());
514
+ const processFunctionForDrafts = !collaborationConnected
515
+ ? fnProcessFunction
516
+ : function(...args: any[]) {
517
+ disconnect(oController.getView());
518
+ fnProcessFunction.apply(null, ...args);
519
+ };
520
+
521
+ if (
522
+ oContext &&
523
+ oContext.getObject() &&
524
+ (!oContext.getObject().DraftAdministrativeData || oContext.getObject().IsActiveEntity === true)
525
+ ) {
526
+ fnProcessFunction();
527
+ } else {
528
+ draftDataContext
529
+ .requestObject()
530
+ .then(function(draftAdminData: any) {
531
+ if (draftAdminData) {
532
+ _bIsModified = !(draftAdminData.CreationDateTime === draftAdminData.LastChangeDateTime);
533
+ if (_bIsModified) {
534
+ performAfterDiscardorKeepDraft(processFunctionForDrafts, fnCancelFunction, oController, bSkipBindingToView);
535
+ } else {
536
+ processFunctionForDrafts();
537
+ }
538
+ } else {
539
+ fnProcessFunction();
540
+ }
541
+ })
542
+ .catch(function(oError: any) {
543
+ Log.error("Cannot retrieve draftDataContext information", oError);
544
+ });
545
+ }
546
+ }
547
+ function fnProcessDataLossConfirmation(fnProcess: Function, oControl: any, programmingModel: string) {
548
+ const bUIEditable = oControl.getModel("ui").getProperty("/isEditable"),
549
+ oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.fe.templates") as ResourceBundle,
550
+ sWarningMsg = oResourceBundle && oResourceBundle.getText("T_COMMON_UTILS_NAVIGATION_AWAY_MSG"),
551
+ sConfirmButtonTxt = oResourceBundle && oResourceBundle.getText("T_COMMON_UTILS_NAVIGATION_AWAY_CONFIRM_BUTTON"),
552
+ sCancelButtonTxt = oResourceBundle && oResourceBundle.getText("T_COMMON_UTILS_NAVIGATION_AWAY_CANCEL_BUTTON");
553
+
554
+ if (programmingModel === ProgrammingModel.Sticky && bUIEditable) {
555
+ return MessageBox.warning(sWarningMsg, {
556
+ actions: [sConfirmButtonTxt, sCancelButtonTxt],
557
+ onClose: function(sAction: any) {
558
+ if (sAction === sConfirmButtonTxt) {
559
+ const oInternalModel = oControl && oControl.getModel("internal");
560
+
561
+ Log.info("Navigation confirmed.");
562
+ if (oInternalModel) {
563
+ oInternalModel.setProperty("/sessionOn", false);
564
+ } else {
565
+ Log.warning("Local UIModel couldn't be found.");
566
+ }
567
+ fnProcess();
568
+ } else {
569
+ Log.info("Navigation rejected.");
570
+ }
571
+ }
572
+ });
573
+ }
574
+ return fnProcess();
575
+ }
576
+ function isFieldControlPathInapplicable(sFieldControlPath: string, oAttribute: any) {
577
+ let bInapplicable = false;
578
+ const aParts = sFieldControlPath.split("/");
579
+ // sensitive data is removed only if the path has already been resolved.
580
+ if (aParts.length > 1) {
581
+ bInapplicable = oAttribute[aParts[0]] && oAttribute[aParts[0]].hasOwnProperty(aParts[1]) && oAttribute[aParts[0]][aParts[1]] === 0;
582
+ } else {
583
+ bInapplicable = oAttribute[sFieldControlPath] === 0;
584
+ }
585
+ return bInapplicable;
586
+ }
587
+ function removeSensitiveData(aAttributes: any[], oMetaModel: ODataMetaModel) {
588
+ const aOutAttributes = [];
589
+ for (let i = 0; i < aAttributes.length; i++) {
590
+ const sEntitySet = aAttributes[i].entitySet,
591
+ oAttribute = aAttributes[i].contextData;
592
+
593
+ delete oAttribute["@odata.context"];
594
+ delete oAttribute["%40odata.context"];
595
+ delete oAttribute["@odata.metadataEtag"];
596
+ delete oAttribute["%40odata.metadataEtag"];
597
+ delete oAttribute["SAP__Messages"];
598
+ const aProperties = Object.keys(oAttribute);
599
+ for (let j = 0; j < aProperties.length; j++) {
600
+ const sProp = aProperties[j],
601
+ aPropertyAnnotations = oMetaModel.getObject("/" + sEntitySet + "/" + sProp + "@");
602
+ if (aPropertyAnnotations) {
603
+ if (
604
+ aPropertyAnnotations["@com.sap.vocabularies.PersonalData.v1.IsPotentiallySensitive"] ||
605
+ aPropertyAnnotations["@com.sap.vocabularies.UI.v1.ExcludeFromNavigationContext"] ||
606
+ aPropertyAnnotations["@com.sap.vocabularies.Analytics.v1.Measure"]
607
+ ) {
608
+ delete oAttribute[sProp];
609
+ } else if (aPropertyAnnotations["@com.sap.vocabularies.Common.v1.FieldControl"]) {
610
+ const oFieldControl = aPropertyAnnotations["@com.sap.vocabularies.Common.v1.FieldControl"];
611
+ if (oFieldControl["$EnumMember"] && oFieldControl["$EnumMember"].split("/")[1] === "Inapplicable") {
612
+ delete oAttribute[sProp];
613
+ } else if (oFieldControl["$Path"] && CommonUtils.isFieldControlPathInapplicable(oFieldControl["$Path"], oAttribute)) {
614
+ delete oAttribute[sProp];
615
+ }
616
+ }
617
+ }
618
+ }
619
+ aOutAttributes.push(oAttribute);
620
+ }
621
+
622
+ return aOutAttributes;
623
+ }
624
+ function _fnCheckIsMatch(oObject: any, oKeysToCheck: any) {
625
+ for (const sKey in oKeysToCheck) {
626
+ if (oKeysToCheck[sKey] !== oObject[sKey]) {
627
+ return false;
628
+ }
629
+ }
630
+ return true;
631
+ }
632
+ function fnGetContextPathProperties(oMetaModel: ODataMetaModel, sContextPath: string, oFilter?: object) {
633
+ const oEntityType = oMetaModel.getObject(sContextPath + "/") || {},
634
+ oProperties: any = {};
635
+
636
+ for (const sKey in oEntityType) {
637
+ if (
638
+ oEntityType.hasOwnProperty(sKey) &&
639
+ !/^\$/i.test(sKey) &&
640
+ oEntityType[sKey].$kind &&
641
+ _fnCheckIsMatch(oEntityType[sKey], oFilter || { $kind: "Property" })
642
+ ) {
643
+ oProperties[sKey] = oEntityType[sKey];
644
+ }
645
+ }
646
+ return oProperties;
647
+ }
648
+ function fnGetMandatoryFilterFields(oMetaModel: ODataMetaModel, sContextPath: string) {
649
+ let aMandatoryFilterFields;
650
+ if (oMetaModel && sContextPath) {
651
+ aMandatoryFilterFields = oMetaModel.getObject(sContextPath + "@Org.OData.Capabilities.V1.FilterRestrictions/RequiredProperties");
652
+ }
653
+ return aMandatoryFilterFields;
654
+ }
655
+ function fnGetIBNActions(oControl: any, aIBNActions: any[]) {
656
+ const aActions = oControl && oControl.getActions();
657
+ if (aActions) {
658
+ aActions.forEach(function(oAction: any) {
659
+ if (oAction.isA("sap.ui.mdc.actiontoolbar.ActionToolbarAction")) {
660
+ oAction = oAction.getAction();
661
+ }
662
+ if (oAction.data("IBNData")) {
663
+ aIBNActions.push(oAction);
664
+ }
665
+ });
666
+ }
667
+ return aIBNActions;
668
+ }
669
+ /**
670
+ * @param aIBNActions
671
+ * @param oView
672
+ */
673
+ function fnUpdateDataFieldForIBNButtonsVisibility(aIBNActions: any[], oView: View) {
674
+ const oParams: any = {};
675
+ const fnGetLinks = function(oData?: any) {
676
+ if (oData) {
677
+ const aKeys = Object.keys(oData);
678
+ aKeys.forEach(function(sKey: string) {
679
+ if (sKey.indexOf("_") !== 0 && sKey.indexOf("odata.context") === -1) {
680
+ oParams[sKey] = { value: oData[sKey] };
681
+ }
682
+ });
683
+ }
684
+ if (aIBNActions.length) {
685
+ aIBNActions.forEach(function(oIBNAction: any) {
686
+ const sSemanticObject = oIBNAction.data("IBNData").semanticObject;
687
+ const sAction = oIBNAction.data("IBNData").action;
688
+ CommonUtils.getShellServices(oView)
689
+ .getLinks({
690
+ semanticObject: sSemanticObject,
691
+ action: sAction,
692
+ params: oParams
693
+ })
694
+ .then(function(aLink: any) {
695
+ oIBNAction.setVisible(oIBNAction.getVisible() && aLink && aLink.length === 1);
696
+ })
697
+ .catch(function(oError: any) {
698
+ Log.error("Cannot retrieve the links from the shell service", oError);
699
+ });
700
+ });
701
+ }
702
+ };
703
+ if (oView && oView.getBindingContext()) {
704
+ (oView.getBindingContext() as any)
705
+ ?.requestObject()
706
+ .then(function(oData: any) {
707
+ return fnGetLinks(oData);
708
+ })
709
+ .catch(function(oError: any) {
710
+ Log.error("Cannot retrieve the links from the shell service", oError);
711
+ });
712
+ } else {
713
+ fnGetLinks();
714
+ }
715
+ }
716
+ function getTranslatedText(sFrameworkKey: string, oResourceBundle: ResourceBundle, oParams?: any, sEntitySetName?: string) {
717
+ let sResourceKey = sFrameworkKey;
718
+ if (oResourceBundle) {
719
+ if (sEntitySetName) {
720
+ // There are console errors logged when making calls to getText for keys that are not defined in the resource bundle
721
+ // for instance keys which are supposed to be provided by the application, e.g, <key>|<entitySet> to override instance specific text
722
+ // hence check if text exists (using "hasText") in the resource bundle before calling "getText"
723
+
724
+ // "hasText" only checks for the key in the immediate resource bundle and not it's custom bundles
725
+ // hence we need to do this recurrsively to check if the key exists in any of the bundles the forms the FE resource bundle
726
+ const bResourceKeyExists = _checkIfResourceKeyExists(
727
+ (oResourceBundle as any).aCustomBundles,
728
+ sFrameworkKey + "|" + sEntitySetName
729
+ );
730
+
731
+ // if resource key with entity set name for instance specific text overriding is provided by the application
732
+ // then use the same key otherwise use the Framework key
733
+ sResourceKey = bResourceKeyExists ? sFrameworkKey + "|" + sEntitySetName : sFrameworkKey;
734
+ }
735
+ return oResourceBundle.getText(sResourceKey, oParams);
736
+ }
737
+
738
+ // do not allow override so get text from the internal bundle directly
739
+ oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core") as ResourceBundle;
740
+ return oResourceBundle.getText(sResourceKey, oParams);
741
+ }
742
+ function _checkIfResourceKeyExists(aCustomBundles: any, sKey: any) {
743
+ if (aCustomBundles.length) {
744
+ for (let i = aCustomBundles.length - 1; i >= 0; i--) {
745
+ const sValue = aCustomBundles[i].hasText(sKey);
746
+ // text found return true
747
+ if (sValue) {
748
+ return true;
749
+ }
750
+ _checkIfResourceKeyExists(aCustomBundles[i].aCustomBundles, sKey);
751
+ }
752
+ }
753
+ return false;
754
+ }
755
+ function getActionPath(oAction: any, bReturnOnlyPath: boolean, sActionName?: string, bCheckStaticValue?: boolean) {
756
+ sActionName = !sActionName ? oAction.getObject(oAction.getPath()) : sActionName;
757
+ let sContextPath = oAction.getPath().split("/@")[0];
758
+ const sEntityTypeName = oAction.getObject(sContextPath).$Type;
759
+ const sEntityName = getEntitySetName(oAction.getModel(), sEntityTypeName);
760
+ if (sEntityName) {
761
+ sContextPath = "/" + sEntityName;
762
+ }
763
+ if (bCheckStaticValue) {
764
+ return oAction.getObject(sContextPath + "/" + sActionName + "@Org.OData.Core.V1.OperationAvailable");
765
+ }
766
+ if (bReturnOnlyPath) {
767
+ return sContextPath + "/" + sActionName;
768
+ } else {
769
+ return {
770
+ sContextPath: sContextPath,
771
+ sProperty: oAction.getObject(sContextPath + "/" + sActionName + "@Org.OData.Core.V1.OperationAvailable/$Path"),
772
+ sBindingParameter: oAction.getObject(sContextPath + "/" + sActionName + "/@$ui5.overload/0/$Parameter/0/$Name")
773
+ };
774
+ }
775
+ }
776
+ function getEntitySetName(oMetaModel: any, sEntityType: any) {
777
+ const oEntityContainer = oMetaModel.getObject("/");
778
+ for (const key in oEntityContainer) {
779
+ if (typeof oEntityContainer[key] === "object" && oEntityContainer[key].$Type === sEntityType) {
780
+ return key;
781
+ }
782
+ }
783
+ }
784
+ function computeDisplayMode(oPropertyAnnotations: any, oCollectionAnnotations?: any) {
785
+ const oTextAnnotation = oPropertyAnnotations["@com.sap.vocabularies.Common.v1.Text"],
786
+ oTextArrangementAnnotation =
787
+ oTextAnnotation &&
788
+ ((oPropertyAnnotations &&
789
+ oPropertyAnnotations["@com.sap.vocabularies.Common.v1.Text@com.sap.vocabularies.UI.v1.TextArrangement"]) ||
790
+ (oCollectionAnnotations && oCollectionAnnotations["@com.sap.vocabularies.UI.v1.TextArrangement"]));
791
+
792
+ if (oTextArrangementAnnotation) {
793
+ if (oTextArrangementAnnotation.$EnumMember === "com.sap.vocabularies.UI.v1.TextArrangementType/TextOnly") {
794
+ return "Description";
795
+ } else if (oTextArrangementAnnotation.$EnumMember === "com.sap.vocabularies.UI.v1.TextArrangementType/TextLast") {
796
+ return "ValueDescription";
797
+ } else if (oTextArrangementAnnotation.$EnumMember === "com.sap.vocabularies.UI.v1.TextArrangementType/TextSeparate") {
798
+ return "Value";
799
+ }
800
+ //Default should be TextFirst if there is a Text annotation and neither TextOnly nor TextLast are set
801
+ return "DescriptionValue";
802
+ }
803
+ return oTextAnnotation ? "DescriptionValue" : "Value";
804
+ }
805
+ function _getEntityType(oContext: any) {
806
+ const oMetaModel = oContext.getModel().getMetaModel();
807
+ return oMetaModel.getObject(oMetaModel.getMetaPath(oContext.getPath()) + "/$Type");
808
+ }
809
+ function _requestObject(sAction: any, oSelectedContext: any, sProperty: any) {
810
+ let oContext = oSelectedContext;
811
+ const nBracketIndex = sAction.indexOf("(");
812
+
813
+ if (nBracketIndex > -1) {
814
+ const sTargetType = sAction.slice(nBracketIndex + 1, -1);
815
+ let sCurrentType = _getEntityType(oContext);
816
+
817
+ while (sCurrentType !== sTargetType) {
818
+ // Find parent binding context and retrieve entity type
819
+ oContext = oContext.getBinding().getContext();
820
+ if (oContext) {
821
+ sCurrentType = _getEntityType(oContext);
822
+ } else {
823
+ Log.warning("Cannot determine target type to request property value for bound action invocation");
824
+ return Promise.resolve(undefined);
825
+ }
826
+ }
827
+ }
828
+
829
+ return oContext.requestObject(sProperty);
830
+ }
831
+ function _requestProperty(oSelectedContext: any, sAction: any, sProperty: any, sDynamicActionEnabledPath: any) {
832
+ const oPromise =
833
+ sProperty && sProperty.indexOf("/") === 0
834
+ ? requestSingletonProperty(sProperty, oSelectedContext.getModel())
835
+ : _requestObject(sAction, oSelectedContext, sProperty);
836
+
837
+ return oPromise.then(function(vPropertyValue: any) {
838
+ return Promise.resolve({
839
+ vPropertyValue: vPropertyValue,
840
+ oSelectedContext: oSelectedContext,
841
+ sAction: sAction,
842
+ sDynamicActionEnabledPath: sDynamicActionEnabledPath
843
+ });
844
+ });
845
+ }
846
+ function _setContextsBasedOnOperationAvailable(oInternalModelContext: any, aRequestPromises: any) {
847
+ return Promise.all(aRequestPromises)
848
+ .then(function(aResults: any[]) {
849
+ if (aResults.length) {
850
+ const aApplicableContexts: any[] = [],
851
+ aNotApplicableContexts: any[] = [];
852
+ aResults.forEach(function(aResult: any) {
853
+ if (aResult) {
854
+ if (aResult.vPropertyValue) {
855
+ oInternalModelContext.getModel().setProperty(aResult.sDynamicActionEnabledPath, true);
856
+ aApplicableContexts.push(aResult.oSelectedContext);
857
+ } else {
858
+ aNotApplicableContexts.push(aResult.oSelectedContext);
859
+ }
860
+ }
861
+ });
862
+ _setDynamicActionContexts(oInternalModelContext, aResults[0].sAction, aApplicableContexts, aNotApplicableContexts);
863
+ }
864
+ })
865
+ .catch(function(oError: any) {
866
+ Log.trace("Cannot retrieve property value from path", oError);
867
+ });
868
+ }
869
+ /**
870
+ * @param oInternalModelContext
871
+ * @param sAction
872
+ * @param aApplicable
873
+ * @param aNotApplicable
874
+ */
875
+ function _setDynamicActionContexts(oInternalModelContext: any, sAction: any, aApplicable: any, aNotApplicable: any) {
876
+ const sDynamicActionPathPrefix = oInternalModelContext.getPath() + "/dynamicActions/" + sAction,
877
+ oInternalModel = oInternalModelContext.getModel();
878
+ oInternalModel.setProperty(sDynamicActionPathPrefix + "/aApplicable", aApplicable);
879
+ oInternalModel.setProperty(sDynamicActionPathPrefix + "/aNotApplicable", aNotApplicable);
880
+ }
881
+ function setActionEnablement(oInternalModelContext: any, oActionOperationAvailableMap: any, aSelectedContexts: any) {
882
+ const aPromises = [];
883
+ for (const sAction in oActionOperationAvailableMap) {
884
+ // Reset all properties before computation
885
+ oInternalModelContext.setProperty("dynamicActions/" + sAction, {
886
+ bEnabled: false,
887
+ aApplicable: [],
888
+ aNotApplicable: []
889
+ });
890
+ // Note that non dynamic actions are not processed here. They are enabled because
891
+ // one or more are selected and the second part of the condition in the templating
892
+ // is then undefined and thus the button takes the default enabling, which is true!
893
+ const aApplicable = [],
894
+ aNotApplicable = [],
895
+ sProperty = oActionOperationAvailableMap[sAction],
896
+ sDynamicActionEnabledPath = oInternalModelContext.getPath() + "/dynamicActions/" + sAction + "/bEnabled";
897
+
898
+ if (typeof sProperty === "object" && sProperty !== null && sProperty !== undefined) {
899
+ for (let i = 0; i < aSelectedContexts.length; i++) {
900
+ const oSelectedContext = aSelectedContexts[i];
901
+ if (oSelectedContext) {
902
+ const oContextData = oSelectedContext.getObject();
903
+ const oTransformedBinding = transformRecursively(
904
+ sProperty,
905
+ "Binding",
906
+ // eslint-disable-next-line no-loop-func
907
+ function(oBindingExpression: any) {
908
+ return constant(oContextData[oBindingExpression.path]);
909
+ },
910
+ true
911
+ );
912
+ const sResult = compileBinding(oTransformedBinding);
913
+ if (sResult === "true") {
914
+ oInternalModelContext.getModel().setProperty(sDynamicActionEnabledPath, true);
915
+ aApplicable.push(oSelectedContext);
916
+ } else {
917
+ aNotApplicable.push(oSelectedContext);
918
+ }
919
+ }
920
+ }
921
+ _setDynamicActionContexts(oInternalModelContext, sAction, aApplicable, aNotApplicable);
922
+ } else {
923
+ const aRequestPromises = [];
924
+ for (let i = 0; i < aSelectedContexts.length; i++) {
925
+ const oSelectedContext = aSelectedContexts[i];
926
+ if (oSelectedContext) {
927
+ const oContextData = oSelectedContext.getObject();
928
+ if (sProperty === null && !!oContextData["#" + sAction]) {
929
+ //look for action advertisement if present and its value is not null
930
+ oInternalModelContext.getModel().setProperty(sDynamicActionEnabledPath, true);
931
+ break;
932
+ } else {
933
+ // Collect promises to retrieve singleton or normal property value asynchronously
934
+ aRequestPromises.push(_requestProperty(oSelectedContext, sAction, sProperty, sDynamicActionEnabledPath));
935
+ }
936
+ }
937
+ }
938
+
939
+ // When all property values have been retrieved, set
940
+ // The applicable and not-applicable selected contexts for each action and
941
+ // The enabled property of the dynamic action in internal model context.
942
+ aPromises.push(_setContextsBasedOnOperationAvailable(oInternalModelContext, aRequestPromises));
943
+ }
944
+ }
945
+ return Promise.all(aPromises);
946
+ }
947
+ function _getDefaultOperators(oRealProperty: any) {
948
+ // mdc defines the full set of operations that are meaningful for each Edm Type
949
+ const oDataClass = TypeUtil.getDataTypeClassName(oRealProperty);
950
+ const oBaseType = TypeUtil.getBaseType(oDataClass);
951
+ return FilterOperatorUtil.getOperatorsForType(oBaseType);
952
+ }
953
+ function _getRestrictions(aDefaultOps: any, aExpressionOps: any) {
954
+ // From the default set of Operators for the Base Type, select those that are defined in the Allowed Value.
955
+ // In case that no operators are found, return undefined so that the default set is used.
956
+ const aOperators = aDefaultOps.filter(function(sElement: any) {
957
+ return aExpressionOps.indexOf(sElement) > -1;
958
+ });
959
+ return aOperators.toString() || undefined;
960
+ }
961
+ function getSpecificAllowedExpression(aExpressions: any) {
962
+ const aAllowedExpressionsPriority = CommonUtils.AllowedExpressionsPrio;
963
+
964
+ aExpressions.sort(function(a: any, b: any) {
965
+ return aAllowedExpressionsPriority.indexOf(a) - aAllowedExpressionsPriority.indexOf(b);
966
+ });
967
+
968
+ return aExpressions[0];
969
+ }
970
+ function getOperatorsForProperty(
971
+ sProperty: any,
972
+ sEntitySetPath: any,
973
+ oContext: any,
974
+ sType?: any,
975
+ bUseSemanticDateRange?: any,
976
+ sSettings?: any
977
+ ) {
978
+ const oFilterRestrictions = CommonUtils.getFilterRestrictionsByPath(sEntitySetPath, oContext);
979
+ const aEqualsOps = ["EQ"];
980
+ const aSingleRangeOps = ["EQ", "GE", "LE", "LT", "GT", "BT", "NOTLE", "NOTLT", "NOTGE", "NOTGT"];
981
+ const aSingleValueDateOps = [
982
+ "TODAY",
983
+ "TOMORROW",
984
+ "YESTERDAY",
985
+ "DATE",
986
+ "FIRSTDAYWEEK",
987
+ "LASTDAYWEEK",
988
+ "FIRSTDAYMONTH",
989
+ "LASTDAYMONTH",
990
+ "FIRSTDAYQUARTER",
991
+ "LASTDAYQUARTER",
992
+ "FIRSTDAYYEAR",
993
+ "LASTDAYYEAR"
994
+ ];
995
+ const aMultiRangeOps = ["EQ", "GE", "LE", "LT", "GT", "BT", "NE", "NOTBT", "NOTLE", "NOTLT", "NOTGE", "NOTGT"];
996
+ const aSearchExpressionOps = ["Contains", "NotContains", "StartsWith", "NotStartsWith", "EndsWith", "NotEndsWith"];
997
+ const aSemanticDateOpsExt = SemanticDateOperators.getSupportedOperations();
998
+ const bSemanticDateRange = bUseSemanticDateRange === "true" || bUseSemanticDateRange === true;
999
+ let aSemanticDateOps: any[] = [];
1000
+ const oSettings = typeof sSettings === "string" ? JSON.parse(sSettings).customData : sSettings;
1001
+
1002
+ if (oContext.getObject(sEntitySetPath + "/@com.sap.vocabularies.Common.v1.ResultContext") === true) {
1003
+ return aEqualsOps.toString();
1004
+ }
1005
+
1006
+ if (oSettings && oSettings.operatorConfiguration && oSettings.operatorConfiguration.length > 0) {
1007
+ aSemanticDateOps = SemanticDateOperators.getFilterOperations(oSettings.operatorConfiguration);
1008
+ } else {
1009
+ aSemanticDateOps = SemanticDateOperators.getSemanticDateOperations();
1010
+ }
1011
+
1012
+ // Get the default Operators for this Property Type
1013
+ let aDefaultOperators = _getDefaultOperators(sType);
1014
+
1015
+ // Is there a Filter Restriction defined for this property?
1016
+ if (oFilterRestrictions && oFilterRestrictions.FilterAllowedExpressions && oFilterRestrictions.FilterAllowedExpressions[sProperty]) {
1017
+ // Extending the default operators list with Semantic Date options DATERANGE, DATE, FROM and TO
1018
+ if (bSemanticDateRange) {
1019
+ aDefaultOperators = aSemanticDateOpsExt.concat(aDefaultOperators);
1020
+ }
1021
+
1022
+ const sAllowedExpression = CommonUtils.getSpecificAllowedExpression(oFilterRestrictions.FilterAllowedExpressions[sProperty]);
1023
+ let sRestrictions;
1024
+ // In case more than one Allowed Expressions has been defined for a property
1025
+ // choose the most restrictive Allowed Expression
1026
+
1027
+ // MultiValue has same Operator as SingleValue, but there can be more than one (maxConditions)
1028
+ switch (sAllowedExpression) {
1029
+ case "SingleValue":
1030
+ const aSingleValueOps = sType === "Edm.Date" && bSemanticDateRange ? aSingleValueDateOps : aEqualsOps;
1031
+ sRestrictions = _getRestrictions(aDefaultOperators, aSingleValueOps);
1032
+ break;
1033
+ case "MultiValue":
1034
+ sRestrictions = _getRestrictions(aDefaultOperators, aEqualsOps);
1035
+ break;
1036
+ case "SingleRange":
1037
+ const sOperators = _getRestrictions(
1038
+ aDefaultOperators,
1039
+ sType === "Edm.Date" && bSemanticDateRange ? aSemanticDateOps : aSingleRangeOps
1040
+ );
1041
+ sRestrictions = sOperators ? sOperators : "";
1042
+ break;
1043
+ case "MultiRange":
1044
+ sRestrictions = _getRestrictions(aDefaultOperators, aMultiRangeOps);
1045
+ break;
1046
+ case "SearchExpression":
1047
+ sRestrictions = _getRestrictions(aDefaultOperators, aSearchExpressionOps);
1048
+ break;
1049
+ case "MultiRangeOrSearchExpression":
1050
+ sRestrictions = _getRestrictions(aDefaultOperators, aSearchExpressionOps.concat(aMultiRangeOps));
1051
+ break;
1052
+
1053
+ default:
1054
+ break;
1055
+ }
1056
+ // In case AllowedExpressions is not recognised, undefined in return results in the default set of
1057
+ // operators for the type.
1058
+ return sRestrictions;
1059
+ } else if (sType === "Edm.Date") {
1060
+ // In case AllowedExpressions is not provided for type Edm.Date then all the default
1061
+ // operators for the type should be returned excluding semantic operators from the list.
1062
+ aSemanticDateOps = SemanticDateOperators.getSemanticDateOperations();
1063
+ const aOperators = aDefaultOperators.filter(function(sElement: any) {
1064
+ return aSemanticDateOps.indexOf(sElement) < 0;
1065
+ });
1066
+ return aOperators.toString();
1067
+ }
1068
+ }
1069
+ function getParameterInfo(oMetaModel: any, sContextPath: any) {
1070
+ const sParameterContextPath = sContextPath.substring(0, sContextPath.lastIndexOf("/"));
1071
+ const bResultContext = oMetaModel.getObject(sParameterContextPath + "/@com.sap.vocabularies.Common.v1.ResultContext");
1072
+ const oParameterInfo: any = {};
1073
+ if (bResultContext && sParameterContextPath !== sContextPath) {
1074
+ oParameterInfo.contextPath = sParameterContextPath;
1075
+ oParameterInfo.parameterProperties = CommonUtils.getContextPathProperties(oMetaModel, sParameterContextPath);
1076
+ }
1077
+ return oParameterInfo;
1078
+ }
1079
+ function addSelectOptionToConditions(oPropertyMetadata: any, aValidOperators: any, aCumulativeConditions: any, oSelectOption: any) {
1080
+ const oCondition = getConditions(oSelectOption, oPropertyMetadata);
1081
+ if (oCondition) {
1082
+ if (!aValidOperators || aValidOperators.indexOf(oCondition.operator) > -1) {
1083
+ aCumulativeConditions.push(oCondition);
1084
+ }
1085
+ }
1086
+ return aCumulativeConditions;
1087
+ }
1088
+ /**
1089
+ * @param sContextPath
1090
+ * @param oSelectionVariant
1091
+ * @param sSelectOptionProp
1092
+ * @param oConditions
1093
+ * @param sConditionPath
1094
+ * @param sConditionProp
1095
+ * @param oValidProperties
1096
+ * @param oMetaModel
1097
+ * @param isParameter
1098
+ */
1099
+ function addSelectOptionsToConditions(
1100
+ sContextPath: any,
1101
+ oSelectionVariant: any,
1102
+ sSelectOptionProp: any,
1103
+ oConditions: any,
1104
+ sConditionPath: any,
1105
+ sConditionProp: any,
1106
+ oValidProperties: any,
1107
+ oMetaModel: any,
1108
+ isParameter: any
1109
+ ) {
1110
+ let aConditions: any[] = [],
1111
+ aSelectOptions,
1112
+ aValidOperators;
1113
+
1114
+ if (isParameter || CommonUtils.isPropertyFilterable(oMetaModel, sContextPath, sConditionProp, true)) {
1115
+ aSelectOptions = oSelectionVariant.getSelectOption(sSelectOptionProp);
1116
+ aValidOperators = isParameter ? ["EQ"] : CommonUtils.getOperatorsForProperty(sConditionProp, sContextPath, oMetaModel);
1117
+ const oPropertyMetadata = oValidProperties[sConditionProp];
1118
+ // Create conditions for all the selectOptions of the property
1119
+ aConditions = isParameter
1120
+ ? addSelectOptionToConditions(oPropertyMetadata, aValidOperators, aConditions, aSelectOptions[0])
1121
+ : aSelectOptions.reduce(addSelectOptionToConditions.bind(null, oPropertyMetadata, aValidOperators), aConditions);
1122
+ if (aConditions.length) {
1123
+ if (sConditionPath) {
1124
+ oConditions[sConditionPath + sConditionProp] = oConditions.hasOwnProperty(sConditionPath + sConditionProp)
1125
+ ? oConditions[sConditionPath + sConditionProp].concat(aConditions)
1126
+ : aConditions;
1127
+ } else {
1128
+ oConditions[sConditionProp] = oConditions.hasOwnProperty(sConditionProp)
1129
+ ? oConditions[sConditionProp].concat(aConditions)
1130
+ : aConditions;
1131
+ }
1132
+ }
1133
+ }
1134
+ }
1135
+
1136
+ function addSelectionVariantToConditions(oSelectionVariant: any, oConditions: object, oMetaModel: ODataMetaModel, sContextPath: string) {
1137
+ const aSelectOptionsPropertyNames = oSelectionVariant.getSelectOptionsPropertyNames(),
1138
+ oValidProperties = CommonUtils.getContextPathProperties(oMetaModel, sContextPath),
1139
+ aMetadatProperties = Object.keys(oValidProperties),
1140
+ oParameterInfo = CommonUtils.getParameterInfo(oMetaModel, sContextPath),
1141
+ sParameterContextPath = oParameterInfo.contextPath,
1142
+ oValidParameterProperties = oParameterInfo.parameterProperties,
1143
+ bHasParameters = !!oParameterInfo.contextPath && oValidParameterProperties && Object.keys(oValidParameterProperties).length > 0;
1144
+
1145
+ if (bHasParameters) {
1146
+ const aMetadataParameters = Object.keys(oValidParameterProperties);
1147
+ aMetadataParameters.forEach(function(sMetadataParameter: string) {
1148
+ let sSelectOptionName;
1149
+ if (aSelectOptionsPropertyNames.includes("$Parameter." + sMetadataParameter)) {
1150
+ sSelectOptionName = "$Parameter." + sMetadataParameter;
1151
+ } else if (aSelectOptionsPropertyNames.includes(sMetadataParameter)) {
1152
+ sSelectOptionName = sMetadataParameter;
1153
+ } else if (
1154
+ sMetadataParameter.startsWith("P_") &&
1155
+ aSelectOptionsPropertyNames.includes("$Parameter." + sMetadataParameter.slice(2, sMetadataParameter.length))
1156
+ ) {
1157
+ sSelectOptionName = "$Parameter." + sMetadataParameter.slice(2, sMetadataParameter.length);
1158
+ } else if (
1159
+ sMetadataParameter.startsWith("P_") &&
1160
+ aSelectOptionsPropertyNames.includes(sMetadataParameter.slice(2, sMetadataParameter.length))
1161
+ ) {
1162
+ sSelectOptionName = sMetadataParameter.slice(2, sMetadataParameter.length);
1163
+ } else if (aSelectOptionsPropertyNames.includes("$Parameter.P_" + sMetadataParameter)) {
1164
+ sSelectOptionName = "$Parameter.P_" + sMetadataParameter;
1165
+ } else if (aSelectOptionsPropertyNames.includes("P_" + sMetadataParameter)) {
1166
+ sSelectOptionName = "P_" + sMetadataParameter;
1167
+ }
1168
+
1169
+ if (sSelectOptionName) {
1170
+ addSelectOptionsToConditions(
1171
+ sParameterContextPath,
1172
+ oSelectionVariant,
1173
+ sSelectOptionName,
1174
+ oConditions,
1175
+ undefined,
1176
+ sMetadataParameter,
1177
+ oValidParameterProperties,
1178
+ oMetaModel,
1179
+ true
1180
+ );
1181
+ }
1182
+ });
1183
+ }
1184
+ aMetadatProperties.forEach(function(sMetadataProperty: string) {
1185
+ let sSelectOptionName;
1186
+ if (aSelectOptionsPropertyNames.includes(sMetadataProperty)) {
1187
+ sSelectOptionName = sMetadataProperty;
1188
+ } else if (
1189
+ sMetadataProperty.startsWith("P_") &&
1190
+ aSelectOptionsPropertyNames.includes(sMetadataProperty.slice(2, sMetadataProperty.length))
1191
+ ) {
1192
+ sSelectOptionName = sMetadataProperty.slice(2, sMetadataProperty.length);
1193
+ } else if (aSelectOptionsPropertyNames.includes("P_" + sMetadataProperty)) {
1194
+ sSelectOptionName = "P_" + sMetadataProperty;
1195
+ }
1196
+ if (sSelectOptionName) {
1197
+ addSelectOptionsToConditions(
1198
+ sContextPath,
1199
+ oSelectionVariant,
1200
+ sSelectOptionName,
1201
+ oConditions,
1202
+ undefined,
1203
+ sMetadataProperty,
1204
+ oValidProperties,
1205
+ oMetaModel,
1206
+ false
1207
+ );
1208
+ }
1209
+ });
1210
+
1211
+ aSelectOptionsPropertyNames.forEach(function(sSelectOption: any) {
1212
+ if (sSelectOption.indexOf(".") > 0 && !sSelectOption.includes("$Parameter")) {
1213
+ const sFullContextPath = ("/" + sSelectOption.replaceAll(".", "/")).startsWith(sContextPath)
1214
+ ? "/" + sSelectOption.replaceAll(".", "/")
1215
+ : sContextPath + "/" + sSelectOption.replaceAll(".", "/"); // check if the full path, eg SalesOrderManage._Item.Material exists in the metamodel
1216
+ if (oMetaModel.getObject(sFullContextPath.replace("P_", ""))) {
1217
+ _createConditionsForNavProperties(
1218
+ sFullContextPath,
1219
+ sContextPath,
1220
+ oSelectionVariant,
1221
+ sSelectOption,
1222
+ oMetaModel,
1223
+ oConditions
1224
+ );
1225
+ }
1226
+ }
1227
+ });
1228
+ return oConditions;
1229
+ }
1230
+ /**
1231
+ * @param sFullContextPath
1232
+ * @param sMainEntitySetPath
1233
+ * @param oSelectionVariant
1234
+ * @param sSelectOption
1235
+ * @param oMetaModel
1236
+ * @param oConditions
1237
+ */
1238
+ function _createConditionsForNavProperties(
1239
+ sFullContextPath: any,
1240
+ sMainEntitySetPath: any,
1241
+ oSelectionVariant: any,
1242
+ sSelectOption: any,
1243
+ oMetaModel: any,
1244
+ oConditions: any
1245
+ ) {
1246
+ let aNavObjectNames = sSelectOption.split(".");
1247
+ // Eg: "SalesOrderManage._Item._Material.Material" or "_Item.Material"
1248
+ if (("/" + sSelectOption.replaceAll(".", "/")).startsWith(sMainEntitySetPath)) {
1249
+ const sFullPath = (("/" + sSelectOption) as any).replaceAll(".", "/"),
1250
+ sNavPath = sFullPath.replace(sMainEntitySetPath + "/", "");
1251
+ aNavObjectNames = sNavPath.split("/");
1252
+ }
1253
+ let sConditionPath = "";
1254
+ const sPropertyName = aNavObjectNames[aNavObjectNames.length - 1]; // Material from SalesOrderManage._Item.Material
1255
+ for (let i = 0; i < aNavObjectNames.length - 1; i++) {
1256
+ if (oMetaModel.getObject(sMainEntitySetPath + "/" + aNavObjectNames[i].replace("P_", "")).$isCollection) {
1257
+ sConditionPath = sConditionPath + aNavObjectNames[i] + "*/"; // _Item*/ in case of 1:n cardinality
1258
+ } else {
1259
+ sConditionPath = sConditionPath + aNavObjectNames[i] + "/"; // _Item/ in case of 1:1 cardinality
1260
+ }
1261
+ sMainEntitySetPath = sMainEntitySetPath + "/" + aNavObjectNames[i];
1262
+ }
1263
+ const sNavPropertyPath = sFullContextPath.slice(0, sFullContextPath.lastIndexOf("/")),
1264
+ oValidProperties = CommonUtils.getContextPathProperties(oMetaModel, sNavPropertyPath),
1265
+ aSelectOptionsPropertyNames = oSelectionVariant.getSelectOptionsPropertyNames();
1266
+ let sSelectOptionName = sPropertyName;
1267
+ if (oValidProperties[sPropertyName]) {
1268
+ sSelectOptionName = sPropertyName;
1269
+ } else if (sPropertyName.startsWith("P_") && oValidProperties[sPropertyName.replace("P_", "")]) {
1270
+ sSelectOptionName = sPropertyName.replace("P_", "");
1271
+ } else if (oValidProperties["P_" + sPropertyName] && aSelectOptionsPropertyNames.includes("P_" + sPropertyName)) {
1272
+ sSelectOptionName = "P_" + sPropertyName;
1273
+ }
1274
+ if (sPropertyName.startsWith("P_") && oConditions[sConditionPath + sSelectOptionName]) {
1275
+ // if there is no SalesOrderManage._Item.Material yet in the oConditions
1276
+ return;
1277
+ } else if (!sPropertyName.startsWith("P_") && oConditions[sConditionPath + sSelectOptionName]) {
1278
+ delete oConditions[sConditionPath + sSelectOptionName];
1279
+ addSelectOptionsToConditions(
1280
+ sNavPropertyPath,
1281
+ oSelectionVariant,
1282
+ sSelectOption,
1283
+ oConditions,
1284
+ sConditionPath,
1285
+ sSelectOptionName,
1286
+ oValidProperties,
1287
+ oMetaModel,
1288
+ false
1289
+ );
1290
+ } else {
1291
+ addSelectOptionsToConditions(
1292
+ sNavPropertyPath,
1293
+ oSelectionVariant,
1294
+ sSelectOption,
1295
+ oConditions,
1296
+ sConditionPath,
1297
+ sSelectOptionName,
1298
+ oValidProperties,
1299
+ oMetaModel,
1300
+ false
1301
+ );
1302
+ }
1303
+ }
1304
+ function addPageContextToSelectionVariant(oSelectionVariant: any, mPageContext: any[], oView: any) {
1305
+ const oAppComponent = CommonUtils.getAppComponent(oView);
1306
+ const oNavigationService = oAppComponent.getNavigationService();
1307
+ return oNavigationService.mixAttributesAndSelectionVariant(mPageContext, oSelectionVariant.toJSONString());
1308
+ }
1309
+ function addExternalStateFiltersToSelectionVariant(oSelectionVariant: any, mFilters: any, oTargetInfo: any, oFilterInfo?: any) {
1310
+ let sFilter: any,
1311
+ sLow = "",
1312
+ sHigh = null;
1313
+ const fnGetSignAndOption = function(sOperator: any, sLowValue: any, sHighValue: any) {
1314
+ const oSelectOptionState = {
1315
+ option: "",
1316
+ sign: "I",
1317
+ low: sLowValue,
1318
+ high: sHighValue
1319
+ };
1320
+ switch (sOperator) {
1321
+ case "Contains":
1322
+ oSelectOptionState.option = "CP";
1323
+ break;
1324
+ case "StartsWith":
1325
+ oSelectOptionState.option = "CP";
1326
+ oSelectOptionState.low += "*";
1327
+ break;
1328
+ case "EndsWith":
1329
+ oSelectOptionState.option = "CP";
1330
+ oSelectOptionState.low = "*" + oSelectOptionState.low;
1331
+ break;
1332
+ case "BT":
1333
+ case "LE":
1334
+ case "LT":
1335
+ case "GT":
1336
+ case "NE":
1337
+ case "EQ":
1338
+ oSelectOptionState.option = sOperator;
1339
+ break;
1340
+ case "TODAY":
1341
+ case "DATE":
1342
+ oSelectOptionState.option = "EQ";
1343
+ break;
1344
+ case "EEQ":
1345
+ oSelectOptionState.option = "EQ";
1346
+ break;
1347
+ case "Empty":
1348
+ oSelectOptionState.option = "EQ";
1349
+ oSelectOptionState.low = "";
1350
+ break;
1351
+ case "NotContains":
1352
+ oSelectOptionState.option = "CP";
1353
+ oSelectOptionState.sign = "E";
1354
+ break;
1355
+ case "NOTBT":
1356
+ oSelectOptionState.option = "BT";
1357
+ oSelectOptionState.sign = "E";
1358
+ break;
1359
+ case "NotStartsWith":
1360
+ oSelectOptionState.option = "CP";
1361
+ oSelectOptionState.low += "*";
1362
+ oSelectOptionState.sign = "E";
1363
+ break;
1364
+ case "NotEndsWith":
1365
+ oSelectOptionState.option = "CP";
1366
+ oSelectOptionState.low = "*" + oSelectOptionState.low;
1367
+ oSelectOptionState.sign = "E";
1368
+ break;
1369
+ case "NotEmpty":
1370
+ oSelectOptionState.option = "NE";
1371
+ oSelectOptionState.low = "";
1372
+ break;
1373
+ case "NOTLE":
1374
+ oSelectOptionState.option = "LE";
1375
+ oSelectOptionState.sign = "E";
1376
+ break;
1377
+ case "NOTGE":
1378
+ oSelectOptionState.option = "GE";
1379
+ oSelectOptionState.sign = "E";
1380
+ break;
1381
+ case "NOTLT":
1382
+ oSelectOptionState.option = "LT";
1383
+ oSelectOptionState.sign = "E";
1384
+ break;
1385
+ case "NOTGT":
1386
+ oSelectOptionState.option = "GT";
1387
+ oSelectOptionState.sign = "E";
1388
+ break;
1389
+ default:
1390
+ Log.warning(sOperator + " is not supported. " + sFilter + " could not be added to the navigation context");
1391
+ }
1392
+ return oSelectOptionState;
1393
+ };
1394
+ const oFilterConditions = mFilters.filterConditions;
1395
+ const oFiltersWithoutConflict = mFilters.filterConditionsWithoutConflict ? mFilters.filterConditionsWithoutConflict : {};
1396
+ const oTablePropertiesWithoutConflict = oTargetInfo.propertiesWithoutConflict ? oTargetInfo.propertiesWithoutConflict : {};
1397
+ const addFiltersToSelectionVariant = function(oSelectionVariant: any, sFilterName: any, sPath?: any) {
1398
+ const aFilters = oFilterConditions[sFilterName];
1399
+ for (const item in aFilters) {
1400
+ const oFilter = aFilters[item];
1401
+ sLow = (oFilter.values[0] && oFilter.values[0].toString()) || "";
1402
+ sHigh = (oFilter.values[1] && oFilter.values[1].toString()) || null;
1403
+ if (oFilter.operator === "TODAY" || oFilter.operator === "DATE") {
1404
+ const aFilter = oFilterInfo[0].aFilters.filter(function(oFilter: any) {
1405
+ return oFilter.sPath === sFilterName;
1406
+ });
1407
+ sLow = aFilter[0].oValue1 || "";
1408
+ sHigh = null;
1409
+ }
1410
+ const oSelectOptionValues = fnGetSignAndOption(oFilter.operator, sLow, sHigh);
1411
+ if (oSelectOptionValues.option) {
1412
+ oSelectionVariant.addSelectOption(
1413
+ sPath ? sPath : sFilterName,
1414
+ oSelectOptionValues.sign,
1415
+ oSelectOptionValues.option,
1416
+ oSelectOptionValues.low,
1417
+ oSelectOptionValues.high
1418
+ );
1419
+ }
1420
+ }
1421
+ };
1422
+
1423
+ for (sFilter in oFilterConditions) {
1424
+ // only add the filter values if it is not already present in the SV already
1425
+ if (!oSelectionVariant.getSelectOption(sFilter)) {
1426
+ // TODO : custom filters should be ignored more generically
1427
+ if (sFilter === "$editState") {
1428
+ continue;
1429
+ }
1430
+ addFiltersToSelectionVariant(oSelectionVariant, sFilter);
1431
+ } else {
1432
+ if (oTablePropertiesWithoutConflict && sFilter in oTablePropertiesWithoutConflict) {
1433
+ addFiltersToSelectionVariant(oSelectionVariant, sFilter, oTablePropertiesWithoutConflict[sFilter]);
1434
+ }
1435
+ // if property was without conflict in page context then add path from page context to SV
1436
+ if (sFilter in oFiltersWithoutConflict) {
1437
+ addFiltersToSelectionVariant(oSelectionVariant, sFilter, oFiltersWithoutConflict[sFilter]);
1438
+ }
1439
+ }
1440
+ }
1441
+ return oSelectionVariant;
1442
+ }
1443
+ function isStickyEditMode(oControl: Control) {
1444
+ const bIsStickyMode = ModelHelper.isStickySessionSupported((oControl.getModel() as ODataModel).getMetaModel());
1445
+ const bUIEditable = oControl.getModel("ui").getProperty("/isEditable");
1446
+ return bIsStickyMode && bUIEditable;
1447
+ }
1448
+ /**
1449
+ * @param aMandatoryFilterFields
1450
+ * @param oSelectionVariant
1451
+ * @param oSelectionVariantDefaults
1452
+ */
1453
+ function addDefaultDisplayCurrency(aMandatoryFilterFields: any[], oSelectionVariant: any, oSelectionVariantDefaults: any) {
1454
+ if (oSelectionVariant && aMandatoryFilterFields && aMandatoryFilterFields.length) {
1455
+ for (let i = 0; i < aMandatoryFilterFields.length; i++) {
1456
+ const aSVOption = oSelectionVariant.getSelectOption("DisplayCurrency"),
1457
+ aDefaultSVOption = oSelectionVariantDefaults && oSelectionVariantDefaults.getSelectOption("DisplayCurrency");
1458
+ if (
1459
+ aMandatoryFilterFields[i].$PropertyPath === "DisplayCurrency" &&
1460
+ (!aSVOption || !aSVOption.length) &&
1461
+ aDefaultSVOption &&
1462
+ aDefaultSVOption.length
1463
+ ) {
1464
+ const displayCurrencySelectOption = aDefaultSVOption[0];
1465
+ const sSign = displayCurrencySelectOption["Sign"];
1466
+ const sOption = displayCurrencySelectOption["Option"];
1467
+ const sLow = displayCurrencySelectOption["Low"];
1468
+ const sHigh = displayCurrencySelectOption["High"];
1469
+ oSelectionVariant.addSelectOption("DisplayCurrency", sSign, sOption, sLow, sHigh);
1470
+ }
1471
+ }
1472
+ }
1473
+ }
1474
+ function getNonComputedVisibleFields(oMetaModel: ODataMetaModel, sPath: any, oView?: any) {
1475
+ const aTechnicalKeys = oMetaModel.getObject(sPath + "/").$Key;
1476
+ const aNonComputedVisibleFields = [];
1477
+ const oEntityType = oMetaModel.getObject(sPath + "/");
1478
+ for (const item in oEntityType) {
1479
+ if (oEntityType[item].$kind && oEntityType[item].$kind === "Property") {
1480
+ const oAnnotations = oMetaModel.getObject(sPath + "/" + item + "@") || {},
1481
+ bIsKey = aTechnicalKeys.indexOf(item) > -1,
1482
+ bIsImmutable = oAnnotations["@Org.OData.Core.V1.Immutable"],
1483
+ bIsNonComputed = !oAnnotations["@Org.OData.Core.V1.Computed"],
1484
+ bIsVisible = !oAnnotations["@com.sap.vocabularies.UI.v1.Hidden"],
1485
+ bIsComputedDefaultValue = oAnnotations["@Org.OData.Core.V1.ComputedDefaultValue"],
1486
+ bIsKeyComputedDefaultValueWithText =
1487
+ bIsKey && oEntityType[item].$Type === "Edm.Guid"
1488
+ ? bIsComputedDefaultValue && oAnnotations["@com.sap.vocabularies.Common.v1.Text"]
1489
+ : false;
1490
+ if (
1491
+ (bIsImmutable || bIsKeyComputedDefaultValueWithText || (bIsKey && oEntityType[item].$Type !== "Edm.Guid")) &&
1492
+ bIsNonComputed &&
1493
+ bIsVisible
1494
+ ) {
1495
+ aNonComputedVisibleFields.push(item);
1496
+ }
1497
+
1498
+ if (!bIsNonComputed && bIsComputedDefaultValue && oView) {
1499
+ const oDiagnostics = getAppComponent(oView).getDiagnostics();
1500
+ const sMessage = "Core.ComputedDefaultValue is ignored as Core.Computed is already set to true";
1501
+ oDiagnostics.addIssue(
1502
+ IssueCategory.Annotation,
1503
+ IssueSeverity.Medium,
1504
+ sMessage,
1505
+ IssueCategoryType,
1506
+ IssueCategoryType?.Annotations?.IgnoredAnnotation
1507
+ );
1508
+ }
1509
+ }
1510
+ }
1511
+ return aNonComputedVisibleFields;
1512
+ }
1513
+ function setUserDefaults(
1514
+ oAppComponent: AppComponent,
1515
+ aParameters: any[],
1516
+ oModel: JSONModel,
1517
+ bIsAction: boolean,
1518
+ bIsCreate?: boolean,
1519
+ oActionDefaultValues?: any
1520
+ ) {
1521
+ return new Promise(function(resolve: (value: any) => void) {
1522
+ const oComponentData = oAppComponent.getComponentData(),
1523
+ oStartupParameters = (oComponentData && oComponentData.startupParameters) || {},
1524
+ oShellServices = oAppComponent.getShellServices();
1525
+ if (!oShellServices.hasUShell()) {
1526
+ aParameters.forEach(function(oParameter: any) {
1527
+ const sPropertyName = bIsAction
1528
+ ? "/" + oParameter.$Name
1529
+ : oParameter.getPath().slice(oParameter.getPath().lastIndexOf("/") + 1);
1530
+ const sParameterName = bIsAction ? sPropertyName.slice(1) : sPropertyName;
1531
+ if (oActionDefaultValues && bIsCreate) {
1532
+ if (oActionDefaultValues[sParameterName]) {
1533
+ oModel.setProperty(sPropertyName, oActionDefaultValues[sParameterName]);
1534
+ }
1535
+ } else if (oStartupParameters[sParameterName]) {
1536
+ oModel.setProperty(sPropertyName, oStartupParameters[sParameterName][0]);
1537
+ }
1538
+ });
1539
+ return resolve(true);
1540
+ }
1541
+ return oShellServices.getStartupAppState(oAppComponent).then(function(oStartupAppState: any) {
1542
+ const oData = oStartupAppState.getData() || {},
1543
+ aExtendedParameters = (oData.selectionVariant && oData.selectionVariant.SelectOptions) || [];
1544
+ aParameters.forEach(function(oParameter: any) {
1545
+ const sPropertyName = bIsAction
1546
+ ? "/" + oParameter.$Name
1547
+ : oParameter.getPath().slice(oParameter.getPath().lastIndexOf("/") + 1);
1548
+ const sParameterName = bIsAction ? sPropertyName.slice(1) : sPropertyName;
1549
+ if (oActionDefaultValues && bIsCreate) {
1550
+ if (oActionDefaultValues[sParameterName]) {
1551
+ oModel.setProperty(sPropertyName, oActionDefaultValues[sParameterName]);
1552
+ }
1553
+ } else if (oStartupParameters[sParameterName]) {
1554
+ oModel.setProperty(sPropertyName, oStartupParameters[sParameterName][0]);
1555
+ } else if (aExtendedParameters.length > 0) {
1556
+ for (const i in aExtendedParameters) {
1557
+ const oExtendedParameter = aExtendedParameters[i];
1558
+ if (oExtendedParameter.PropertyName === sParameterName) {
1559
+ const oRange = oExtendedParameter.Ranges.length ? oExtendedParameter.Ranges[0] : undefined;
1560
+ if (oRange && oRange.Sign === "I" && oRange.Option === "EQ") {
1561
+ oModel.setProperty(sPropertyName, oRange.Low); // high is ignored when Option=EQ
1562
+ }
1563
+ }
1564
+ }
1565
+ }
1566
+ });
1567
+ return resolve(true);
1568
+ });
1569
+ });
1570
+ }
1571
+ function getAdditionalParamsForCreate(oStartupParameters: any, oInboundParameters: any) {
1572
+ const oInbounds = oInboundParameters,
1573
+ aCreateParameters = oInbounds
1574
+ ? Object.keys(oInbounds).filter(function(sParameter: string) {
1575
+ return oInbounds[sParameter].useForCreate;
1576
+ })
1577
+ : [];
1578
+ let oRet;
1579
+ for (let i = 0; i < aCreateParameters.length; i++) {
1580
+ const sCreateParameter = aCreateParameters[i];
1581
+ const aValues = oStartupParameters && oStartupParameters[sCreateParameter];
1582
+ if (aValues && aValues.length === 1) {
1583
+ oRet = oRet || Object.create(null);
1584
+ oRet[sCreateParameter] = aValues[0];
1585
+ }
1586
+ }
1587
+ return oRet;
1588
+ }
1589
+ function getSemanticObjectMapping(oOutbound: any) {
1590
+ const aSemanticObjectMapping: any[] = [];
1591
+ if (oOutbound.parameters) {
1592
+ const aParameters = Object.keys(oOutbound.parameters) || [];
1593
+ if (aParameters.length > 0) {
1594
+ aParameters.forEach(function(sParam: string) {
1595
+ const oMapping = oOutbound.parameters[sParam];
1596
+ if (oMapping.value && oMapping.value.value && oMapping.value.format === "binding") {
1597
+ // using the format of UI.Mapping
1598
+ const oSemanticMapping = {
1599
+ "LocalProperty": {
1600
+ "$PropertyPath": oMapping.value.value
1601
+ },
1602
+ "SemanticObjectProperty": sParam
1603
+ };
1604
+
1605
+ if (aSemanticObjectMapping.length > 0) {
1606
+ // To check if the semanticObject Mapping is done for the same local property more that once then first one will be considered
1607
+ for (let i = 0; i < aSemanticObjectMapping.length; i++) {
1608
+ if (
1609
+ aSemanticObjectMapping[i]["LocalProperty"]["$PropertyPath"] !==
1610
+ oSemanticMapping["LocalProperty"]["$PropertyPath"]
1611
+ ) {
1612
+ aSemanticObjectMapping.push(oSemanticMapping);
1613
+ }
1614
+ }
1615
+ } else {
1616
+ aSemanticObjectMapping.push(oSemanticMapping);
1617
+ }
1618
+ }
1619
+ });
1620
+ }
1621
+ }
1622
+ return aSemanticObjectMapping;
1623
+ }
1624
+ function getHeaderFacetItemConfigForExternalNavigation(oViewData: any, oCrossNav: any) {
1625
+ const oHeaderFacetItems: any = {};
1626
+ let sId;
1627
+ const oControlConfig = oViewData.controlConfiguration;
1628
+ for (const config in oControlConfig) {
1629
+ if (config.indexOf("@com.sap.vocabularies.UI.v1.DataPoint") > -1 || config.indexOf("@com.sap.vocabularies.UI.v1.Chart") > -1) {
1630
+ if (
1631
+ oControlConfig[config].navigation &&
1632
+ oControlConfig[config].navigation.targetOutbound &&
1633
+ oControlConfig[config].navigation.targetOutbound.outbound
1634
+ ) {
1635
+ const sOutbound = oControlConfig[config].navigation.targetOutbound.outbound;
1636
+ const oOutbound = oCrossNav[sOutbound];
1637
+ if (oOutbound.semanticObject && oOutbound.action) {
1638
+ if (config.indexOf("Chart") > -1) {
1639
+ sId = generate(["fe", "MicroChartLink", config]);
1640
+ } else {
1641
+ sId = generate(["fe", "HeaderDPLink", config]);
1642
+ }
1643
+ const aSemanticObjectMapping = CommonUtils.getSemanticObjectMapping(oOutbound);
1644
+ oHeaderFacetItems[sId] = {
1645
+ semanticObject: oOutbound.semanticObject,
1646
+ action: oOutbound.action,
1647
+ semanticObjectMapping: aSemanticObjectMapping
1648
+ };
1649
+ } else {
1650
+ Log.error("Cross navigation outbound is configured without semantic object and action for " + sOutbound);
1651
+ }
1652
+ }
1653
+ }
1654
+ }
1655
+ return oHeaderFacetItems;
1656
+ }
1657
+ function setSemanticObjectMappings(oSelectionVariant: any, vMappings: object) {
1658
+ const oMappings = typeof vMappings === "string" ? JSON.parse(vMappings) : vMappings;
1659
+ for (let i = 0; i < oMappings.length; i++) {
1660
+ const sLocalProperty =
1661
+ (oMappings[i]["LocalProperty"] && oMappings[i]["LocalProperty"]["$PropertyPath"]) ||
1662
+ (oMappings[i]["@com.sap.vocabularies.Common.v1.LocalProperty"] &&
1663
+ oMappings[i]["@com.sap.vocabularies.Common.v1.LocalProperty"]["$Path"]);
1664
+ const sSemanticObjectProperty =
1665
+ oMappings[i]["SemanticObjectProperty"] || oMappings[i]["@com.sap.vocabularies.Common.v1.SemanticObjectProperty"];
1666
+ if (oSelectionVariant.getSelectOption(sLocalProperty)) {
1667
+ const oSelectOption = oSelectionVariant.getSelectOption(sLocalProperty);
1668
+
1669
+ //Create a new SelectOption with sSemanticObjectProperty as the property Name and remove the older one
1670
+ oSelectionVariant.removeSelectOption(sLocalProperty);
1671
+ oSelectionVariant.massAddSelectOption(sSemanticObjectProperty, oSelectOption);
1672
+ }
1673
+ }
1674
+ return oSelectionVariant;
1675
+ }
1676
+ function fnGetSemanticObjectsFromPath(oMetaModel: any, sPath: any) {
1677
+ return new Promise(function(resolve: (value: any) => void) {
1678
+ const sSemanticObject = oMetaModel.getObject(sPath + "@com.sap.vocabularies.Common.v1.SemanticObject");
1679
+ const aSemanticObjectUnavailableActions = oMetaModel.getObject(
1680
+ sPath + "@com.sap.vocabularies.Common.v1.SemanticObjectUnavailableActions"
1681
+ );
1682
+ const aSemanticObjectForGetLinks = [{ semanticObject: sSemanticObject }];
1683
+ const oSemanticObject = {
1684
+ semanticObject: sSemanticObject
1685
+ };
1686
+ resolve({
1687
+ semanticObjectPath: sPath,
1688
+ semanticObjectForGetLinks: aSemanticObjectForGetLinks,
1689
+ semanticObject: oSemanticObject,
1690
+ unavailableActions: aSemanticObjectUnavailableActions
1691
+ });
1692
+ }).catch(function(oError: any) {
1693
+ Log.error("Error in fnGetSemanticObjectsFromPath", oError);
1694
+ });
1695
+ }
1696
+ function fnUpdateSemanticTargetsModel(aGetLinksPromises: any, aSemanticObjects: any, oInternalModelContext: any, sCurrentHash: any) {
1697
+ return Promise.all(aGetLinksPromises)
1698
+ .then(function(aValues: any[]) {
1699
+ let aLinks,
1700
+ _oLink,
1701
+ _sLinkIntentAction,
1702
+ aFinalLinks: any[] = [];
1703
+ let oFinalSemanticObjects: any = {};
1704
+ const bIntentHasActions = function(sIntent: any, aActions: any) {
1705
+ for (const intent in aActions) {
1706
+ if (intent === sIntent) {
1707
+ return true;
1708
+ } else {
1709
+ return false;
1710
+ }
1711
+ }
1712
+ };
1713
+
1714
+ for (let k = 0; k < aValues.length; k++) {
1715
+ aLinks = aValues[k];
1716
+ if (aLinks && aLinks.length > 0 && aLinks[0] !== undefined) {
1717
+ const oSemanticObject: any = {};
1718
+ let oTmp = {};
1719
+ let sAlternatePath;
1720
+ for (let i = 0; i < aLinks.length; i++) {
1721
+ aFinalLinks.push([]);
1722
+ let hasTargetsNotFiltered = false;
1723
+ let hasTargets = false;
1724
+ for (let iLinkCount = 0; iLinkCount < aLinks[i][0].length; iLinkCount++) {
1725
+ _oLink = aLinks[i][0][iLinkCount];
1726
+ _sLinkIntentAction = _oLink && _oLink.intent.split("?")[0].split("-")[1];
1727
+
1728
+ if (!(_oLink && _oLink.intent && _oLink.intent.indexOf(sCurrentHash) === 0)) {
1729
+ hasTargetsNotFiltered = true;
1730
+ if (!bIntentHasActions(_sLinkIntentAction, aSemanticObjects[k].unavailableActions)) {
1731
+ aFinalLinks[i].push(_oLink);
1732
+ hasTargets = true;
1733
+ }
1734
+ }
1735
+ }
1736
+ oTmp = {
1737
+ semanticObject: aSemanticObjects[k].semanticObject,
1738
+ path: aSemanticObjects[k].path,
1739
+ HasTargets: hasTargets,
1740
+ HasTargetsNotFiltered: hasTargetsNotFiltered
1741
+ };
1742
+ if (oSemanticObject[aSemanticObjects[k].semanticObject] === undefined) {
1743
+ oSemanticObject[aSemanticObjects[k].semanticObject] = {};
1744
+ }
1745
+ sAlternatePath = aSemanticObjects[k].path.replace(/\//g, "_");
1746
+ if (oSemanticObject[aSemanticObjects[k].semanticObject][sAlternatePath] === undefined) {
1747
+ oSemanticObject[aSemanticObjects[k].semanticObject][sAlternatePath] = {};
1748
+ }
1749
+ oSemanticObject[aSemanticObjects[k].semanticObject][sAlternatePath] = Object.assign(
1750
+ oSemanticObject[aSemanticObjects[k].semanticObject][sAlternatePath],
1751
+ oTmp
1752
+ );
1753
+ }
1754
+ const sSemanticObjectName = Object.keys(oSemanticObject)[0];
1755
+ if (Object.keys(oFinalSemanticObjects).includes(sSemanticObjectName)) {
1756
+ oFinalSemanticObjects[sSemanticObjectName] = Object.assign(
1757
+ oFinalSemanticObjects[sSemanticObjectName],
1758
+ oSemanticObject[sSemanticObjectName]
1759
+ );
1760
+ } else {
1761
+ oFinalSemanticObjects = Object.assign(oFinalSemanticObjects, oSemanticObject);
1762
+ }
1763
+ aFinalLinks = [];
1764
+ }
1765
+ }
1766
+ if (Object.keys(oFinalSemanticObjects).length > 0) {
1767
+ oInternalModelContext.setProperty(
1768
+ "semanticsTargets",
1769
+ mergeObjects(oFinalSemanticObjects, oInternalModelContext.getProperty("semanticsTargets"))
1770
+ );
1771
+ return oFinalSemanticObjects;
1772
+ }
1773
+ })
1774
+ .catch(function(oError: any) {
1775
+ Log.error("fnUpdateSemanticTargetsModel: Cannot read links", oError);
1776
+ });
1777
+ }
1778
+ function fnGetSemanticObjectPromise(oAppComponent: any, oView: any, oMetaModel: any, sPath: any) {
1779
+ return CommonUtils.getSemanticObjectsFromPath(oMetaModel, sPath);
1780
+ }
1781
+ function fnGetSemanticTargetsFromPageModel(oController: any, sPageModel: string) {
1782
+ const _fnfindValuesHelper = function(obj: any, key: any, list: any) {
1783
+ if (!obj) {
1784
+ return list;
1785
+ }
1786
+ if (obj instanceof Array) {
1787
+ for (const i in obj) {
1788
+ list = list.concat(_fnfindValuesHelper(obj[i], key, []));
1789
+ }
1790
+ return list;
1791
+ }
1792
+ if (obj[key]) {
1793
+ list.push(obj[key]);
1794
+ }
1795
+
1796
+ if (typeof obj == "object" && obj !== null) {
1797
+ const children = Object.keys(obj);
1798
+ if (children.length > 0) {
1799
+ for (let i = 0; i < children.length; i++) {
1800
+ list = list.concat(_fnfindValuesHelper(obj[children[i]], key, []));
1801
+ }
1802
+ }
1803
+ }
1804
+ return list;
1805
+ };
1806
+ const _fnfindValues = function(obj: any, key: any) {
1807
+ return _fnfindValuesHelper(obj, key, []);
1808
+ };
1809
+ const _fnDeleteDuplicateSemanticObjects = function(aSemanticObjectPath: any) {
1810
+ return aSemanticObjectPath.filter(function(value: any, index: any) {
1811
+ return aSemanticObjectPath.indexOf(value) === index;
1812
+ });
1813
+ };
1814
+ const oView = oController.getView();
1815
+ const oInternalModelContext = oView.getBindingContext("internal");
1816
+
1817
+ if (oInternalModelContext) {
1818
+ const aSemanticObjectsPromises = [];
1819
+ const oComponent = oController.getOwnerComponent();
1820
+ const oAppComponent = Component.getOwnerComponentFor(oComponent) as AppComponent;
1821
+ const oMetaModel = oAppComponent.getMetaModel();
1822
+ let oPageModel = oComponent.getModel(sPageModel).getData();
1823
+ if (JSON.stringify(oPageModel) === "{}") {
1824
+ oPageModel = oComponent.getModel(sPageModel)._getObject("/", undefined);
1825
+ }
1826
+ let aSemanticObjectsFound = _fnfindValues(oPageModel, "semanticObjectPath");
1827
+ aSemanticObjectsFound = _fnDeleteDuplicateSemanticObjects(aSemanticObjectsFound);
1828
+ const oShellServiceHelper = CommonUtils.getShellServices(oAppComponent);
1829
+ let sCurrentHash = CommonUtils.getHash();
1830
+ const aSemanticObjectsForGetLinks = [];
1831
+ const aSemanticObjects: any[] = [];
1832
+ let sPath;
1833
+ let _oSemanticObject;
1834
+
1835
+ if (sCurrentHash && sCurrentHash.indexOf("?") !== -1) {
1836
+ // sCurrentHash can contain query string, cut it off!
1837
+ sCurrentHash = sCurrentHash.split("?")[0];
1838
+ }
1839
+
1840
+ for (let i = 0; i < aSemanticObjectsFound.length; i++) {
1841
+ sPath = aSemanticObjectsFound[i];
1842
+ aSemanticObjectsPromises.push(CommonUtils.getSemanticObjectPromise(oAppComponent, oView, oMetaModel, sPath));
1843
+ }
1844
+
1845
+ if (aSemanticObjectsPromises.length === 0) {
1846
+ return Promise.resolve();
1847
+ } else {
1848
+ Promise.all(aSemanticObjectsPromises)
1849
+ .then(function(aValues: any[]) {
1850
+ const aGetLinksPromises = [];
1851
+ let sSemObjExpression;
1852
+ const aSemanticObjectsResolved = aValues.filter(function(element: any) {
1853
+ if (
1854
+ element.semanticObject !== undefined &&
1855
+ element.semanticObject.semanticObject &&
1856
+ typeof element.semanticObject.semanticObject === "object"
1857
+ ) {
1858
+ sSemObjExpression = compileBinding(bindingExpression(element.semanticObject.semanticObject.$Path));
1859
+ element.semanticObject.semanticObject = sSemObjExpression;
1860
+ element.semanticObjectForGetLinks[0].semanticObject = sSemObjExpression;
1861
+ return true;
1862
+ } else if (element) {
1863
+ return element.semanticObject !== undefined;
1864
+ } else {
1865
+ return false;
1866
+ }
1867
+ });
1868
+ for (let j = 0; j < aSemanticObjectsResolved.length; j++) {
1869
+ _oSemanticObject = aSemanticObjectsResolved[j];
1870
+ if (
1871
+ _oSemanticObject &&
1872
+ _oSemanticObject.semanticObject &&
1873
+ !(_oSemanticObject.semanticObject.semanticObject.indexOf("{") === 0)
1874
+ ) {
1875
+ aSemanticObjectsForGetLinks.push(_oSemanticObject.semanticObjectForGetLinks);
1876
+ aSemanticObjects.push({
1877
+ semanticObject: _oSemanticObject.semanticObject.semanticObject,
1878
+ unavailableActions: _oSemanticObject.unavailableActions,
1879
+ path: aSemanticObjectsResolved[j].semanticObjectPath
1880
+ });
1881
+ aGetLinksPromises.push(oShellServiceHelper.getLinksWithCache([_oSemanticObject.semanticObjectForGetLinks]));
1882
+ }
1883
+ }
1884
+ return CommonUtils.updateSemanticTargets(aGetLinksPromises, aSemanticObjects, oInternalModelContext, sCurrentHash);
1885
+ })
1886
+ .catch(function(oError: any) {
1887
+ Log.error("fnGetSemanticTargetsFromTable: Cannot get Semantic Objects", oError);
1888
+ });
1889
+ }
1890
+ } else {
1891
+ return Promise.resolve();
1892
+ }
1893
+ }
1894
+ function getFilterRestrictions(oFilterRestrictionsAnnotation: any, sRestriction: any) {
1895
+ const FilterRestrictions = CommonUtils.FilterRestrictions;
1896
+ if (sRestriction === FilterRestrictions.REQUIRED_PROPERTIES || sRestriction === FilterRestrictions.NON_FILTERABLE_PROPERTIES) {
1897
+ let aProps = [];
1898
+ if (oFilterRestrictionsAnnotation && oFilterRestrictionsAnnotation[sRestriction]) {
1899
+ aProps = oFilterRestrictionsAnnotation[sRestriction].map(function(oProperty: any) {
1900
+ return oProperty.$PropertyPath;
1901
+ });
1902
+ }
1903
+ return aProps;
1904
+ } else if (sRestriction === FilterRestrictions.ALLOWED_EXPRESSIONS) {
1905
+ const mAllowedExpressions: any = {};
1906
+ if (oFilterRestrictionsAnnotation && oFilterRestrictionsAnnotation.FilterExpressionRestrictions) {
1907
+ oFilterRestrictionsAnnotation.FilterExpressionRestrictions.forEach(function(oProperty: any) {
1908
+ //SingleValue | MultiValue | SingleRange | MultiRange | SearchExpression | MultiRangeOrSearchExpression
1909
+ if (mAllowedExpressions[oProperty.Property.$PropertyPath]) {
1910
+ mAllowedExpressions[oProperty.Property.$PropertyPath].push(oProperty.AllowedExpressions);
1911
+ } else {
1912
+ mAllowedExpressions[oProperty.Property.$PropertyPath] = [oProperty.AllowedExpressions];
1913
+ }
1914
+ });
1915
+ }
1916
+ return mAllowedExpressions;
1917
+ }
1918
+ // Default return the FilterRestrictions Annotation
1919
+ return oFilterRestrictionsAnnotation;
1920
+ }
1921
+ function getFilterRestrictionsByPath(sEntitySetPath: any, oMetaModel: any) {
1922
+ const oRet: any = {},
1923
+ FilterRestrictions = CommonUtils.FilterRestrictions,
1924
+ oFilterRestrictions = sEntitySetPath ? oMetaModel.getObject(sEntitySetPath + "@Org.OData.Capabilities.V1.FilterRestrictions") : {};
1925
+ oRet[FilterRestrictions.REQUIRED_PROPERTIES] = getFilterRestrictions(oFilterRestrictions, FilterRestrictions.REQUIRED_PROPERTIES) || [];
1926
+ oRet[FilterRestrictions.NON_FILTERABLE_PROPERTIES] =
1927
+ getFilterRestrictions(oFilterRestrictions, FilterRestrictions.NON_FILTERABLE_PROPERTIES) || [];
1928
+ //SingleValue | MultiValue | SingleRange | MultiRange | SearchExpression | MultiRangeOrSearchExpression
1929
+ oRet[FilterRestrictions.ALLOWED_EXPRESSIONS] = getFilterRestrictions(oFilterRestrictions, FilterRestrictions.ALLOWED_EXPRESSIONS) || {};
1930
+
1931
+ const aPathParts = sEntitySetPath.split("/");
1932
+
1933
+ if (aPathParts.length > 2) {
1934
+ // In normal filterbar scenarios sEntitySetPath is of the format "/Customer".
1935
+ // But, In case of sEntitySetPath of format "/Customer/Set" this is to check navigation restrictions of "Customer" for non-filterable properties in "Set"
1936
+ const sNavigationPath = aPathParts[aPathParts.length - 1];
1937
+ aPathParts.splice(-1, 1); // removing NavigationProperty from the end.
1938
+ const sParentEntitySetPath = aPathParts.join("/");
1939
+ const oNavigationRestrictions = CommonUtils.getNavigationRestrictions(oMetaModel, sParentEntitySetPath, sNavigationPath);
1940
+ const oNavigationFilterRestrictions = oNavigationRestrictions && oNavigationRestrictions["FilterRestrictions"];
1941
+ oRet[FilterRestrictions.REQUIRED_PROPERTIES].concat(
1942
+ getFilterRestrictions(oNavigationFilterRestrictions, FilterRestrictions.REQUIRED_PROPERTIES) || []
1943
+ );
1944
+ oRet[FilterRestrictions.NON_FILTERABLE_PROPERTIES].concat(
1945
+ getFilterRestrictions(oNavigationFilterRestrictions, FilterRestrictions.NON_FILTERABLE_PROPERTIES) || []
1946
+ );
1947
+ //SingleValue | MultiValue | SingleRange | MultiRange | SearchExpression | MultiRangeOrSearchExpression
1948
+ oRet[FilterRestrictions.ALLOWED_EXPRESSIONS] = mergeObjects(
1949
+ {},
1950
+ getFilterRestrictions(oNavigationFilterRestrictions, FilterRestrictions.ALLOWED_EXPRESSIONS) || {},
1951
+ oRet[FilterRestrictions.ALLOWED_EXPRESSIONS]
1952
+ );
1953
+ }
1954
+
1955
+ return oRet;
1956
+ }
1957
+ function templateControlFragment(sFragmentName: any, oPreprocessorSettings: any, oOptions: any, oModifier?: any) {
1958
+ oOptions = oOptions || {};
1959
+ if (oModifier) {
1960
+ return oModifier.templateControlFragment(sFragmentName, oPreprocessorSettings, oOptions.view).then(function(oFragment: any) {
1961
+ // This is required as Flex returns an HTMLCollection as templating result in XML time.
1962
+ return oModifier.targets === "xmlTree" && oFragment.length > 0 ? oFragment[0] : oFragment;
1963
+ });
1964
+ } else {
1965
+ return loadMacroLibrary()
1966
+ .then(function() {
1967
+ return XMLPreprocessor.process(
1968
+ XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment"),
1969
+ { name: sFragmentName },
1970
+ oPreprocessorSettings
1971
+ );
1972
+ })
1973
+ .then(function(oFragment: any) {
1974
+ const oControl = oFragment.firstElementChild;
1975
+ if (!!oOptions.isXML && oControl) {
1976
+ return oControl;
1977
+ }
1978
+ return Fragment.load({
1979
+ id: oOptions.id,
1980
+ definition: oFragment,
1981
+ controller: oOptions.controller
1982
+ });
1983
+ });
1984
+ }
1985
+ }
1986
+ function getSingletonPath(path: string, metaModel: ODataMetaModel): string | undefined {
1987
+ const parts = path.split("/").filter(Boolean),
1988
+ propertyName = parts.pop(),
1989
+ navigationPath = parts.join("/"),
1990
+ entitySet = navigationPath && metaModel.getObject("/" + navigationPath);
1991
+ if (entitySet?.$kind === "Singleton") {
1992
+ const singletonName = parts[parts.length - 1];
1993
+ return "/" + singletonName + "/" + propertyName;
1994
+ }
1995
+ return undefined;
1996
+ }
1997
+ function requestSingletonProperty(path: string, model: ODataModel) {
1998
+ if (!path || !model) {
1999
+ return Promise.resolve(null);
2000
+ }
2001
+ const metaModel = model.getMetaModel();
2002
+ // Find the underlying entity set from the property path and check whether it is a singleton.
2003
+ const resolvedPath = getSingletonPath(path, metaModel);
2004
+ if (resolvedPath) {
2005
+ const propertyBinding = model.bindProperty(resolvedPath);
2006
+ return propertyBinding.requestValue();
2007
+ }
2008
+
2009
+ return Promise.resolve(null);
2010
+ }
2011
+ function addEventToBindingInfo(oControl: Control, sEventName: string, fHandler: Function) {
2012
+ let oBindingInfo: any;
2013
+ const setBindingInfo = function() {
2014
+ if (oBindingInfo) {
2015
+ if (!oBindingInfo.events) {
2016
+ oBindingInfo.events = {};
2017
+ }
2018
+ if (!oBindingInfo.events[sEventName]) {
2019
+ oBindingInfo.events[sEventName] = fHandler;
2020
+ } else {
2021
+ const fOriginalHandler = oBindingInfo.events[sEventName];
2022
+ oBindingInfo.events[sEventName] = function(...args: any[]) {
2023
+ fHandler.apply(this, ...args);
2024
+ fOriginalHandler.apply(this, ...args);
2025
+ };
2026
+ }
2027
+ }
2028
+ };
2029
+ if (oControl.isA("sap.ui.mdc.Chart")) {
2030
+ (oControl as any)
2031
+ .innerChartBound()
2032
+ .then(function() {
2033
+ oBindingInfo = (oControl as any)
2034
+ .getControlDelegate()
2035
+ ._getChart(oControl)
2036
+ .getBindingInfo("data");
2037
+ setBindingInfo();
2038
+ })
2039
+ .catch(function(sError: any) {
2040
+ Log.error(sError);
2041
+ });
2042
+ } else {
2043
+ oBindingInfo = oControl.data("rowsBindingInfo");
2044
+ setBindingInfo();
2045
+ }
2046
+ }
2047
+ function loadMacroLibrary() {
2048
+ return new Promise<void>(function(resolve) {
2049
+ sap.ui.require(["sap/fe/macros/macroLibrary"], function(/*macroLibrary*/) {
2050
+ resolve();
2051
+ });
2052
+ });
2053
+ }
2054
+
2055
+ function fnOnStrictHandlingFailed(sGroupId: string, actionName: string, oModel: ODataModel, aMessages: any[]) {
2056
+ const localI18nRef = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core") as ResourceBundle,
2057
+ sActionName = actionName,
2058
+ sCancelButtonTxt = localI18nRef.getText("CANCEL");
2059
+ if (aMessages.length === 1) {
2060
+ const sMessage = aMessages[0].message + "\n" + localI18nRef.getText("PROCEED");
2061
+ const dialogPromise = new Promise(function(resolve) {
2062
+ MessageBox.warning(sMessage, {
2063
+ title: localI18nRef.getText("WARNING"),
2064
+ actions: [sActionName, sCancelButtonTxt],
2065
+ emphasizedAction: sActionName,
2066
+ onClose: function(sAction: string) {
2067
+ if (sAction === sActionName) {
2068
+ resolve(true);
2069
+ oModel.submitBatch(sGroupId);
2070
+ } else {
2071
+ resolve(false);
2072
+ }
2073
+ }
2074
+ });
2075
+ });
2076
+ return dialogPromise;
2077
+ }
2078
+ return new Promise(function(resolve) {
2079
+ const oMessageDialogModel = new JSONModel();
2080
+ oMessageDialogModel.setData(aMessages);
2081
+ const bStrictHandlingFlow = true;
2082
+ const oMessageObject = messageHandling.prepareMessageViewForDialog(oMessageDialogModel, bStrictHandlingFlow);
2083
+ const oDialog = new Dialog({
2084
+ resizable: true,
2085
+ content: oMessageObject.oMessageView,
2086
+ state: "Warning",
2087
+ customHeader: new Bar({
2088
+ contentLeft: [oMessageObject.oBackButton],
2089
+ contentMiddle: [new Title({ text: "Warning" })]
2090
+ }),
2091
+ contentHeight: "50%",
2092
+ contentWidth: "50%",
2093
+ verticalScrolling: false
2094
+ });
2095
+ oDialog.setBeginButton(
2096
+ new Button({
2097
+ press: function() {
2098
+ resolve(true);
2099
+ oModel.submitBatch(sGroupId);
2100
+ oDialog.close();
2101
+ },
2102
+ type: "Emphasized",
2103
+ text: getTranslatedText("IGNORE", localI18nRef, sActionName)
2104
+ })
2105
+ );
2106
+ oDialog.setEndButton(
2107
+ new Button({
2108
+ press: function() {
2109
+ resolve(false);
2110
+ oDialog.close();
2111
+ },
2112
+ text: sCancelButtonTxt
2113
+ })
2114
+ );
2115
+ oDialog.open();
2116
+ });
2117
+ }
2118
+ const CommonUtils = {
2119
+ isPropertyFilterable: isPropertyFilterable,
2120
+ isFieldControlPathInapplicable: isFieldControlPathInapplicable,
2121
+ removeSensitiveData: removeSensitiveData,
2122
+ fireButtonPress: fnFireButtonPress,
2123
+ getTargetView: getTargetView,
2124
+ hasTransientContext: fnHasTransientContexts,
2125
+ updateRelatedAppsDetails: fnUpdateRelatedAppsDetails,
2126
+ resolveStringtoBoolean: fnResolveStringtoBoolean,
2127
+ getAppComponent: getAppComponent,
2128
+ processDataLossConfirmation: fnProcessDataLossConfirmation,
2129
+ getMandatoryFilterFields: fnGetMandatoryFilterFields,
2130
+ getContextPathProperties: fnGetContextPathProperties,
2131
+ getParameterInfo: getParameterInfo,
2132
+ updateDataFieldForIBNButtonsVisibility: fnUpdateDataFieldForIBNButtonsVisibility,
2133
+ getTranslatedText: getTranslatedText,
2134
+ getEntitySetName: getEntitySetName,
2135
+ getActionPath: getActionPath,
2136
+ computeDisplayMode: computeDisplayMode,
2137
+ setActionEnablement: setActionEnablement,
2138
+ isStickyEditMode: isStickyEditMode,
2139
+ getOperatorsForProperty: getOperatorsForProperty,
2140
+ addSelectionVariantToConditions: addSelectionVariantToConditions,
2141
+ addExternalStateFiltersToSelectionVariant: addExternalStateFiltersToSelectionVariant,
2142
+ addPageContextToSelectionVariant: addPageContextToSelectionVariant,
2143
+ addDefaultDisplayCurrency: addDefaultDisplayCurrency,
2144
+ getNonComputedVisibleFields: getNonComputedVisibleFields,
2145
+ setUserDefaults: setUserDefaults,
2146
+ getShellServices: getShellServices,
2147
+ getHash: getHash,
2148
+ getIBNActions: fnGetIBNActions,
2149
+ getHeaderFacetItemConfigForExternalNavigation: getHeaderFacetItemConfigForExternalNavigation,
2150
+ getSemanticObjectMapping: getSemanticObjectMapping,
2151
+ setSemanticObjectMappings: setSemanticObjectMappings,
2152
+ getSemanticObjectPromise: fnGetSemanticObjectPromise,
2153
+ getSemanticTargetsFromPageModel: fnGetSemanticTargetsFromPageModel,
2154
+ getSemanticObjectsFromPath: fnGetSemanticObjectsFromPath,
2155
+ updateSemanticTargets: fnUpdateSemanticTargetsModel,
2156
+ getPropertyDataType: getPropertyDataType,
2157
+ getNavigationRestrictions: getNavigationRestrictions,
2158
+ getSearchRestrictions: getSearchRestrictions,
2159
+ getFilterRestrictionsByPath: getFilterRestrictionsByPath,
2160
+ getSpecificAllowedExpression: getSpecificAllowedExpression,
2161
+ getAdditionalParamsForCreate: getAdditionalParamsForCreate,
2162
+ requestSingletonProperty: requestSingletonProperty,
2163
+ templateControlFragment: templateControlFragment,
2164
+ addEventToBindingInfo: addEventToBindingInfo,
2165
+ FilterRestrictions: {
2166
+ REQUIRED_PROPERTIES: "RequiredProperties",
2167
+ NON_FILTERABLE_PROPERTIES: "NonFilterableProperties",
2168
+ ALLOWED_EXPRESSIONS: "FilterAllowedExpressions"
2169
+ },
2170
+ AllowedExpressionsPrio: ["SingleValue", "MultiValue", "SingleRange", "MultiRange", "SearchExpression", "MultiRangeOrSearchExpression"],
2171
+ fnProcessDataLossOrDraftDiscardConfirmation: fnProcessDataLossOrDraftDiscardConfirmation,
2172
+ normalizeSearchTerm: normalizeSearchTerm,
2173
+ fnOnStrictHandlingFailed: fnOnStrictHandlingFailed,
2174
+ getSingletonPath: getSingletonPath
2175
+ };
2176
+
2177
+ export default CommonUtils;