@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
@@ -12,11 +12,11 @@ import {
12
12
  LineItem,
13
13
  PathAnnotationExpression,
14
14
  PresentationVariantTypeTypes,
15
- PropertyAnnotationValue,
16
15
  PropertyPath,
17
16
  SelectionVariantType,
18
17
  SelectOptionType,
19
- UIAnnotationTypes
18
+ UIAnnotationTypes,
19
+ FieldGroupType
20
20
  } from "@sap-ux/vocabularies-types";
21
21
  import {
22
22
  ActionType,
@@ -24,18 +24,20 @@ import {
24
24
  CreationMode,
25
25
  FormatOptionsType,
26
26
  HorizontalAlign,
27
+ Importance,
27
28
  ManifestTableColumn,
28
29
  NavigationSettingsConfiguration,
29
30
  NavigationTargetConfiguration,
30
31
  SelectionMode,
31
32
  TableColumnSettings,
32
33
  TableManifestConfiguration,
34
+ TableManifestSettingsConfiguration,
33
35
  TemplateType,
34
36
  VariantManagementType,
35
37
  ViewPathConfiguration,
36
38
  VisualizationType
37
39
  } from "../../ManifestSettings";
38
- import { EntityType, Property } from "@sap-ux/annotation-converter";
40
+ import { EntityType, Property, TypeDefinition } from "@sap-ux/annotation-converter";
39
41
  import { TableID } from "../../helpers/ID";
40
42
  import {
41
43
  AnnotationAction,
@@ -69,13 +71,12 @@ import {
69
71
  ExpressionOrPrimitive,
70
72
  formatResult,
71
73
  ifElse,
72
- isBinding,
73
74
  isConstant,
74
75
  not,
75
76
  or,
76
77
  resolveBindingString
77
78
  } from "sap/fe/core/helpers/BindingExpression";
78
- import { Draft, bindingContextPathVisitor, singletonPathVisitor, UI } from "sap/fe/core/converters/helpers/BindingHelper";
79
+ import { Entity, bindingContextPathVisitor, UI } from "sap/fe/core/converters/helpers/BindingHelper";
79
80
  import { KeyHelper } from "sap/fe/core/converters/helpers/Key";
80
81
  import tableFormatters from "sap/fe/core/formatters/TableFormatter";
81
82
  import { MessageType } from "sap/fe/core/formatters/TableFormatterTypes";
@@ -84,11 +85,10 @@ import {
84
85
  getTargetObjectPath,
85
86
  isPathDeletable,
86
87
  isPathSearchable,
87
- isPathInsertable,
88
88
  isPathUpdatable
89
89
  } from "sap/fe/core/templating/DataModelPathHelper";
90
90
  import { replaceSpecialChars } from "sap/fe/core/helpers/StableIdHelper";
91
- import { IssueCategory, IssueSeverity, IssueType } from "sap/fe/core/converters/helpers/IssueManager";
91
+ import { IssueCategory, IssueSeverity, IssueType, IssueCategoryType } from "sap/fe/core/converters/helpers/IssueManager";
92
92
 
93
93
  import ManifestWrapper from "../../ManifestWrapper";
94
94
  import ConverterContext from "../../ConverterContext";
@@ -100,10 +100,27 @@ import {
100
100
  getTargetValueOnDataPoint
101
101
  } from "sap/fe/core/templating/PropertyHelper";
102
102
  import { AggregationHelper } from "../../helpers/Aggregation";
103
- import { DisplayMode, getDisplayMode, getTypeConfig } from "sap/fe/core/templating/UIFormatters";
103
+ import { DisplayMode, EDM_TYPE_MAPPING, getDisplayMode } from "sap/fe/core/templating/DisplayModeFormatter";
104
104
  import { getMessageTypeFromCriticalityType } from "./Criticality";
105
105
  import { FilterFunctions } from "@sap-ux/vocabularies-types/dist/generated/Capabilities";
106
+ import { SemanticKey } from "@sap-ux/vocabularies-types/types/generated/Common";
106
107
  import { getNonSortablePropertiesRestrictions } from "sap/fe/core/templating/EntitySetHelper";
108
+ import {
109
+ generateStandardActionsContext,
110
+ StandardActionConfigType,
111
+ getDeleteVisibility,
112
+ getStandardActionCreate,
113
+ getStandardActionDelete,
114
+ getStandardActionPaste,
115
+ getStandardActionMassEdit,
116
+ isDraftOrStickySupported,
117
+ getInsertUpdateActionsTemplating,
118
+ getCreateVisibility,
119
+ isInDisplayMode,
120
+ getMassEditVisibility,
121
+ getRestrictions,
122
+ getCreationRow
123
+ } from "./table/StandardActions";
107
124
 
108
125
  export type TableAnnotationConfiguration = {
109
126
  autoBindOnInit: boolean;
@@ -120,11 +137,10 @@ export type TableAnnotationConfiguration = {
120
137
  rowNavigated: BindingExpression<boolean>;
121
138
  };
122
139
  selectionMode: string | undefined;
123
- show?: {
124
- create?: string | boolean;
125
- delete?: string | boolean;
126
- paste?: BindingExpression<boolean>;
127
- massEdit?: { visible: boolean | string; enabled: boolean | string };
140
+ standardActions: {
141
+ actions: Record<string, StandardActionConfigType>;
142
+ isInsertUpdateTemplated: boolean;
143
+ updatablePropertyPath: string;
128
144
  };
129
145
  displayMode?: boolean;
130
146
  threshold: number;
@@ -134,8 +150,7 @@ export type TableAnnotationConfiguration = {
134
150
  aggregateConditions?: string;
135
151
 
136
152
  /** Create new entries */
137
- create: CreateBehaviour | CreateBehaviourExternal;
138
- parentEntityDeleteEnabled?: BindingExpression<boolean>;
153
+ create: CreateBehavior | CreateBehaviorExternal;
139
154
  title: string;
140
155
  searchable: boolean;
141
156
  };
@@ -143,9 +158,9 @@ export type TableAnnotationConfiguration = {
143
158
  /**
144
159
  * New entries are created within the app (default case)
145
160
  */
146
- type CreateBehaviour = {
161
+ type CreateBehavior = {
147
162
  mode: CreationMode;
148
- append: Boolean;
163
+ append: boolean;
149
164
  newAction?: string;
150
165
  navigateToTarget?: string;
151
166
  };
@@ -153,7 +168,7 @@ type CreateBehaviour = {
153
168
  /**
154
169
  * New entries are created by navigating to some target
155
170
  */
156
- type CreateBehaviourExternal = {
171
+ type CreateBehaviorExternal = {
157
172
  mode: "External";
158
173
  outbound: string;
159
174
  outboundDetail: NavigationTargetConfiguration["outboundDetail"];
@@ -198,6 +213,7 @@ export type TableControlConfiguration = {
198
213
  showRowCount: boolean;
199
214
  enableMassEdit: boolean | undefined;
200
215
  enableAutoColumnWidth: boolean;
216
+ dataStateIndicatorFilter: string | undefined;
201
217
  };
202
218
 
203
219
  export type TableType = "GridTable" | "ResponsiveTable" | "AnalyticalTable";
@@ -222,6 +238,7 @@ export type BaseTableColumn = ConfigurableObject & {
222
238
  sortable: boolean;
223
239
  horizontalAlign?: HorizontalAlign;
224
240
  formatOptions: FormatOptionsType;
241
+ importance: string;
225
242
  };
226
243
 
227
244
  export type CustomTableColumn = BaseTableColumn & {
@@ -233,6 +250,7 @@ export type AnnotationTableColumn = BaseTableColumn & {
233
250
  annotationPath: string;
234
251
  relativePath: string;
235
252
  label?: string;
253
+ tooltip?: string;
236
254
  groupLabel?: string;
237
255
  group?: string;
238
256
  isGroupable?: boolean;
@@ -240,6 +258,7 @@ export type AnnotationTableColumn = BaseTableColumn & {
240
258
  showDataFieldsLabel?: boolean;
241
259
  isKey?: boolean;
242
260
  unit?: string;
261
+ unitText?: string;
243
262
  exportSettings?: {
244
263
  template?: string;
245
264
  label?: string;
@@ -252,6 +271,8 @@ export type AnnotationTableColumn = BaseTableColumn & {
252
271
  delimiter?: boolean;
253
272
  trueValue?: boolean;
254
273
  falseValue?: boolean;
274
+ unit?: string;
275
+ unitProperty?: string;
255
276
  };
256
277
  isDataPointFakeTargetProperty?: boolean;
257
278
  textArrangement?: {
@@ -298,7 +319,7 @@ export type TableVisualization = {
298
319
  actions: BaseAction[];
299
320
  aggregates?: Record<string, AggregateData>;
300
321
  enableAnalytics?: boolean;
301
- enableDataStateFilter: boolean;
322
+ enableAnalyticsSearch?: boolean;
302
323
  operationAvailableMap: string;
303
324
  operationAvailableProperties: string;
304
325
  };
@@ -373,6 +394,7 @@ export function getTableColumns(
373
394
 
374
395
  return insertCustomElements(annotationColumns, manifestColumns, {
375
396
  width: "overwrite",
397
+ importance: "overwrite",
376
398
  isNavigable: "overwrite",
377
399
  availability: "overwrite",
378
400
  settings: "overwrite",
@@ -490,6 +512,10 @@ function updateTableVisualizationForAnalytics(
490
512
  tableVisualization.enableAnalytics = true;
491
513
  tableVisualization.aggregates = aggregatesDefinitions;
492
514
 
515
+ const aggregationHelper = new AggregationHelper(entityType, converterContext);
516
+ const allowedTransformations = aggregationHelper.getAllowedTransformations();
517
+ tableVisualization.enableAnalyticsSearch = allowedTransformations ? allowedTransformations.indexOf("search") >= 0 : true;
518
+
493
519
  // Add group and sort conditions from the presentation variant
494
520
  tableVisualization.annotation.groupConditions = getGroupConditions(presentationVariantAnnotation, tableVisualization.columns);
495
521
  tableVisualization.annotation.aggregateConditions = getAggregateConditions(
@@ -545,13 +571,17 @@ export function updateLinkedProperties(entityType: EntityType, tableColumns: Tab
545
571
  tableColumns.forEach(oColumn => {
546
572
  const oTableColumn = oColumn as AnnotationTableColumn;
547
573
  if (oTableColumn.propertyInfos === undefined && oTableColumn.relativePath) {
548
- const oProperty = entityType.entityProperties.find(oProp => oProp.name === oTableColumn.relativePath);
574
+ const oProperty = entityType.entityProperties.find((oProp: Property) => oProp.name === oTableColumn.relativePath);
549
575
  if (oProperty) {
550
- const sUnit = getAssociatedCurrencyProperty(oProperty)?.name || getAssociatedUnitProperty(oProperty)?.name;
551
- if (sUnit) {
552
- const oUnitColumn = findColumnByPath(sUnit);
553
-
576
+ const oUnit = getAssociatedCurrencyProperty(oProperty) || getAssociatedUnitProperty(oProperty);
577
+ if (oUnit) {
578
+ const oUnitColumn = findColumnByPath(oUnit.name);
554
579
  oTableColumn.unit = oUnitColumn?.name;
580
+ } else {
581
+ const sUnit = oProperty?.annotations?.Measures?.ISOCurrency || oProperty?.annotations?.Measures?.Unit;
582
+ if (sUnit) {
583
+ oTableColumn.unitText = `${sUnit}`;
584
+ }
555
585
  }
556
586
 
557
587
  const displayMode = getDisplayMode(oProperty),
@@ -604,7 +634,6 @@ export function createTableVisualization(
604
634
  control: tableManifestConfig,
605
635
  actions: removeDuplicateActions(getTableActions(lineItemAnnotation, visualizationPath, converterContext, navigationSettings)),
606
636
  columns: columns,
607
- enableDataStateFilter: converterContext.getTemplateType() === "ObjectPage",
608
637
  operationAvailableMap: JSON.stringify(operationAvailableMap),
609
638
  operationAvailableProperties: getOperationAvailableProperties(operationAvailableMap, converterContext)
610
639
  };
@@ -630,7 +659,6 @@ export function createDefaultTableVisualization(converterContext: ConverterConte
630
659
  control: tableManifestConfig,
631
660
  actions: [],
632
661
  columns: columns,
633
- enableDataStateFilter: converterContext.getTemplateType() === "ObjectPage",
634
662
  operationAvailableMap: JSON.stringify(operationAvailableMap),
635
663
  operationAvailableProperties: getOperationAvailableProperties(operationAvailableMap, converterContext)
636
664
  };
@@ -688,6 +716,22 @@ function getOperationAvailableMap(lineItemAnnotation: LineItem | undefined, conv
688
716
  return operationAvailableMap;
689
717
  }
690
718
 
719
+ /**
720
+ * Gets updatable propertyPath for the current entityset if valid.
721
+ *
722
+ * @param converterContext The instance of the converter context
723
+ * @returns {string} The updatable property for the rows
724
+ */
725
+ function getCurrentEntitySetUpdatablePath(converterContext: ConverterContext): string {
726
+ const restrictions = getRestrictions(converterContext);
727
+ const entitySet = converterContext.getEntitySet();
728
+ const updatable = restrictions.isUpdatable;
729
+ const isOnlyDynamicOnCurrentEntity: any = !isConstant(updatable.expression) && updatable.navigationExpression._type === "Unresolvable";
730
+ const updatablePropertyPath = (entitySet?.annotations.Capabilities?.UpdateRestrictions?.Updatable as any)?.path;
731
+
732
+ return isOnlyDynamicOnCurrentEntity ? (updatablePropertyPath as string) : "";
733
+ }
734
+
691
735
  /**
692
736
  * Method to retrieve all property paths assigned to the Core.OperationAvailable annotation.
693
737
  *
@@ -910,7 +954,8 @@ export function getSelectionMode(
910
954
  converterContext: ConverterContext,
911
955
  isEntitySet: boolean,
912
956
  targetCapabilities: TableCapabilityRestriction,
913
- isDeleteButtonVisible?: Expression<boolean>
957
+ deleteButtonVisibilityExpression?: Expression<boolean>,
958
+ massEditVisibilityExpression: Expression<boolean> = constant(false)
914
959
  ): string | undefined {
915
960
  if (!lineItemAnnotation) {
916
961
  return SelectionMode.None;
@@ -928,15 +973,34 @@ export function getSelectionMode(
928
973
  );
929
974
  let isParentDeletable, parentEntitySetDeletable;
930
975
  if (converterContext.getTemplateType() === TemplateType.ObjectPage) {
931
- isParentDeletable = isPathDeletable(converterContext.getDataModelObjectPath(), undefined);
976
+ isParentDeletable = isPathDeletable(converterContext.getDataModelObjectPath());
932
977
  parentEntitySetDeletable = isParentDeletable ? compileBinding(isParentDeletable, true) : isParentDeletable;
933
978
  }
934
- if (selectionMode && selectionMode === SelectionMode.None && isDeleteButtonVisible) {
935
- return compileBinding(ifElse(isDeleteButtonVisible, constant("Multi"), constant("None")));
979
+
980
+ const bMassEditEnabled: boolean = !isConstant(massEditVisibilityExpression) || massEditVisibilityExpression.value !== false;
981
+ if (selectionMode && selectionMode === SelectionMode.None && deleteButtonVisibilityExpression) {
982
+ if (converterContext.getTemplateType() === TemplateType.ObjectPage && bMassEditEnabled) {
983
+ // Mass Edit in OP is enabled only in edit mode.
984
+ return compileBinding(
985
+ ifElse(
986
+ and(equal(bindingExpression("/editMode", "ui"), "Editable"), massEditVisibilityExpression),
987
+ constant("Multi"),
988
+ ifElse(deleteButtonVisibilityExpression, constant("Multi"), constant("None"))
989
+ )
990
+ );
991
+ } else if (bMassEditEnabled) {
992
+ return SelectionMode.Multi;
993
+ }
994
+
995
+ return compileBinding(ifElse(deleteButtonVisibilityExpression, constant("Multi"), constant("None")));
936
996
  }
937
997
  if (!selectionMode || selectionMode === SelectionMode.Auto) {
938
998
  selectionMode = SelectionMode.Multi;
939
999
  }
1000
+ if (bMassEditEnabled) {
1001
+ // Override default selection mode when mass edit is visible
1002
+ selectionMode = selectionMode === SelectionMode.Single ? SelectionMode.Single : SelectionMode.Multi;
1003
+ }
940
1004
 
941
1005
  if (
942
1006
  hasBoundActionsAlwaysVisibleInToolBar(lineItemAnnotation, converterContext.getEntityType()) ||
@@ -953,12 +1017,22 @@ export function getSelectionMode(
953
1017
  aVisibleBindingExpressions = getVisibleExpForCustomActionsRequiringContext(manifestActions);
954
1018
 
955
1019
  // No action requiring a context:
956
- if (aHiddenBindingExpressions.length === 0 && aVisibleBindingExpressions.length === 0 && isDeleteButtonVisible) {
1020
+ if (
1021
+ aHiddenBindingExpressions.length === 0 &&
1022
+ aVisibleBindingExpressions.length === 0 &&
1023
+ (deleteButtonVisibilityExpression || bMassEditEnabled)
1024
+ ) {
957
1025
  if (!isEntitySet) {
958
- if (targetCapabilities.isDeletable || parentEntitySetDeletable !== "false") {
1026
+ // Example: OP case
1027
+ if (targetCapabilities.isDeletable || parentEntitySetDeletable !== "false" || bMassEditEnabled) {
1028
+ // Building expression for delete and mass edit
1029
+ const buttonVisibilityExpression = or(
1030
+ deleteButtonVisibilityExpression || true, // default delete visibility as true
1031
+ massEditVisibilityExpression
1032
+ );
959
1033
  return compileBinding(
960
1034
  ifElse(
961
- and(equal(bindingExpression("/editMode", "ui"), "Editable"), isDeleteButtonVisible),
1035
+ and(equal(bindingExpression("/editMode", "ui"), "Editable"), buttonVisibilityExpression),
962
1036
  constant(selectionMode),
963
1037
  constant(SelectionMode.None)
964
1038
  )
@@ -967,18 +1041,28 @@ export function getSelectionMode(
967
1041
  return SelectionMode.None;
968
1042
  }
969
1043
  // EntitySet deletable:
970
- } else if (targetCapabilities.isDeletable && isDeleteButtonVisible) {
971
- return compileBinding(ifElse(isDeleteButtonVisible, constant(selectionMode), constant("None")));
1044
+ } else if (bMassEditEnabled) {
1045
+ // example: LR scenario
1046
+ return selectionMode;
1047
+ } else if (targetCapabilities.isDeletable && deleteButtonVisibilityExpression) {
1048
+ return compileBinding(ifElse(deleteButtonVisibilityExpression, constant(selectionMode), constant("None")));
972
1049
  // EntitySet not deletable:
973
1050
  } else {
974
1051
  return SelectionMode.None;
975
1052
  }
976
1053
  // There are actions requiring a context:
977
1054
  } else if (!isEntitySet) {
978
- if (targetCapabilities.isDeletable || parentEntitySetDeletable !== "false") {
1055
+ // Example: OP case
1056
+ if (targetCapabilities.isDeletable || parentEntitySetDeletable !== "false" || bMassEditEnabled) {
1057
+ // Use selectionMode in edit mode if delete is enabled or mass edit is visible
1058
+ const editModebuttonVisibilityExpression = ifElse(
1059
+ bMassEditEnabled && !targetCapabilities.isDeletable,
1060
+ massEditVisibilityExpression,
1061
+ constant(true)
1062
+ );
979
1063
  return compileBinding(
980
1064
  ifElse(
981
- equal(bindingExpression("/editMode", "ui"), "Editable"),
1065
+ and(equal(bindingExpression("/editMode", "ui"), "Editable"), editModebuttonVisibilityExpression),
982
1066
  constant(selectionMode),
983
1067
  ifElse(
984
1068
  or(...aHiddenBindingExpressions.concat(aVisibleBindingExpressions)),
@@ -997,13 +1081,14 @@ export function getSelectionMode(
997
1081
  );
998
1082
  }
999
1083
  //EntitySet deletable:
1000
- } else if (targetCapabilities.isDeletable) {
1001
- return SelectionMode.Multi;
1084
+ } else if (targetCapabilities.isDeletable || bMassEditEnabled) {
1085
+ // Example: LR scenario
1086
+ return selectionMode;
1002
1087
  //EntitySet not deletable:
1003
1088
  } else {
1004
1089
  return compileBinding(
1005
1090
  ifElse(
1006
- or(...aHiddenBindingExpressions.concat(aVisibleBindingExpressions)),
1091
+ or(...aHiddenBindingExpressions.concat(aVisibleBindingExpressions), massEditVisibilityExpression),
1007
1092
  constant(selectionMode),
1008
1093
  constant(SelectionMode.None)
1009
1094
  )
@@ -1109,14 +1194,25 @@ function getHighlightRowBinding(
1109
1194
  defaultHighlightRowDefinition = getMessageTypeFromCriticalityType(criticalityAnnotation);
1110
1195
  }
1111
1196
  }
1112
- return ifElse(
1113
- isDraftRoot && Draft.IsNewObject,
1114
- MessageType.Information as MessageType,
1115
- formatResult(
1116
- [defaultHighlightRowDefinition, bindingExpression(`filteredMessages`, "internal")],
1117
- tableFormatters.rowHighlighting,
1118
- targetEntityType
1119
- )
1197
+
1198
+ const aMissingKeys: any[] = [];
1199
+ targetEntityType?.keys.forEach((key: any) => {
1200
+ if (key.name !== "IsActiveEntity") {
1201
+ aMissingKeys.push(bindingExpression(key.name, undefined));
1202
+ }
1203
+ });
1204
+
1205
+ return formatResult(
1206
+ [
1207
+ defaultHighlightRowDefinition,
1208
+ bindingExpression(`filteredMessages`, "internal"),
1209
+ isDraftRoot && Entity.HasActive,
1210
+ isDraftRoot && Entity.IsActive,
1211
+ `${isDraftRoot}`,
1212
+ ...aMissingKeys
1213
+ ],
1214
+ tableFormatters.rowHighlighting,
1215
+ targetEntityType
1120
1216
  );
1121
1217
  }
1122
1218
 
@@ -1132,7 +1228,7 @@ function _getCreationBehaviour(
1132
1228
  if (navigation?.outbound && navigation.outboundDetail && navigationSettings?.create) {
1133
1229
  return {
1134
1230
  mode: "External",
1135
- outbound: navigation.outbound,
1231
+ outbound: navigation.outbound as string,
1136
1232
  outboundDetail: navigation.outboundDetail,
1137
1233
  navigationSettings: navigationSettings
1138
1234
  };
@@ -1289,6 +1385,13 @@ export const getColumnsFromEntityType = function(
1289
1385
  wrap: relatedPropertiesInfo.exportSettingsWrapping
1290
1386
  };
1291
1387
 
1388
+ if (relatedPropertiesInfo.exportUnitName) {
1389
+ columnInfo.exportSettings.unitProperty = relatedPropertiesInfo.exportUnitName;
1390
+ columnInfo.exportSettings.type = "Currency"; // Force to a currency because there's a unitProperty (otherwise the value isn't properly formatted when exported)
1391
+ } else if (relatedPropertiesInfo.exportUnitString) {
1392
+ columnInfo.exportSettings.unit = relatedPropertiesInfo.exportUnitString;
1393
+ }
1394
+
1292
1395
  // Collect information of related columns to be created.
1293
1396
  relatedPropertyNames.forEach(name => {
1294
1397
  columnsToBeCreated[name] = relatedPropertiesInfo.properties[name];
@@ -1315,8 +1418,8 @@ export const getColumnsFromEntityType = function(
1315
1418
  * @param {string} fullPropertyPath The full path to the target property
1316
1419
  * @param {string} relativePath The relative path to the target property based on the context
1317
1420
  * @param {boolean} useDataFieldPrefix Should be prefixed with "DataField::", else it will be prefixed with "Property::"
1318
- * @param {boolean} availableForAdaptation Decides whether column should be available for adaptation
1319
- * @param {string[]} nonSortableColumns The array of all non sortable column names
1421
+ * @param {boolean} availableForAdaptation Decides whether the column should be available for adaptation
1422
+ * @param {string[]} nonSortableColumns The array of all non-sortable column names
1320
1423
  * @param {AggregationHelper} aggregationHelper The aggregationHelper for the entity
1321
1424
  * @param {ConverterContext} converterContext The converter context
1322
1425
  * @returns {AnnotationTableColumn} The annotation column definition
@@ -1349,7 +1452,7 @@ const getColumnDefinitionFromProperty = function(
1349
1452
  oConstraints: propertyTypeConfig.constraints
1350
1453
  }
1351
1454
  : undefined;
1352
- const exportSettings = isDataPointFakeProperty
1455
+ const exportSettings: any = isDataPointFakeProperty
1353
1456
  ? {
1354
1457
  template: getTargetValueOnDataPoint(property)
1355
1458
  }
@@ -1361,7 +1464,19 @@ const getColumnDefinitionFromProperty = function(
1361
1464
  trueValue: property.type === "Edm.Boolean" ? "Yes" : undefined,
1362
1465
  falseValue: property.type === "Edm.Boolean" ? "No" : undefined
1363
1466
  };
1364
- return {
1467
+
1468
+ if (!isDataPointFakeProperty) {
1469
+ const oUnitProperty = getAssociatedCurrencyProperty(property) || getAssociatedUnitProperty(property);
1470
+ const sUnitText = property?.annotations?.Measures?.ISOCurrency || property?.annotations?.Measures?.Unit;
1471
+ if (oUnitProperty) {
1472
+ exportSettings.unitProperty = oUnitProperty.name;
1473
+ exportSettings.type = "Currency"; // Force to a currency because there's a unitProperty (otherwise the value isn't properly formatted when exported)
1474
+ } else if (sUnitText) {
1475
+ exportSettings.unit = `${sUnitText}`;
1476
+ }
1477
+ }
1478
+
1479
+ const oColumn: any = {
1365
1480
  key: key,
1366
1481
  isGroupable: !isDataPointFakeProperty && !isHidden ? aggregationHelper.isPropertyGroupable(property) : false,
1367
1482
  type: ColumnType.Annotation,
@@ -1384,7 +1499,13 @@ const getColumnDefinitionFromProperty = function(
1384
1499
  caseSensitive: isFilteringCaseSensitive(converterContext),
1385
1500
  typeConfig: oTypeConfig,
1386
1501
  visualSettings: isDataPointFakeProperty ? { widthCalculation: null } : undefined
1387
- } as AnnotationTableColumn;
1502
+ };
1503
+ const sTooltip = _getTooltip(property);
1504
+ if (sTooltip) {
1505
+ oColumn.tooltip = sTooltip;
1506
+ }
1507
+
1508
+ return oColumn as AnnotationTableColumn;
1388
1509
  };
1389
1510
 
1390
1511
  /**
@@ -1401,7 +1522,6 @@ const _isValidColumn = function(dataField: DataFieldAbstractTypes) {
1401
1522
  return !!dataField.Inline;
1402
1523
  case UIAnnotationTypes.DataFieldWithAction:
1403
1524
  case UIAnnotationTypes.DataFieldWithIntentBasedNavigation:
1404
- return false;
1405
1525
  case UIAnnotationTypes.DataField:
1406
1526
  case UIAnnotationTypes.DataFieldWithUrl:
1407
1527
  case UIAnnotationTypes.DataFieldForAnnotation:
@@ -1426,7 +1546,7 @@ const _isValidColumn = function(dataField: DataFieldAbstractTypes) {
1426
1546
  export const _getVisibleExpression = function(
1427
1547
  dataFieldModelPath: DataModelObjectPath,
1428
1548
  formatOptions?: any,
1429
- returnExpression?: Boolean
1549
+ returnExpression: boolean = false
1430
1550
  ): BindingExpression<string> {
1431
1551
  const targetObject: DataFieldAbstractTypes | DataPointTypeTypes = dataFieldModelPath.targetObject;
1432
1552
  let propertyValue;
@@ -1466,7 +1586,7 @@ export const _getVisibleExpression = function(
1466
1586
  or(not(isAnalyticalGroupHeaderExpanded), isAnalyticalLeaf)
1467
1587
  ]
1468
1588
  );
1469
- return returnExpression ? (expression as BindingExpression<string>) : compileBinding(expression);
1589
+ return returnExpression ? ((expression as any) as BindingExpression<string>) : compileBinding(expression);
1470
1590
  };
1471
1591
 
1472
1592
  /**
@@ -1479,7 +1599,7 @@ export const _getVisibleExpression = function(
1479
1599
  const _getFieldGroupHiddenExpressions = function(
1480
1600
  dataFieldGroup: DataFieldAbstractTypes,
1481
1601
  fieldFormatOptions: any
1482
- ): BindingExpression<string> {
1602
+ ): BindingExpression<string> | undefined {
1483
1603
  const aFieldGroupHiddenExpressions: BindingExpression<string>[] = [];
1484
1604
  if (
1485
1605
  dataFieldGroup.$Type === UIAnnotationTypes.DataFieldForAnnotation &&
@@ -1491,8 +1611,10 @@ const _getFieldGroupHiddenExpressions = function(
1491
1611
  );
1492
1612
  });
1493
1613
  return compileBinding(
1494
- ifElse(or(...(aFieldGroupHiddenExpressions as ExpressionOrPrimitive<boolean>[])), constant(true), constant(false))
1614
+ ifElse(or(...((aFieldGroupHiddenExpressions as any) as ExpressionOrPrimitive<boolean>[])), constant(true), constant(false))
1495
1615
  );
1616
+ } else {
1617
+ return undefined;
1496
1618
  }
1497
1619
  };
1498
1620
 
@@ -1533,6 +1655,34 @@ const _getLabel = function(property: DataFieldAbstractTypes | Property, isGroup:
1533
1655
  }
1534
1656
  };
1535
1657
 
1658
+ const _getTooltip = function(source: DataFieldAbstractTypes | Property): string | undefined {
1659
+ if (!source) {
1660
+ return undefined;
1661
+ }
1662
+
1663
+ if (isProperty(source)) {
1664
+ return source.annotations.Common?.QuickInfo
1665
+ ? compileBinding(annotationExpression(source.annotations.Common.QuickInfo.valueOf()))
1666
+ : undefined;
1667
+ } else if (isDataFieldTypes(source)) {
1668
+ return source.Value?.$target?.annotations?.Common?.QuickInfo
1669
+ ? compileBinding(annotationExpression(source.Value.$target.annotations.Common.QuickInfo.valueOf()))
1670
+ : undefined;
1671
+ } else if (source.$Type === UIAnnotationTypes.DataFieldForAnnotation) {
1672
+ const datapointTarget = source.Target?.$target as DataPoint;
1673
+ return datapointTarget?.Value?.$target?.annotations?.Common?.QuickInfo
1674
+ ? compileBinding(annotationExpression(datapointTarget.Value.$target.annotations.Common.QuickInfo.valueOf()))
1675
+ : undefined;
1676
+ } else {
1677
+ return undefined;
1678
+ }
1679
+ };
1680
+ export function getRowStatusVisibility(): Expression<boolean> {
1681
+ return formatResult(
1682
+ [bindingExpression(`semanticKeyHasDraftIndicator`, "internal"), bindingExpression(`filteredMessages`, "internal")],
1683
+ tableFormatters.getErrorStatusTextVisibilityFormatter
1684
+ );
1685
+ }
1536
1686
  /**
1537
1687
  * Creates a PropertyInfo for each identified property consumed by a LineItem.
1538
1688
  *
@@ -1669,6 +1819,8 @@ const _getRelativePath = function(dataField: DataFieldAbstractTypes): string {
1669
1819
  case UIAnnotationTypes.DataField:
1670
1820
  case UIAnnotationTypes.DataFieldWithNavigationPath:
1671
1821
  case UIAnnotationTypes.DataFieldWithUrl:
1822
+ case UIAnnotationTypes.DataFieldWithIntentBasedNavigation:
1823
+ case UIAnnotationTypes.DataFieldWithAction:
1672
1824
  relativePath = (dataField as DataField)?.Value?.path;
1673
1825
  break;
1674
1826
 
@@ -1767,13 +1919,72 @@ function getDefaultDraftIndicatorForColumn(name: string, semanticKeys: any[]) {
1767
1919
  if (bSemanticKeyFound) {
1768
1920
  return {
1769
1921
  hasDraftIndicator: true,
1770
- semantickeys: aSemanticKeyValues
1922
+ semantickeys: aSemanticKeyValues,
1923
+ objectStatusTextVisibility: compileBinding(getRowStatusVisibility())
1771
1924
  };
1772
1925
  } else {
1773
1926
  return {};
1774
1927
  }
1775
1928
  }
1776
1929
 
1930
+ /**
1931
+ * Returns the importance value for an annotation column.
1932
+ * If it is not set explicitly via annotations, the default annotation importance is returned.
1933
+ *
1934
+ * @param lineItem
1935
+ * @param semanticKeys
1936
+ * @returns {Importance} The importance value
1937
+ */
1938
+ function _getAnnotationImportance(lineItem: DataFieldAbstractTypes, semanticKeys: SemanticKey): Importance {
1939
+ switch (lineItem.annotations?.UI?.Importance) {
1940
+ case "UI.ImportanceType/High":
1941
+ return Importance.High;
1942
+ case "UI.ImportanceType/Medium":
1943
+ return Importance.Medium;
1944
+ case "UI.ImportanceType/Low":
1945
+ return Importance.Low;
1946
+ default:
1947
+ return _getDefaultAnnotationImportance(lineItem, semanticKeys);
1948
+ }
1949
+ }
1950
+
1951
+ /**
1952
+ * Returns the default importance value for an annotation column as inferred by semantic key configurations.
1953
+ *
1954
+ * @param lineItem
1955
+ * @param semanticKeys
1956
+ * @returns {Importance} The importance value
1957
+ */
1958
+ function _getDefaultAnnotationImportance(lineItem: DataFieldAbstractTypes, semanticKeys: SemanticKey): Importance {
1959
+ //Check if semanticKeys are defined at the EntitySet level
1960
+ if (!semanticKeys || semanticKeys.length === 0) {
1961
+ return Importance.None;
1962
+ }
1963
+
1964
+ if (lineItem.$Type === UIAnnotationTypes.DataFieldForAnnotation) {
1965
+ const targetDataField = (lineItem as DataFieldForAnnotation).Target?.$target;
1966
+
1967
+ //If a FieldGroup contains a semanticKey, importance set to High
1968
+ if (targetDataField.$Type === UIAnnotationTypes.FieldGroupType) {
1969
+ return ((targetDataField as unknown) as FieldGroupType).Data.some((dataField: DataFieldAbstractTypes) => {
1970
+ return (
1971
+ dataField.$Type !== UIAnnotationTypes.DataFieldForAnnotation &&
1972
+ ((dataField as unknown) as DataFieldTypes).Value &&
1973
+ ((dataField as unknown) as DataFieldTypes).Value.path &&
1974
+ semanticKeys.find(semanticKey => semanticKey.value === ((dataField as unknown) as DataFieldTypes).Value.path)
1975
+ );
1976
+ })
1977
+ ? Importance.High
1978
+ : Importance.None;
1979
+ }
1980
+ }
1981
+
1982
+ //If current field is a semanticKey, importance set to High
1983
+ return semanticKeys.find(semanticKey => semanticKey.value === (lineItem as DataFieldTypes).Value?.path)
1984
+ ? Importance.High
1985
+ : Importance.None;
1986
+ }
1987
+
1777
1988
  /**
1778
1989
  * Returns line items from metadata annotations.
1779
1990
  *
@@ -1793,11 +2004,10 @@ const getColumnsFromAnnotations = function(
1793
2004
  nonSortableColumns: string[] = getNonSortablePropertiesRestrictions(converterContext.getEntitySet()),
1794
2005
  tableManifestSettings: TableManifestConfiguration = converterContext.getManifestControlConfiguration(visualizationPath),
1795
2006
  tableType: TableType = tableManifestSettings?.tableSettings?.type || "ResponsiveTable";
1796
- const semanticKeys = converterContext.getAnnotationsByTerm("Common", "com.sap.vocabularies.Common.v1.SemanticKey", [
2007
+ const semanticKeys: SemanticKey = converterContext.getAnnotationsByTerm("Common", "com.sap.vocabularies.Common.v1.SemanticKey", [
1797
2008
  converterContext.getEntityType()
1798
2009
  ])[0];
1799
2010
  if (lineItemAnnotation) {
1800
- // Get columns from the LineItem Annotation
1801
2011
  lineItemAnnotation.forEach(lineItem => {
1802
2012
  if (!_isValidColumn(lineItem)) {
1803
2013
  return;
@@ -1816,10 +2026,9 @@ const getColumnsFromAnnotations = function(
1816
2026
  const sLabel: string | undefined = _getLabel(lineItem, isGroup);
1817
2027
  const name = _getAnnotationColumnName(lineItem);
1818
2028
  const isFieldGroupColumn: boolean = groupPath.indexOf("@com.sap.vocabularies.UI.v1.FieldGroup") > -1;
1819
- const showDataFieldsLabel: boolean =
1820
- isFieldGroupColumn && (lineItem as any)?.Target?.$target?.Data.length > 1
1821
- ? _getShowDataFieldsLabel(name, visualizationPath, converterContext)
1822
- : false;
2029
+ const showDataFieldsLabel: boolean = isFieldGroupColumn
2030
+ ? _getShowDataFieldsLabel(name, visualizationPath, converterContext)
2031
+ : false;
1823
2032
  const dataType: string | undefined = getDataFieldDataType(lineItem);
1824
2033
  const sDateInputFormat: string | undefined = dataType === "Edm.Date" ? "YYYY-MM-DD" : undefined;
1825
2034
  const formatOptions = {
@@ -1833,7 +2042,7 @@ const getColumnsFromAnnotations = function(
1833
2042
  ) {
1834
2043
  fieldGroupHiddenExpressions = _getFieldGroupHiddenExpressions(lineItem, formatOptions);
1835
2044
  }
1836
- const exportSettings = {
2045
+ const exportSettings: any = {
1837
2046
  template: relatedPropertiesInfo.exportSettingsTemplate,
1838
2047
  wrap: relatedPropertiesInfo.exportSettingsWrapping,
1839
2048
  type: dataType ? _getExportDataType(dataType, relatedPropertyNames.length > 1) : undefined,
@@ -1842,6 +2051,13 @@ const getColumnsFromAnnotations = function(
1842
2051
  trueValue: dataType === "Edm.Boolean" ? "Yes" : undefined,
1843
2052
  falseValue: dataType === "Edm.Boolean" ? "No" : undefined
1844
2053
  };
2054
+
2055
+ if (relatedPropertiesInfo.exportUnitName) {
2056
+ exportSettings.unitProperty = relatedPropertiesInfo.exportUnitName;
2057
+ exportSettings.type = "Currency"; // Force to a currency because there's a unitProperty (otherwise the value isn't properly formatted when exported)
2058
+ } else if (relatedPropertiesInfo.exportUnitString) {
2059
+ exportSettings.unit = relatedPropertiesInfo.exportUnitString;
2060
+ }
1845
2061
  const propertyTypeConfig = dataType && getTypeConfig(lineItem, dataType);
1846
2062
  const oTypeConfig = propertyTypeConfig
1847
2063
  ? {
@@ -1858,7 +2074,7 @@ const getColumnsFromAnnotations = function(
1858
2074
  // In case of text arrangement annotation with display mode as text only, exclude text property from the width calculation
1859
2075
  visualSettings = {
1860
2076
  widthCalculation: {
1861
- excludeProperties: "Property::" + relatedPropertiesInfo.visualSettingsToBeExcluded
2077
+ excludeProperties: ["Property::" + relatedPropertiesInfo.visualSettingsToBeExcluded]
1862
2078
  }
1863
2079
  };
1864
2080
  } else if (!dataType || !oTypeConfig) {
@@ -1866,7 +2082,19 @@ const getColumnsFromAnnotations = function(
1866
2082
  visualSettings.widthCalculation = null;
1867
2083
  }
1868
2084
 
1869
- annotationColumns.push({
2085
+ // TODO: For situation POC - increase width of the column with the situations indicator - works for the situations demo app only!
2086
+ // Might be a good idea to move the complete column width determination to the converter, that would allow us to widen
2087
+ // the columns as needed. This workaround only deals with Date columns.
2088
+ const { hasDraftIndicator } = getDefaultDraftIndicatorForColumn(name, semanticKeys);
2089
+ const widthOverride =
2090
+ (converterContext.getEntityType().annotations as any).FE?.Situations &&
2091
+ hasDraftIndicator &&
2092
+ lineItem.$Type === UIAnnotationTypes.DataField &&
2093
+ lineItem.Value.$target.type === "Edm.Date"
2094
+ ? "11em"
2095
+ : undefined;
2096
+
2097
+ const oColumn: any = {
1870
2098
  key: KeyHelper.generateKeyFromDataField(lineItem),
1871
2099
  type: ColumnType.Annotation,
1872
2100
  label: sLabel,
@@ -1883,14 +2111,21 @@ const getColumnsFromAnnotations = function(
1883
2111
  propertyInfos: relatedPropertyNames.length > 0 ? relatedPropertyNames : undefined,
1884
2112
  additionalPropertyInfos: additionalPropertyNames.length > 0 ? additionalPropertyNames : undefined,
1885
2113
  exportSettings: exportSettings,
1886
- width: lineItem.annotations?.HTML5?.CssDefaults?.width || undefined,
2114
+ width: lineItem.annotations?.HTML5?.CssDefaults?.width || widthOverride || undefined,
2115
+ importance: _getAnnotationImportance(lineItem, semanticKeys),
1887
2116
  isNavigable: true,
1888
2117
  formatOptions: formatOptions,
1889
2118
  exportContactProperty: relatedPropertiesInfo.exportSettingsContactProperty,
1890
2119
  caseSensitive: isFilteringCaseSensitive(converterContext),
1891
2120
  typeConfig: oTypeConfig,
1892
2121
  visualSettings: visualSettings
1893
- } as AnnotationTableColumn);
2122
+ };
2123
+ const sTooltip = _getTooltip(lineItem);
2124
+ if (sTooltip) {
2125
+ oColumn.tooltip = sTooltip;
2126
+ }
2127
+
2128
+ annotationColumns.push(oColumn as AnnotationTableColumn);
1894
2129
 
1895
2130
  // Collect information of related columns to be created.
1896
2131
  relatedPropertyNames.forEach(name => {
@@ -2021,36 +2256,53 @@ const getColumnsFromManifest = function(
2021
2256
  converterContext,
2022
2257
  entityType
2023
2258
  );
2024
-
2025
- internalColumns[key] = {
2026
- key: key,
2027
- id: "CustomColumn::" + key,
2028
- name: "CustomColumn::" + key,
2029
- header: manifestColumn.header,
2030
- width: manifestColumn.width || undefined,
2031
- horizontalAlign: _getManifestOrDefaultValue(manifestColumn?.horizontalAlign, HorizontalAlign.Begin, isAnnotationColumn),
2032
- type: manifestColumn.type === "Slot" ? ColumnType.Slot : ColumnType.Default,
2033
- availability: _getManifestOrDefaultValue(manifestColumn?.availability, AvailabilityType.Default, isAnnotationColumn),
2034
- template: manifestColumn.template || "undefined",
2035
- position: {
2036
- anchor: manifestColumn.position?.anchor,
2037
- placement: manifestColumn.position === undefined ? Placement.After : manifestColumn.position.placement
2038
- },
2039
- isNavigable: isAnnotationColumn ? undefined : isActionNavigable(manifestColumn, navigationSettings, true),
2040
- settings: manifestColumn.settings,
2041
- sortable: false,
2042
- propertyInfos: propertyInfos,
2043
- formatOptions: {
2044
- ...getDefaultFormatOptionsForTable(),
2045
- ...manifestColumn.formatOptions
2046
- },
2047
- exportSettings: {
2048
- template: propertyInfos ? _appendCustomTemplate(propertyInfos) : undefined,
2049
- fieldLabel: propertyInfos ? manifestColumn.header : undefined,
2050
- wrap: propertyInfos && propertyInfos.length > 1 ? true : false
2051
- },
2052
- caseSensitive: isFilteringCaseSensitive(converterContext)
2053
- };
2259
+ if (!manifestColumn?.template && manifestColumn?.type !== "Slot" && !isAnnotationColumn) {
2260
+ const Message = "The annotation column '" + key + "' referenced in the manifest is not found";
2261
+ converterContext
2262
+ .getDiagnostics()
2263
+ .addIssue(
2264
+ IssueCategory.Manifest,
2265
+ IssueSeverity.Low,
2266
+ Message,
2267
+ IssueCategoryType,
2268
+ IssueCategoryType?.AnnotationColumns?.InvalidKey
2269
+ );
2270
+ } else {
2271
+ internalColumns[key] = {
2272
+ key: key,
2273
+ id: "CustomColumn::" + key,
2274
+ name: "CustomColumn::" + key,
2275
+ header: manifestColumn.header,
2276
+ width: manifestColumn.width || undefined,
2277
+ importance: _getManifestOrDefaultValue(manifestColumn?.importance, Importance.None, isAnnotationColumn),
2278
+ horizontalAlign: _getManifestOrDefaultValue(manifestColumn?.horizontalAlign, HorizontalAlign.Begin, isAnnotationColumn),
2279
+ type: manifestColumn.type === "Slot" ? ColumnType.Slot : ColumnType.Default,
2280
+ availability: _getManifestOrDefaultValue(manifestColumn?.availability, AvailabilityType.Default, isAnnotationColumn),
2281
+ template: manifestColumn.template || "undefined",
2282
+ position: {
2283
+ anchor: manifestColumn.position?.anchor,
2284
+ placement: manifestColumn.position === undefined ? Placement.After : manifestColumn.position.placement
2285
+ },
2286
+ isNavigable: isAnnotationColumn ? undefined : isActionNavigable(manifestColumn, navigationSettings, true),
2287
+ settings: manifestColumn.settings,
2288
+ sortable: false,
2289
+ propertyInfos: propertyInfos,
2290
+ formatOptions: _getManifestOrDefaultValue(
2291
+ manifestColumn.formatOptions,
2292
+ {
2293
+ ...getDefaultFormatOptionsForTable(),
2294
+ ...manifestColumn.formatOptions
2295
+ },
2296
+ isAnnotationColumn
2297
+ ),
2298
+ exportSettings: {
2299
+ template: propertyInfos ? _appendCustomTemplate(propertyInfos) : undefined,
2300
+ fieldLabel: propertyInfos ? manifestColumn.header : undefined,
2301
+ wrap: propertyInfos && propertyInfos.length > 1 ? true : false
2302
+ },
2303
+ caseSensitive: isFilteringCaseSensitive(converterContext)
2304
+ };
2305
+ }
2054
2306
  }
2055
2307
  return internalColumns;
2056
2308
  };
@@ -2094,9 +2346,10 @@ export function getP13nMode(
2094
2346
  // No personalization configured in manifest.
2095
2347
  aPersonalization.push("Sort");
2096
2348
  aPersonalization.push("Column");
2097
- if (variantManagement === VariantManagementType.Control) {
2349
+ if (variantManagement === VariantManagementType.Control || _isFilterBarHidden(manifestWrapper, converterContext)) {
2098
2350
  // Feature parity with V2.
2099
2351
  // Enable table filtering by default only in case of Control level variant management.
2352
+ // Or when the LR filter bar is hidden via manifest setting
2100
2353
  aPersonalization.push("Filter");
2101
2354
  }
2102
2355
  if (bAnalyticalTable) {
@@ -2109,256 +2362,20 @@ export function getP13nMode(
2109
2362
  }
2110
2363
 
2111
2364
  /**
2112
- * Function to determine the visibility of the Delete button.
2365
+ * Returns a boolean suggesting if a filter bar is being used on the page.
2113
2366
  *
2114
- * @param converterContext The instance of the converter context
2115
- * @param navigationPath Path to the navigation entity
2116
- * @param isTargetDeletable Flag which determines whether a target is deletable
2117
- * @param viewConfiguration The instance of the configuration for the view path
2118
- * @returns {Expression<boolean>} The expression for the Delete button
2119
- */
2120
- export function getDeleteVisible(
2121
- converterContext: ConverterContext,
2122
- navigationPath: string,
2123
- isTargetDeletable: boolean,
2124
- viewConfiguration?: ViewPathConfiguration
2125
- ): Expression<boolean> {
2126
- const currentEntitySet = converterContext.getEntitySet();
2127
- const dataModelObjectPath = converterContext.getDataModelObjectPath();
2128
- const visitedNavigationPaths = dataModelObjectPath.navigationProperties.map(navProp => navProp.name);
2129
- const isDeleteHiddenExpression = currentEntitySet
2130
- ? annotationExpression(
2131
- (currentEntitySet?.annotations.UI?.DeleteHidden as PropertyAnnotationValue<boolean>) || false,
2132
- visitedNavigationPaths,
2133
- undefined,
2134
- (path: string) => singletonPathVisitor(path, converterContext, visitedNavigationPaths)
2135
- )
2136
- : constant(false);
2137
- const isDeleteHidden: any = compileBinding(isDeleteHiddenExpression);
2138
- let isParentDeletable, parentEntitySetDeletable;
2139
- if (converterContext.getTemplateType() === TemplateType.ObjectPage) {
2140
- isParentDeletable = isPathDeletable(converterContext.getDataModelObjectPath(), navigationPath);
2141
- parentEntitySetDeletable = isParentDeletable ? compileBinding(isParentDeletable) : isParentDeletable;
2142
- }
2143
- const bIsStickySessionSupported = converterContext.getDataModelObjectPath().startingEntitySet?.annotations?.Session
2144
- ?.StickySessionSupported
2145
- ? true
2146
- : false;
2147
- const bIsDraftRoot = currentEntitySet && currentEntitySet.annotations?.Common?.DraftRoot ? true : false;
2148
- const bIsDraftNode = currentEntitySet && currentEntitySet.annotations?.Common?.DraftNode ? true : false;
2149
- const bIsDraftParentEntityForContainment =
2150
- converterContext.getDataModelObjectPath().targetObject?.containsTarget &&
2151
- (converterContext.getDataModelObjectPath().startingEntitySet?.annotations?.Common?.DraftRoot ||
2152
- converterContext.getDataModelObjectPath().startingEntitySet?.annotations?.Common?.DraftNode)
2153
- ? true
2154
- : false;
2155
- if (
2156
- bIsDraftRoot ||
2157
- bIsDraftNode ||
2158
- bIsStickySessionSupported ||
2159
- (!converterContext.getEntitySet() && bIsDraftParentEntityForContainment)
2160
- ) {
2161
- //do not show case the delete button if parentEntitySetDeletable is false
2162
- if (parentEntitySetDeletable === "false") {
2163
- return constant(false);
2164
- //OP
2165
- } else if (parentEntitySetDeletable && isDeleteHidden !== "true") {
2166
- //Delete Hidden in case of true and path based
2167
- if (isDeleteHidden && isDeleteHidden !== "false") {
2168
- return and(equal(bindingExpression("/editMode", "ui"), "Editable"), not(isDeleteHiddenExpression));
2169
- } else {
2170
- return equal(bindingExpression("/editMode", "ui"), "Editable");
2171
- }
2172
- } else if (
2173
- isDeleteHidden === "true" ||
2174
- !isTargetDeletable ||
2175
- (viewConfiguration && converterContext.getManifestWrapper().hasMultipleVisualizations(viewConfiguration)) ||
2176
- converterContext.getTemplateType() === TemplateType.AnalyticalListPage
2177
- ) {
2178
- return constant(false);
2179
- } else if (converterContext.getTemplateType() !== TemplateType.ListReport) {
2180
- if (isDeleteHidden && isDeleteHidden === "false") {
2181
- return and(equal(bindingExpression("/editMode", "ui"), "Editable"), not(isDeleteHiddenExpression));
2182
- } else {
2183
- return equal(bindingExpression("/editMode", "ui"), "Editable");
2184
- }
2185
- } else if (isBinding(isDeleteHiddenExpression)) {
2186
- // UI.DeleteHidden annotation points to a path
2187
- return not(isDeleteHiddenExpression);
2188
- } else {
2189
- return constant(true);
2190
- }
2191
- } else {
2192
- return constant(false);
2193
- }
2194
- }
2195
-
2196
- /**
2197
- * Returns the enablement for the 'Mass Edit' button
2198
- *
2199
- * @param converterContext The converterContext
2200
- * @param bMassEditVisible The visibility of the 'Mass Edit' button
2201
- * @returns {*} Expression or Boolean value for the enablement of the 'Mass Edit' button
2202
- */
2203
-
2204
- export function getEnablementMassEdit(
2205
- converterContext: ConverterContext,
2206
- bMassEditVisible: string | boolean | undefined
2207
- ): string | boolean {
2208
- if (bMassEditVisible) {
2209
- const isParentUpdatable: any = isPathUpdatable(converterContext.getDataModelObjectPath(), undefined, true);
2210
- //when updatable is path based and pointing to current entity set property, that case is handled in table helper and runtime
2211
- if (isParentUpdatable?.currentEntityRestriction) {
2212
- return false;
2213
- }
2214
- const oExpression: any = compileBinding(isParentUpdatable);
2215
- return isParentUpdatable
2216
- ? "{= %{internal>numberOfSelectedContexts} >= 2 && " + compileBinding(isParentUpdatable, oExpression) + "}"
2217
- : false;
2218
- }
2219
- return false;
2220
- }
2221
-
2222
- /**
2223
- * Returns the visibility for the 'Mass Edit' button
2224
- *
2225
- * @param converterContext The converterContext
2226
- * @param tableManifestConfiguration The manifest configuration for the table
2227
- * @param targetCapabilities The target capability restrictions for the table
2228
- * @param selectionMode The selection mode for the table
2229
- * @returns {*} Expression or Boolean value for the visibility of the 'Mass Edit' button
2230
- */
2231
-
2232
- export function getVisibilityMassEdit(
2233
- converterContext: ConverterContext,
2234
- tableManifestConfiguration: TableControlConfiguration,
2235
- targetCapabilities: TableCapabilityRestriction,
2236
- selectionMode: string | undefined
2237
- ): boolean | string | undefined {
2238
- const entitySet = converterContext.getEntitySet(),
2239
- bUpdateHidden: any = entitySet && entitySet?.annotations.UI?.UpdateHidden?.valueOf(),
2240
- bMassEditEnabled: boolean = tableManifestConfiguration?.enableMassEdit || false,
2241
- iSelectionLimit: number = tableManifestConfiguration?.selectionLimit;
2242
- let bMassEditVisible: boolean = true;
2243
- if ((selectionMode && selectionMode === "Single") || (iSelectionLimit && iSelectionLimit < 2)) {
2244
- bMassEditVisible = false;
2245
- } else if (selectionMode && (selectionMode === "Auto" || selectionMode === "None")) {
2246
- bMassEditVisible = true;
2247
- }
2248
- if (targetCapabilities?.isUpdatable !== false && bMassEditVisible && bMassEditEnabled) {
2249
- if (bUpdateHidden && typeof bUpdateHidden === "boolean") {
2250
- return !bUpdateHidden && converterContext.getTemplateType() === TemplateType.ObjectPage ? compileBinding(UI.IsEditable) : false;
2251
- } else if (bUpdateHidden && bUpdateHidden?.path) {
2252
- return converterContext.getTemplateType() === TemplateType.ObjectPage
2253
- ? compileBinding(and(equal(UI.IsEditable, true), equal(annotationExpression(bUpdateHidden), false)))
2254
- : false;
2255
- }
2256
- return converterContext.getTemplateType() === TemplateType.ObjectPage ? compileBinding(UI.IsEditable) : false;
2257
- }
2258
- return false;
2259
- }
2260
-
2261
- /**
2262
- * Function to determine the visibility of the Create button.
2367
+ * Chart has a dependency to filter bar (issue with loading data). Once resolved, the check for chart should be removed here.
2368
+ * Until then, hiding filter bar is now allowed if a chart is being used on LR.
2263
2369
  *
2264
- * @param converterContext The instance of the converter context
2265
- * @param creationMode The mode used for creation
2266
- * @param isInsertable Annotation expression of InsertRestrictions.Insertable
2267
- * @param viewConfiguration The instance of the configuration for the view path
2268
- * @returns {Expression<boolean>} Expression or Boolean value of the 'UI.CreateHidden' annotation
2269
- */
2270
- export function getCreateVisible(
2271
- converterContext: ConverterContext,
2272
- creationMode: CreationMode | "External",
2273
- isInsertable: Expression<boolean>,
2274
- viewConfiguration?: ViewPathConfiguration
2275
- ): Expression<boolean> {
2276
- const currentEntitySet = converterContext.getEntitySet();
2277
- const dataModelObjectPath = converterContext.getDataModelObjectPath();
2278
- const visitedNavigationPaths = dataModelObjectPath.navigationProperties.map(navProp => navProp.name);
2279
- const isCreateHidden: Expression<boolean> = currentEntitySet
2280
- ? annotationExpression(
2281
- (currentEntitySet?.annotations.UI?.CreateHidden as PropertyAnnotationValue<boolean>) || false,
2282
- visitedNavigationPaths,
2283
- undefined,
2284
- (path: string) => singletonPathVisitor(path, converterContext, visitedNavigationPaths)
2285
- )
2286
- : constant(false);
2287
-
2288
- // if there is a custom new action the create button will be bound against this new action (instead of a POST action).
2289
- // The visibility of the create button then depends on the new action's OperationAvailable annotation (instead of the insertRestrictions):
2290
- // OperationAvailable = true or undefined -> create is visible
2291
- // OperationAvailable = false -> create is not visible
2292
- const newActionName: BindingExpression<string> = currentEntitySet?.annotations.Common?.DraftRoot?.NewAction?.toString();
2293
- const showCreateForNewAction = newActionName
2294
- ? annotationExpression(
2295
- converterContext?.getEntityType().actions[newActionName].annotations?.Core?.OperationAvailable?.valueOf(),
2296
- [],
2297
- true,
2298
- (path: string) => singletonPathVisitor(path, converterContext, [])
2299
- )
2300
- : undefined;
2301
- // - If it's statically not insertable -> create is not visible
2302
- // - If create is statically hidden -> create is not visible
2303
- // - If it's an ALP template -> create is not visible
2304
- // -
2305
- // - Otherwise
2306
- // - If the create mode is external -> create is visible
2307
- // - If we're on the list report ->
2308
- // - If UI.CreateHidden points to a property path -> provide a negated binding to this path
2309
- // - Otherwise, create is visible
2310
- // - Otherwise
2311
- // - This depends on the value of the the UI.IsEditable
2312
- return ifElse(
2313
- or(
2314
- or(
2315
- equal(showCreateForNewAction, false),
2316
- and(isConstant(isInsertable), equal(isInsertable, false), equal(showCreateForNewAction, undefined))
2317
- ),
2318
- isConstant(isCreateHidden) && equal(isCreateHidden, true),
2319
- or(
2320
- viewConfiguration ? converterContext.getManifestWrapper().hasMultipleVisualizations(viewConfiguration) : false,
2321
- converterContext.getTemplateType() === TemplateType.AnalyticalListPage
2322
- )
2323
- ),
2324
- false,
2325
- ifElse(
2326
- creationMode === "External",
2327
- true,
2328
- ifElse(
2329
- converterContext.getTemplateType() === TemplateType.ListReport,
2330
- ifElse(isBinding(isCreateHidden), not(isCreateHidden), true),
2331
- and(not(isCreateHidden), UI.IsEditable)
2332
- )
2333
- )
2334
- );
2335
- }
2336
-
2337
- /**
2338
- * Returns the visibility for the Paste button.
2339
- *
2340
- * @param converterContext The instance of the converter context
2341
- * @param creationBehaviour The chosen behavior of creation
2342
- * @param isInsertable The expression which denotes insert restrictions
2343
- * @param pasteEnabledInManifest The flag which denotes the paste enablement status via manifest
2344
- * @param viewConfiguration The instance of the configuration for the view path
2345
- * @returns {Expression<boolean>} Expression or Boolean value of the UI.CreateHidden annotation
2370
+ * @param {ManifestWrapper} manifestWrapper Manifest settings getter for the page
2371
+ * @param {ConverterContext} converterContext The instance of the converter context
2372
+ * @returns {boolean} Boolean suggesting if a filter bar is being used on the page.
2346
2373
  */
2347
- export function getPasteEnabled(
2348
- converterContext: ConverterContext,
2349
- creationBehaviour: TableAnnotationConfiguration["create"],
2350
- isInsertable: Expression<boolean>,
2351
- pasteEnabledInManifest: boolean,
2352
- viewConfiguration?: ViewPathConfiguration
2353
- ): Expression<boolean> {
2354
- // If create is not visible -> it's not enabled
2355
- // If create is visible ->
2356
- // If it's in the ListReport -> not enabled
2357
- // If it's insertable -> enabled
2358
- return ifElse(
2359
- pasteEnabledInManifest && equal(getCreateVisible(converterContext, creationBehaviour.mode, isInsertable, viewConfiguration), true),
2360
- converterContext.getTemplateType() === TemplateType.ObjectPage && isInsertable,
2361
- false
2374
+ function _isFilterBarHidden(manifestWrapper: ManifestWrapper, converterContext: ConverterContext): boolean {
2375
+ return (
2376
+ manifestWrapper.isFilterBarHidden() &&
2377
+ !converterContext.getManifestWrapper().hasMultipleVisualizations() &&
2378
+ converterContext.getTemplateType() !== TemplateType.AnalyticalListPage
2362
2379
  );
2363
2380
  }
2364
2381
 
@@ -2491,41 +2508,48 @@ export function getTableAnnotationConfiguration(
2491
2508
  p13nMode: string | undefined = getP13nMode(visualizationPath, converterContext, tableManifestConfiguration),
2492
2509
  id = navigationPropertyPath ? TableID(visualizationPath) : TableID(converterContext.getContextPath(), "LineItem");
2493
2510
  const targetCapabilities = getCapabilityRestriction(converterContext);
2494
- const isDeleteButtonVisible = getDeleteVisible(
2511
+ const navigationTargetPath = getNavigationTargetPath(converterContext, navigationPropertyPath);
2512
+ const navigationSettings = pageManifestSettings.getNavigationConfiguration(navigationTargetPath);
2513
+ const creationBehaviour = _getCreationBehaviour(lineItemAnnotation, tableManifestConfiguration, converterContext, navigationSettings);
2514
+ const standardActionsContext = generateStandardActionsContext(
2495
2515
  converterContext,
2496
- navigationPropertyPath,
2497
- targetCapabilities.isDeletable,
2516
+ creationBehaviour.mode as CreationMode,
2517
+ tableManifestConfiguration,
2498
2518
  viewConfiguration
2499
2519
  );
2520
+
2521
+ const deleteButtonVisibilityExpression = getDeleteVisibility(converterContext, standardActionsContext);
2522
+ const createButtonVisibilityExpression = getCreateVisibility(converterContext, standardActionsContext);
2523
+ const massEditButtonVisibilityExpression = getMassEditVisibility(converterContext, standardActionsContext);
2524
+ const isInsertUpdateTemplated = getInsertUpdateActionsTemplating(
2525
+ standardActionsContext,
2526
+ isDraftOrStickySupported(converterContext),
2527
+ compileBinding(createButtonVisibilityExpression) === "false"
2528
+ );
2529
+
2500
2530
  const selectionMode = getSelectionMode(
2501
2531
  lineItemAnnotation,
2502
2532
  visualizationPath,
2503
2533
  converterContext,
2504
2534
  hasAbsolutePath,
2505
2535
  targetCapabilities,
2506
- isDeleteButtonVisible
2536
+ deleteButtonVisibilityExpression,
2537
+ massEditButtonVisibilityExpression
2507
2538
  );
2508
2539
  let threshold = navigationPropertyPath ? 10 : 30;
2509
2540
  if (presentationVariantAnnotation?.MaxItems) {
2510
2541
  threshold = presentationVariantAnnotation.MaxItems.valueOf() as number;
2511
2542
  }
2512
- const navigationTargetPath = getNavigationTargetPath(converterContext, navigationPropertyPath);
2513
- const navigationSettings = pageManifestSettings.getNavigationConfiguration(navigationTargetPath);
2514
- const creationBehaviour = _getCreationBehaviour(lineItemAnnotation, tableManifestConfiguration, converterContext, navigationSettings);
2515
- let isParentDeletable: any, parentEntitySetDeletable;
2516
- if (converterContext.getTemplateType() === TemplateType.ObjectPage) {
2517
- isParentDeletable = isPathDeletable(converterContext.getDataModelObjectPath(), undefined, true);
2518
- if (isParentDeletable?.currentEntityRestriction) {
2519
- parentEntitySetDeletable = undefined;
2520
- } else {
2521
- parentEntitySetDeletable = isParentDeletable ? compileBinding(isParentDeletable, true) : isParentDeletable;
2522
- }
2523
- }
2524
- const dataModelObjectPath = converterContext.getDataModelObjectPath();
2525
- const isInsertable: Expression<boolean> = isPathInsertable(dataModelObjectPath);
2543
+
2526
2544
  const variantManagement: VariantManagementType = pageManifestSettings.getVariantManagement();
2527
- const bMassEditVisible: any = getVisibilityMassEdit(converterContext, tableManifestConfiguration, targetCapabilities, selectionMode);
2528
2545
  const isSearchable = isPathSearchable(converterContext.getDataModelObjectPath());
2546
+ const standardActions = {
2547
+ create: getStandardActionCreate(converterContext, standardActionsContext),
2548
+ "delete": getStandardActionDelete(converterContext, standardActionsContext),
2549
+ paste: getStandardActionPaste(converterContext, standardActionsContext, isInsertUpdateTemplated),
2550
+ massEdit: getStandardActionMassEdit(converterContext, standardActionsContext),
2551
+ creationRow: getCreationRow(converterContext, standardActionsContext)
2552
+ };
2529
2553
 
2530
2554
  return {
2531
2555
  id: id,
@@ -2540,34 +2564,22 @@ export function getTableAnnotationConfiguration(
2540
2564
  navigationTargetPath
2541
2565
  ),
2542
2566
  p13nMode: p13nMode,
2543
- show: {
2544
- "delete": compileBinding(isDeleteButtonVisible),
2545
- create: compileBinding(getCreateVisible(converterContext, creationBehaviour?.mode, isInsertable)),
2546
- paste: compileBinding(
2547
- getPasteEnabled(
2548
- converterContext,
2549
- creationBehaviour,
2550
- isInsertable,
2551
- tableManifestConfiguration.enablePaste,
2552
- viewConfiguration
2553
- )
2554
- ),
2555
- massEdit: {
2556
- visible: bMassEditVisible,
2557
- enabled: getEnablementMassEdit(converterContext, bMassEditVisible)
2558
- }
2567
+ standardActions: {
2568
+ actions: standardActions,
2569
+ isInsertUpdateTemplated: isInsertUpdateTemplated,
2570
+ updatablePropertyPath: getCurrentEntitySetUpdatablePath(converterContext)
2559
2571
  },
2560
2572
  displayMode: isInDisplayMode(converterContext, viewConfiguration),
2561
2573
  create: creationBehaviour,
2562
2574
  selectionMode: selectionMode,
2563
2575
  autoBindOnInit:
2564
- converterContext.getTemplateType() !== TemplateType.ListReport &&
2565
- converterContext.getTemplateType() !== TemplateType.AnalyticalListPage &&
2566
- !(viewConfiguration && converterContext.getManifestWrapper().hasMultipleVisualizations(viewConfiguration)),
2576
+ _isFilterBarHidden(pageManifestSettings, converterContext) ||
2577
+ (converterContext.getTemplateType() !== TemplateType.ListReport &&
2578
+ converterContext.getTemplateType() !== TemplateType.AnalyticalListPage &&
2579
+ !(viewConfiguration && pageManifestSettings.hasMultipleVisualizations(viewConfiguration))),
2567
2580
  variantManagement: variantManagement === "Control" && !p13nMode ? VariantManagementType.None : variantManagement,
2568
2581
  threshold: threshold,
2569
2582
  sortConditions: getSortConditions(converterContext, presentationVariantAnnotation, columns),
2570
- parentEntityDeleteEnabled: parentEntitySetDeletable,
2571
2583
  title: title,
2572
2584
  searchable: tableManifestConfiguration.type !== "AnalyticalTable" && !(isConstant(isSearchable) && isSearchable.value === false)
2573
2585
  };
@@ -2606,19 +2618,6 @@ function _getExportDataType(dataType: string, isComplexProperty: boolean = false
2606
2618
  return exportDataType;
2607
2619
  }
2608
2620
 
2609
- function isInDisplayMode(converterContext: ConverterContext, viewConfiguration?: ViewPathConfiguration): boolean {
2610
- const templateType = converterContext.getTemplateType();
2611
- if (
2612
- templateType === TemplateType.ListReport ||
2613
- templateType === TemplateType.AnalyticalListPage ||
2614
- (viewConfiguration && converterContext.getManifestWrapper().hasMultipleVisualizations(viewConfiguration))
2615
- ) {
2616
- return true;
2617
- }
2618
- // updatable will be handled at the property level
2619
- return false;
2620
- }
2621
-
2622
2621
  /**
2623
2622
  * Split the visualization path into the navigation property path and annotation.
2624
2623
  *
@@ -2659,118 +2658,237 @@ export function getSelectionVariantConfiguration(
2659
2658
  return undefined;
2660
2659
  }
2661
2660
 
2661
+ function _getFullScreenBasedOnDevice(
2662
+ tableSettings: TableManifestSettingsConfiguration,
2663
+ converterContext: ConverterContext,
2664
+ isIphone: boolean
2665
+ ): boolean {
2666
+ // If enableFullScreen is not set, use as default true on phone and false otherwise
2667
+ let enableFullScreen = tableSettings.enableFullScreen ?? isIphone;
2668
+ // Make sure that enableFullScreen is not set on ListReport for desktop or tablet
2669
+ if (!isIphone && enableFullScreen && converterContext.getTemplateType() === TemplateType.ListReport) {
2670
+ enableFullScreen = false;
2671
+ converterContext.getDiagnostics().addIssue(IssueCategory.Manifest, IssueSeverity.Low, IssueType.FULLSCREENMODE_NOT_ON_LISTREPORT);
2672
+ }
2673
+ return enableFullScreen;
2674
+ }
2675
+
2676
+ function _getMultiSelectMode(
2677
+ tableSettings: TableManifestSettingsConfiguration,
2678
+ tableType: TableType,
2679
+ converterContext: ConverterContext
2680
+ ): string | undefined {
2681
+ let multiSelectMode: string | undefined;
2682
+ if (tableType !== "ResponsiveTable") {
2683
+ return undefined;
2684
+ }
2685
+ switch (converterContext.getTemplateType()) {
2686
+ case TemplateType.ListReport:
2687
+ case TemplateType.AnalyticalListPage:
2688
+ multiSelectMode = !tableSettings.selectAll ? "ClearAll" : "Default";
2689
+ break;
2690
+ case TemplateType.ObjectPage:
2691
+ multiSelectMode = tableSettings.selectAll === false ? "ClearAll" : "Default";
2692
+ if (converterContext.getManifestWrapper().useIconTabBar()) {
2693
+ multiSelectMode = !tableSettings.selectAll ? "ClearAll" : "Default";
2694
+ }
2695
+ break;
2696
+ default:
2697
+ }
2698
+
2699
+ return multiSelectMode;
2700
+ }
2701
+
2702
+ function _getTableType(
2703
+ tableSettings: TableManifestSettingsConfiguration,
2704
+ aggregationHelper: AggregationHelper,
2705
+ converterContext: ConverterContext
2706
+ ): TableType {
2707
+ let tableType = tableSettings?.type || "ResponsiveTable";
2708
+ if (converterContext.getTemplateType() !== "ObjectPage") {
2709
+ if (tableSettings?.type === "AnalyticalTable" && !aggregationHelper.isAnalyticsSupported()) {
2710
+ tableType = "GridTable";
2711
+ }
2712
+ if (!tableSettings?.type) {
2713
+ if (converterContext.getManifestWrapper().isDesktop() && aggregationHelper.isAnalyticsSupported()) {
2714
+ tableType = "AnalyticalTable";
2715
+ } else {
2716
+ tableType = "ResponsiveTable";
2717
+ }
2718
+ }
2719
+ }
2720
+ return tableType;
2721
+ }
2722
+
2723
+ function _getFilters(
2724
+ tableSettings: TableManifestSettingsConfiguration,
2725
+ quickFilterPaths: { annotationPath: string }[],
2726
+ quickSelectionVariant: any,
2727
+ path: { annotationPath: string },
2728
+ converterContext: ConverterContext
2729
+ ): any {
2730
+ if (quickSelectionVariant) {
2731
+ quickFilterPaths.push({ annotationPath: path.annotationPath });
2732
+ }
2733
+ return {
2734
+ quickFilters: {
2735
+ enabled:
2736
+ converterContext.getTemplateType() === TemplateType.ListReport ? "{= ${pageInternal>hasPendingFilters} !== true}" : true,
2737
+ showCounts: tableSettings?.quickVariantSelection?.showCounts,
2738
+ paths: quickFilterPaths
2739
+ }
2740
+ };
2741
+ }
2742
+
2743
+ function _getEnableExport(
2744
+ tableSettings: TableManifestSettingsConfiguration,
2745
+ converterContext: ConverterContext,
2746
+ enablePaste: boolean
2747
+ ): boolean {
2748
+ return tableSettings.enableExport !== undefined
2749
+ ? tableSettings.enableExport
2750
+ : converterContext.getTemplateType() !== "ObjectPage" || enablePaste;
2751
+ }
2752
+
2753
+ function _getFilterConfiguration(
2754
+ tableSettings: TableManifestSettingsConfiguration,
2755
+ lineItemAnnotation: LineItem | undefined,
2756
+ converterContext: ConverterContext
2757
+ ): any {
2758
+ if (!lineItemAnnotation) {
2759
+ return {};
2760
+ }
2761
+ const quickFilterPaths: { annotationPath: string }[] = [];
2762
+ const targetEntityType = converterContext.getAnnotationEntityType(lineItemAnnotation);
2763
+ let quickSelectionVariant: any;
2764
+ let filters;
2765
+ tableSettings?.quickVariantSelection?.paths?.forEach((path: { annotationPath: string }) => {
2766
+ quickSelectionVariant = targetEntityType.resolvePath("@" + path.annotationPath);
2767
+ filters = _getFilters(tableSettings, quickFilterPaths, quickSelectionVariant, path, converterContext);
2768
+ });
2769
+
2770
+ let hideTableTitle = false;
2771
+ hideTableTitle = !!tableSettings.quickVariantSelection?.hideTableTitle;
2772
+ return {
2773
+ filters: filters,
2774
+ headerVisible: !(quickSelectionVariant && hideTableTitle)
2775
+ };
2776
+ }
2777
+
2662
2778
  export function getTableManifestConfiguration(
2663
2779
  lineItemAnnotation: LineItem | undefined,
2664
2780
  visualizationPath: string,
2665
2781
  converterContext: ConverterContext,
2666
- checkCondensedLayout: boolean = false
2782
+ checkCondensedLayout = false
2667
2783
  ): TableControlConfiguration {
2668
2784
  const tableManifestSettings: TableManifestConfiguration = converterContext.getManifestControlConfiguration(visualizationPath);
2669
2785
  const tableSettings = (tableManifestSettings && tableManifestSettings.tableSettings) || {};
2670
- let quickSelectionVariant: any;
2671
- const quickFilterPaths: { annotationPath: string }[] = [];
2672
- let enableExport = true;
2673
- let creationMode = CreationMode.NewPage;
2674
- let filters;
2675
- let createAtEnd = true;
2676
- let disableAddRowButtonForEmptyData = false;
2677
- let customValidationFunction;
2678
- let condensedTableLayout = false;
2679
- let hideTableTitle = false;
2680
- let tableType: TableType = "ResponsiveTable";
2681
- let enableFullScreen = false;
2682
- let selectionLimit = 200;
2683
- let multiSelectMode;
2684
- const enableAutoColumnWidth = true;
2685
- let enablePaste = converterContext.getTemplateType() === "ObjectPage";
2786
+ const creationMode = CreationMode.NewPage;
2787
+ const enableAutoColumnWidth = !converterContext.getManifestWrapper().isPhone();
2788
+ const enablePaste =
2789
+ tableSettings.enablePaste !== undefined ? tableSettings.enablePaste : converterContext.getTemplateType() === "ObjectPage"; // Paste is disabled by default excepted for OP
2790
+ const dataStateIndicatorFilter =
2791
+ converterContext.getTemplateType() === TemplateType.ListReport ? "API.dataStateIndicatorFilter" : undefined;
2686
2792
  const isCondensedTableLayoutCompliant = checkCondensedLayout && converterContext.getManifestWrapper().isCondensedLayoutCompliant();
2793
+ const oFilterConfiguration = _getFilterConfiguration(tableSettings, lineItemAnnotation, converterContext);
2794
+ const customValidationFunction = tableSettings.creationMode?.customValidationFunction;
2795
+ const condensedTableLayout = tableSettings.condensedTableLayout !== undefined ? tableSettings.condensedTableLayout : false;
2687
2796
  const entityType = converterContext.getEntityType();
2688
2797
  const aggregationHelper = new AggregationHelper(entityType, converterContext);
2689
- if (lineItemAnnotation) {
2690
- const targetEntityType = converterContext.getAnnotationEntityType(lineItemAnnotation);
2691
- tableSettings?.quickVariantSelection?.paths?.forEach((path: { annotationPath: string }) => {
2692
- quickSelectionVariant = targetEntityType.resolvePath("@" + path.annotationPath);
2693
- // quickSelectionVariant = converterContext.getEntityTypeAnnotation(path.annotationPath);
2694
- if (quickSelectionVariant) {
2695
- quickFilterPaths.push({ annotationPath: path.annotationPath });
2696
- }
2697
- filters = {
2698
- quickFilters: {
2699
- enabled:
2700
- converterContext.getTemplateType() === TemplateType.ListReport
2701
- ? "{= ${pageInternal>hasPendingFilters} !== true}"
2702
- : true,
2703
- showCounts: tableSettings?.quickVariantSelection?.showCounts,
2704
- paths: quickFilterPaths
2705
- }
2706
- };
2707
- });
2708
- creationMode = tableSettings.creationMode?.name || creationMode;
2709
- createAtEnd = tableSettings.creationMode?.createAtEnd !== undefined ? tableSettings.creationMode?.createAtEnd : true;
2710
- customValidationFunction = tableSettings.creationMode?.customValidationFunction;
2711
- // if a custom validation function is provided, disableAddRowButtonForEmptyData should not be considered, i.e. set to false
2712
- disableAddRowButtonForEmptyData = !customValidationFunction ? !!tableSettings.creationMode?.disableAddRowButtonForEmptyData : false;
2713
- condensedTableLayout = tableSettings.condensedTableLayout !== undefined ? tableSettings.condensedTableLayout : false;
2714
- hideTableTitle = !!tableSettings.quickVariantSelection?.hideTableTitle;
2715
- tableType = tableSettings?.type || "ResponsiveTable";
2716
- if (converterContext.getTemplateType() !== "ObjectPage") {
2717
- if (tableSettings?.type === "AnalyticalTable" && !aggregationHelper.isAnalyticsSupported()) {
2718
- tableType = "GridTable";
2719
- }
2720
- if (!tableSettings?.type) {
2721
- if (converterContext.getManifestWrapper().isDesktop() && aggregationHelper.isAnalyticsSupported()) {
2722
- tableType = "AnalyticalTable";
2723
- } else {
2724
- tableType = "ResponsiveTable";
2725
- }
2726
- }
2727
- }
2728
- enableFullScreen = tableSettings.enableFullScreen || false;
2729
- if (enableFullScreen === true && converterContext.getTemplateType() === TemplateType.ListReport) {
2730
- enableFullScreen = false;
2731
- converterContext
2732
- .getDiagnostics()
2733
- .addIssue(IssueCategory.Manifest, IssueSeverity.Low, IssueType.FULLSCREENMODE_NOT_ON_LISTREPORT);
2734
- }
2735
- selectionLimit = tableSettings.selectAll === true || tableSettings.selectionLimit === 0 ? 0 : tableSettings.selectionLimit || 200;
2736
- if (tableType === "ResponsiveTable") {
2737
- if (
2738
- converterContext.getTemplateType() === TemplateType.ListReport ||
2739
- converterContext.getTemplateType() === TemplateType.AnalyticalListPage
2740
- ) {
2741
- multiSelectMode = !!tableSettings.selectAll ? "Default" : "ClearAll";
2742
- }
2743
- if (converterContext.getTemplateType() === TemplateType.ObjectPage) {
2744
- if (converterContext.getManifestWrapper().useIconTabBar()) {
2745
- multiSelectMode = !!tableSettings.selectAll ? "Default" : "ClearAll";
2746
- } else {
2747
- multiSelectMode = tableSettings.selectAll === false ? "ClearAll" : "Default";
2748
- }
2749
- }
2750
- }
2751
- enablePaste = converterContext.getTemplateType() === "ObjectPage" && tableSettings.enablePaste !== false;
2752
- enableExport =
2753
- tableSettings.enableExport !== undefined
2754
- ? tableSettings.enableExport
2755
- : converterContext.getTemplateType() !== "ObjectPage" || enablePaste;
2756
- }
2757
- return {
2758
- filters: filters,
2759
- type: tableType,
2760
- enableFullScreen: enableFullScreen,
2761
- headerVisible: !(quickSelectionVariant && hideTableTitle),
2762
- enableExport: enableExport,
2763
- creationMode: creationMode,
2764
- createAtEnd: createAtEnd,
2765
- disableAddRowButtonForEmptyData: disableAddRowButtonForEmptyData,
2798
+ const tableType: TableType = _getTableType(tableSettings, aggregationHelper, converterContext);
2799
+ const oConfiguration = {
2800
+ createAtEnd: tableSettings.creationMode?.createAtEnd !== undefined ? tableSettings.creationMode?.createAtEnd : true,
2801
+ creationMode: tableSettings.creationMode?.name || creationMode,
2766
2802
  customValidationFunction: customValidationFunction,
2767
- useCondensedTableLayout: condensedTableLayout && isCondensedTableLayoutCompliant,
2768
- selectionLimit: selectionLimit,
2769
- multiSelectMode: multiSelectMode,
2803
+ dataStateIndicatorFilter: dataStateIndicatorFilter,
2804
+ // if a custom validation function is provided, disableAddRowButtonForEmptyData should not be considered, i.e. set to false
2805
+ disableAddRowButtonForEmptyData: !customValidationFunction ? !!tableSettings.creationMode?.disableAddRowButtonForEmptyData : false,
2806
+ enableAutoColumnWidth: enableAutoColumnWidth,
2807
+ enableExport: _getEnableExport(tableSettings, converterContext, enablePaste),
2808
+ enableFullScreen: _getFullScreenBasedOnDevice(tableSettings, converterContext, converterContext.getManifestWrapper().isPhone()),
2809
+ enableMassEdit: tableSettings?.enableMassEdit,
2770
2810
  enablePaste: enablePaste,
2811
+ headerVisible: true,
2812
+ multiSelectMode: _getMultiSelectMode(tableSettings, tableType, converterContext),
2813
+ selectionLimit: tableSettings.selectAll === true || tableSettings.selectionLimit === 0 ? 0 : tableSettings.selectionLimit || 200,
2814
+
2771
2815
  showRowCount:
2772
2816
  !tableSettings?.quickVariantSelection?.showCounts && !converterContext.getManifestWrapper().getViewConfiguration()?.showCounts,
2773
- enableMassEdit: tableSettings?.enableMassEdit,
2774
- enableAutoColumnWidth: enableAutoColumnWidth
2817
+ type: tableType,
2818
+ useCondensedTableLayout: condensedTableLayout && isCondensedTableLayoutCompliant
2819
+ };
2820
+
2821
+ return { ...oConfiguration, ...oFilterConfiguration };
2822
+ }
2823
+
2824
+ export type configTypeConstraints = {
2825
+ scale?: number;
2826
+ precision?: number;
2827
+ maxLength?: number;
2828
+ nullable?: boolean;
2829
+ minimum?: string;
2830
+ maximum?: string;
2831
+ isDigitSequence?: boolean;
2832
+ };
2833
+
2834
+ export type configTypeformatOptions = {
2835
+ parseAsString?: boolean;
2836
+ emptyString?: string;
2837
+ parseKeepsEmptyString?: boolean;
2838
+ };
2839
+
2840
+ export type configType = {
2841
+ type: string;
2842
+ constraints: configTypeConstraints;
2843
+ formatOptions: configTypeformatOptions;
2844
+ };
2845
+
2846
+ export function getTypeConfig(oProperty: Property | DataFieldAbstractTypes, dataType: string | undefined): any {
2847
+ let oTargetMapping = EDM_TYPE_MAPPING[(oProperty as Property)?.type] || (dataType ? EDM_TYPE_MAPPING[dataType] : undefined);
2848
+ if (!oTargetMapping && (oProperty as Property)?.targetType && (oProperty as Property).targetType?._type === "TypeDefinition") {
2849
+ oTargetMapping = EDM_TYPE_MAPPING[((oProperty as Property).targetType as TypeDefinition).underlyingType];
2850
+ }
2851
+ const propertyTypeConfig: configType = {
2852
+ type: oTargetMapping?.type,
2853
+ constraints: {},
2854
+ formatOptions: {}
2855
+ };
2856
+ if (isProperty(oProperty)) {
2857
+ propertyTypeConfig.constraints = {
2858
+ scale: oTargetMapping.constraints?.$Scale ? oProperty.scale : undefined,
2859
+ precision: oTargetMapping.constraints?.$Precision ? oProperty.precision : undefined,
2860
+ maxLength: oTargetMapping.constraints?.$MaxLength ? oProperty.maxLength : undefined,
2861
+ nullable: oTargetMapping.constraints?.$Nullable ? oProperty.nullable : undefined,
2862
+ minimum:
2863
+ oTargetMapping.constraints?.["@Org.OData.Validation.V1.Minimum/$Decimal"] &&
2864
+ !isNaN(oProperty.annotations?.Validation?.Minimum)
2865
+ ? `${oProperty.annotations?.Validation?.Minimum}`
2866
+ : undefined,
2867
+ maximum:
2868
+ oTargetMapping.constraints?.["@Org.OData.Validation.V1.Maximum/$Decimal"] &&
2869
+ !isNaN(oProperty.annotations?.Validation?.Maximum)
2870
+ ? `${oProperty.annotations?.Validation?.Maximum}`
2871
+ : undefined,
2872
+ isDigitSequence:
2873
+ propertyTypeConfig.type === "sap.ui.model.odata.type.String" &&
2874
+ oTargetMapping.constraints?.["@com.sap.vocabularies.Common.v1.IsDigitSequence"] &&
2875
+ (oProperty as Property).annotations?.Common?.IsDigitSequence
2876
+ ? true
2877
+ : undefined
2878
+ };
2879
+ }
2880
+ propertyTypeConfig.formatOptions = {
2881
+ parseAsString:
2882
+ propertyTypeConfig?.type?.indexOf("sap.ui.model.odata.type.Int") === 0 ||
2883
+ propertyTypeConfig?.type?.indexOf("sap.ui.model.odata.type.Double") === 0
2884
+ ? false
2885
+ : undefined,
2886
+ emptyString:
2887
+ propertyTypeConfig?.type?.indexOf("sap.ui.model.odata.type.Int") === 0 ||
2888
+ propertyTypeConfig?.type?.indexOf("sap.ui.model.odata.type.Double") === 0
2889
+ ? ""
2890
+ : undefined,
2891
+ parseKeepsEmptyString: propertyTypeConfig.type === "sap.ui.model.odata.type.String" ? true : undefined
2775
2892
  };
2893
+ return propertyTypeConfig;
2776
2894
  }