@sapui5/sap.fe.core 1.97.0 → 1.100.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (306) hide show
  1. package/package.json +7 -4
  2. package/src/sap/fe/core/.library +1 -1
  3. package/src/sap/fe/core/AnnotationHelper.js +309 -405
  4. package/src/sap/fe/core/AnnotationHelper.ts +315 -0
  5. package/src/sap/fe/core/AppComponent.js +389 -397
  6. package/src/sap/fe/core/AppComponent.ts +403 -0
  7. package/src/sap/fe/core/AppStateHandler.js +198 -181
  8. package/src/sap/fe/core/AppStateHandler.ts +171 -0
  9. package/src/sap/fe/core/BaseController.js +83 -58
  10. package/src/sap/fe/core/BaseController.ts +68 -0
  11. package/src/sap/fe/core/BusyLocker.js +105 -121
  12. package/src/sap/fe/core/BusyLocker.ts +98 -0
  13. package/src/sap/fe/core/CommonUtils.js +2164 -2379
  14. package/src/sap/fe/core/CommonUtils.ts +2177 -0
  15. package/src/sap/fe/core/ExtensionAPI.js +279 -266
  16. package/src/sap/fe/core/ExtensionAPI.ts +250 -0
  17. package/src/sap/fe/core/PageController.js +218 -125
  18. package/src/sap/fe/core/PageController.ts +129 -0
  19. package/src/sap/fe/core/RouterProxy.js +924 -807
  20. package/src/sap/fe/core/RouterProxy.ts +840 -0
  21. package/src/sap/fe/core/Synchronization.js +41 -35
  22. package/src/sap/fe/core/Synchronization.ts +29 -0
  23. package/src/sap/fe/core/TemplateComponent.js +173 -155
  24. package/src/sap/fe/core/TemplateComponent.ts +173 -0
  25. package/src/sap/fe/core/TemplateModel.js +79 -54
  26. package/src/sap/fe/core/TemplateModel.ts +63 -0
  27. package/src/sap/fe/core/TransactionHelper.js +1560 -1579
  28. package/src/sap/fe/core/TransactionHelper.ts +1717 -0
  29. package/src/sap/fe/core/actions/collaboration/ActivitySync.js +392 -0
  30. package/src/sap/fe/core/actions/collaboration/ActivitySync.ts +355 -0
  31. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.js +136 -0
  32. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.ts +119 -0
  33. package/src/sap/fe/core/actions/collaboration/Manage.js +262 -0
  34. package/src/sap/fe/core/actions/collaboration/Manage.ts +244 -0
  35. package/src/sap/fe/core/actions/collaboration/ManageDialog.fragment.xml +103 -0
  36. package/src/sap/fe/core/actions/collaboration/UserDetails.fragment.xml +13 -0
  37. package/src/sap/fe/core/actions/draft.js +521 -581
  38. package/src/sap/fe/core/actions/draft.ts +566 -0
  39. package/src/sap/fe/core/actions/messageHandling.js +564 -511
  40. package/src/sap/fe/core/actions/messageHandling.ts +552 -0
  41. package/src/sap/fe/core/actions/nonDraft.js +17 -19
  42. package/src/sap/fe/core/actions/nonDraft.ts +12 -0
  43. package/src/sap/fe/core/actions/operations.js +1093 -1211
  44. package/src/sap/fe/core/actions/operations.ts +1192 -0
  45. package/src/sap/fe/core/actions/sticky.js +114 -104
  46. package/src/sap/fe/core/actions/sticky.ts +119 -0
  47. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +70 -66
  48. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.ts +65 -0
  49. package/src/sap/fe/core/controllerextensions/EditFlow.js +1594 -1701
  50. package/src/sap/fe/core/controllerextensions/EditFlow.ts +1672 -0
  51. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +80 -54
  52. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +61 -0
  53. package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +719 -505
  54. package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +783 -0
  55. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +797 -813
  56. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +803 -0
  57. package/src/sap/fe/core/controllerextensions/InternalRouting.js +1005 -973
  58. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +978 -0
  59. package/src/sap/fe/core/controllerextensions/KPIManagement.js +530 -476
  60. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +137 -46
  61. package/src/sap/fe/core/controllerextensions/MassEdit.js +144 -0
  62. package/src/sap/fe/core/controllerextensions/MassEdit.ts +156 -0
  63. package/src/sap/fe/core/controllerextensions/MessageHandler.js +234 -232
  64. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +225 -0
  65. package/src/sap/fe/core/controllerextensions/PageReady.js +302 -337
  66. package/src/sap/fe/core/controllerextensions/PageReady.ts +23 -17
  67. package/src/sap/fe/core/controllerextensions/Paginator.js +189 -148
  68. package/src/sap/fe/core/controllerextensions/Paginator.ts +163 -0
  69. package/src/sap/fe/core/controllerextensions/Placeholder.js +158 -146
  70. package/src/sap/fe/core/controllerextensions/Placeholder.ts +151 -0
  71. package/src/sap/fe/core/controllerextensions/Routing.js +145 -106
  72. package/src/sap/fe/core/controllerextensions/Routing.ts +132 -0
  73. package/src/sap/fe/core/controllerextensions/RoutingListener.js +8 -6
  74. package/src/sap/fe/core/controllerextensions/RoutingListener.ts +3 -0
  75. package/src/sap/fe/core/controllerextensions/Share.js +220 -244
  76. package/src/sap/fe/core/controllerextensions/Share.ts +231 -0
  77. package/src/sap/fe/core/controllerextensions/SideEffects.js +593 -634
  78. package/src/sap/fe/core/controllerextensions/SideEffects.ts +29 -27
  79. package/src/sap/fe/core/controllerextensions/ViewState.js +789 -806
  80. package/src/sap/fe/core/controllerextensions/ViewState.ts +805 -0
  81. package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +4 -3
  82. package/src/sap/fe/core/controls/ActionPartial.fragment.xml +2 -2
  83. package/src/sap/fe/core/controls/CommandExecution.js +68 -66
  84. package/src/sap/fe/core/controls/CommandExecution.ts +72 -0
  85. package/src/sap/fe/core/controls/ConditionalWrapper.js +91 -75
  86. package/src/sap/fe/core/controls/ConditionalWrapper.ts +83 -0
  87. package/src/sap/fe/core/controls/CustomQuickViewPage.js +131 -125
  88. package/src/sap/fe/core/controls/CustomQuickViewPage.ts +126 -0
  89. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +105 -110
  90. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +101 -0
  91. package/src/sap/fe/core/controls/FieldWrapper.js +122 -140
  92. package/src/sap/fe/core/controls/FieldWrapper.ts +115 -0
  93. package/src/sap/fe/core/controls/FilterBar.js +163 -159
  94. package/src/sap/fe/core/controls/FilterBar.ts +143 -0
  95. package/src/sap/fe/core/controls/FormElementWrapper.js +46 -44
  96. package/src/sap/fe/core/controls/FormElementWrapper.ts +40 -0
  97. package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +38 -42
  98. package/src/sap/fe/core/controls/MultiValueParameterDelegate.ts +31 -0
  99. package/src/sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog.fragment.xml +2 -1
  100. package/src/sap/fe/core/controls/filterbar/FilterContainer.js +127 -116
  101. package/src/sap/fe/core/controls/filterbar/FilterContainer.ts +98 -0
  102. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +242 -255
  103. package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +245 -0
  104. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +151 -141
  105. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +125 -0
  106. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +336 -322
  107. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +337 -0
  108. package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +106 -0
  109. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +79 -0
  110. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +70 -0
  111. package/src/sap/fe/core/converters/ConverterContext.js +348 -367
  112. package/src/sap/fe/core/converters/ConverterContext.ts +33 -19
  113. package/src/sap/fe/core/converters/ManifestSettings.js +12 -1
  114. package/src/sap/fe/core/converters/ManifestSettings.ts +16 -1
  115. package/src/sap/fe/core/converters/ManifestWrapper.js +354 -354
  116. package/src/sap/fe/core/converters/ManifestWrapper.ts +34 -6
  117. package/src/sap/fe/core/converters/MetaModelConverter.js +72 -9
  118. package/src/sap/fe/core/converters/MetaModelConverter.ts +75 -16
  119. package/src/sap/fe/core/converters/TemplateConverter.js +1 -1
  120. package/src/sap/fe/core/converters/TemplateConverter.ts +4 -3
  121. package/src/sap/fe/core/converters/annotations/DataField.js +28 -14
  122. package/src/sap/fe/core/converters/annotations/DataField.ts +38 -14
  123. package/src/sap/fe/core/converters/common/AnnotationConverter.js +33 -21
  124. package/src/sap/fe/core/converters/controls/Common/Action.js +11 -2
  125. package/src/sap/fe/core/converters/controls/Common/Action.ts +8 -2
  126. package/src/sap/fe/core/converters/controls/Common/Chart.js +5 -3
  127. package/src/sap/fe/core/converters/controls/Common/Chart.ts +11 -3
  128. package/src/sap/fe/core/converters/controls/Common/DataVisualization.js +3 -3
  129. package/src/sap/fe/core/converters/controls/Common/DataVisualization.ts +2 -2
  130. package/src/sap/fe/core/converters/controls/Common/Form.js +21 -11
  131. package/src/sap/fe/core/converters/controls/Common/Form.ts +28 -6
  132. package/src/sap/fe/core/converters/controls/Common/KPI.js +69 -4
  133. package/src/sap/fe/core/converters/controls/Common/KPI.ts +75 -2
  134. package/src/sap/fe/core/converters/controls/Common/Table.js +507 -408
  135. package/src/sap/fe/core/converters/controls/Common/Table.ts +618 -500
  136. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +592 -0
  137. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +718 -0
  138. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +465 -59
  139. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +462 -72
  140. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.js +2 -2
  141. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.ts +1 -1
  142. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +17 -9
  143. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +24 -9
  144. package/src/sap/fe/core/converters/helpers/Aggregation.js +118 -121
  145. package/src/sap/fe/core/converters/helpers/Aggregation.ts +28 -5
  146. package/src/sap/fe/core/converters/helpers/BindingHelper.js +20 -6
  147. package/src/sap/fe/core/converters/helpers/BindingHelper.ts +16 -4
  148. package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +12 -1
  149. package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +11 -0
  150. package/src/sap/fe/core/converters/helpers/IssueManager.js +7 -1
  151. package/src/sap/fe/core/converters/helpers/IssueManager.ts +6 -0
  152. package/src/sap/fe/core/converters/helpers/Key.js +42 -57
  153. package/src/sap/fe/core/converters/helpers/Key.ts +1 -1
  154. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +28 -7
  155. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +23 -6
  156. package/src/sap/fe/core/converters/templates/ListReportConverter.js +20 -7
  157. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +36 -14
  158. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +7 -5
  159. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +5 -1
  160. package/src/sap/fe/core/designtime/AppComponent.designtime.js +93 -90
  161. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +91 -0
  162. package/src/sap/fe/core/formatters/CollaborationFormatter.js +104 -0
  163. package/src/sap/fe/core/formatters/CollaborationFormatter.ts +60 -0
  164. package/src/sap/fe/core/formatters/CriticalityFormatter.js +1 -1
  165. package/src/sap/fe/core/formatters/CriticalityFormatter.ts +1 -1
  166. package/src/sap/fe/core/formatters/FPMFormatter.js +1 -1
  167. package/src/sap/fe/core/formatters/FPMFormatter.ts +4 -10
  168. package/src/sap/fe/core/formatters/KPIFormatter.js +1 -1
  169. package/src/sap/fe/core/formatters/KPIFormatter.ts +3 -1
  170. package/src/sap/fe/core/formatters/TableFormatter.js +91 -29
  171. package/src/sap/fe/core/formatters/TableFormatter.ts +94 -28
  172. package/src/sap/fe/core/formatters/ValueFormatter.js +30 -5
  173. package/src/sap/fe/core/formatters/ValueFormatter.ts +30 -7
  174. package/src/sap/fe/core/fpm/Component.js +51 -54
  175. package/src/sap/fe/core/fpm/Component.ts +48 -0
  176. package/src/sap/fe/core/helpers/AppStartupHelper.js +373 -0
  177. package/src/sap/fe/core/helpers/AppStartupHelper.ts +417 -0
  178. package/src/sap/fe/core/helpers/BindingExpression.js +489 -442
  179. package/src/sap/fe/core/helpers/BindingExpression.ts +486 -469
  180. package/src/sap/fe/core/helpers/ClassSupport.js +212 -76
  181. package/src/sap/fe/core/helpers/ClassSupport.ts +198 -71
  182. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +64 -59
  183. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +52 -0
  184. package/src/sap/fe/core/helpers/EditState.js +81 -84
  185. package/src/sap/fe/core/helpers/EditState.ts +81 -0
  186. package/src/sap/fe/core/helpers/ExcelFormatHelper.js +62 -48
  187. package/src/sap/fe/core/helpers/ExcelFormatHelper.ts +49 -0
  188. package/src/sap/fe/core/helpers/FPMHelper.js +52 -56
  189. package/src/sap/fe/core/helpers/FPMHelper.ts +62 -0
  190. package/src/sap/fe/core/helpers/KeepAliveHelper.js +4 -5
  191. package/src/sap/fe/core/helpers/KeepAliveHelper.ts +10 -10
  192. package/src/sap/fe/core/helpers/MassEditHelper.js +604 -0
  193. package/src/sap/fe/core/helpers/MassEditHelper.ts +699 -0
  194. package/src/sap/fe/core/helpers/ModelHelper.js +253 -225
  195. package/src/sap/fe/core/helpers/ModelHelper.ts +250 -0
  196. package/src/sap/fe/core/helpers/PasteHelper.js +210 -132
  197. package/src/sap/fe/core/helpers/PasteHelper.ts +196 -0
  198. package/src/sap/fe/core/helpers/SemanticDateOperators.js +336 -313
  199. package/src/sap/fe/core/helpers/SemanticDateOperators.ts +334 -0
  200. package/src/sap/fe/core/helpers/SemanticKeyHelper.js +66 -67
  201. package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +73 -0
  202. package/src/sap/fe/core/helpers/StableIdHelper.js +4 -7
  203. package/src/sap/fe/core/helpers/StableIdHelper.ts +2 -6
  204. package/src/sap/fe/core/jsx-runtime/jsx.js +1 -1
  205. package/src/sap/fe/core/jsx-runtime/jsx.ts +1 -1
  206. package/src/sap/fe/core/library.js +427 -425
  207. package/src/sap/fe/core/library.support.js +23 -27
  208. package/src/sap/fe/core/library.support.ts +23 -0
  209. package/src/sap/fe/core/library.ts +420 -0
  210. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +64 -0
  211. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +69 -0
  212. package/src/sap/fe/core/messagebundle.properties +78 -13
  213. package/src/sap/fe/core/messagebundle_ar.properties +58 -7
  214. package/src/sap/fe/core/messagebundle_bg.properties +58 -7
  215. package/src/sap/fe/core/messagebundle_ca.properties +58 -7
  216. package/src/sap/fe/core/messagebundle_cs.properties +59 -8
  217. package/src/sap/fe/core/messagebundle_cy.properties +58 -7
  218. package/src/sap/fe/core/messagebundle_da.properties +58 -7
  219. package/src/sap/fe/core/messagebundle_de.properties +58 -7
  220. package/src/sap/fe/core/messagebundle_el.properties +58 -7
  221. package/src/sap/fe/core/messagebundle_en.properties +57 -6
  222. package/src/sap/fe/core/messagebundle_en_GB.properties +57 -6
  223. package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +61 -6
  224. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +58 -7
  225. package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +58 -7
  226. package/src/sap/fe/core/messagebundle_es.properties +58 -7
  227. package/src/sap/fe/core/messagebundle_es_MX.properties +58 -7
  228. package/src/sap/fe/core/messagebundle_et.properties +58 -7
  229. package/src/sap/fe/core/messagebundle_fi.properties +60 -9
  230. package/src/sap/fe/core/messagebundle_fr.properties +64 -13
  231. package/src/sap/fe/core/messagebundle_fr_CA.properties +59 -8
  232. package/src/sap/fe/core/messagebundle_hi.properties +58 -7
  233. package/src/sap/fe/core/messagebundle_hr.properties +58 -7
  234. package/src/sap/fe/core/messagebundle_hu.properties +59 -8
  235. package/src/sap/fe/core/messagebundle_id.properties +61 -10
  236. package/src/sap/fe/core/messagebundle_it.properties +58 -7
  237. package/src/sap/fe/core/messagebundle_iw.properties +58 -7
  238. package/src/sap/fe/core/messagebundle_ja.properties +58 -7
  239. package/src/sap/fe/core/messagebundle_kk.properties +58 -7
  240. package/src/sap/fe/core/messagebundle_ko.properties +58 -7
  241. package/src/sap/fe/core/messagebundle_lt.properties +58 -7
  242. package/src/sap/fe/core/messagebundle_lv.properties +59 -8
  243. package/src/sap/fe/core/messagebundle_ms.properties +58 -7
  244. package/src/sap/fe/core/messagebundle_nl.properties +58 -7
  245. package/src/sap/fe/core/messagebundle_no.properties +58 -7
  246. package/src/sap/fe/core/messagebundle_pl.properties +58 -7
  247. package/src/sap/fe/core/messagebundle_pt.properties +59 -8
  248. package/src/sap/fe/core/messagebundle_pt_PT.properties +58 -7
  249. package/src/sap/fe/core/messagebundle_ro.properties +58 -7
  250. package/src/sap/fe/core/messagebundle_ru.properties +58 -7
  251. package/src/sap/fe/core/messagebundle_sh.properties +58 -7
  252. package/src/sap/fe/core/messagebundle_sk.properties +58 -7
  253. package/src/sap/fe/core/messagebundle_sl.properties +58 -7
  254. package/src/sap/fe/core/messagebundle_sv.properties +59 -8
  255. package/src/sap/fe/core/messagebundle_th.properties +58 -7
  256. package/src/sap/fe/core/messagebundle_tr.properties +60 -9
  257. package/src/sap/fe/core/messagebundle_uk.properties +58 -7
  258. package/src/sap/fe/core/messagebundle_vi.properties +58 -7
  259. package/src/sap/fe/core/messagebundle_zh_CN.properties +58 -7
  260. package/src/sap/fe/core/messagebundle_zh_TW.properties +58 -7
  261. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +45 -71
  262. package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +3 -1
  263. package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +231 -202
  264. package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +212 -0
  265. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +67 -92
  266. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +10 -6
  267. package/src/sap/fe/core/services/NavigationServiceFactory.js +351 -300
  268. package/src/sap/fe/core/services/NavigationServiceFactory.ts +313 -0
  269. package/src/sap/fe/core/services/ResourceModelServiceFactory.js +114 -81
  270. package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +83 -0
  271. package/src/sap/fe/core/services/RoutingServiceFactory.js +927 -1152
  272. package/src/sap/fe/core/services/RoutingServiceFactory.ts +898 -0
  273. package/src/sap/fe/core/services/ShellServicesFactory.js +649 -707
  274. package/src/sap/fe/core/services/ShellServicesFactory.ts +52 -15
  275. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +569 -637
  276. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +78 -102
  277. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +429 -478
  278. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +460 -0
  279. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +10 -8
  280. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +8 -0
  281. package/src/sap/fe/core/support/AnnotationIssue.support.js +15 -3
  282. package/src/sap/fe/core/support/AnnotationIssue.support.ts +16 -2
  283. package/src/sap/fe/core/support/CollectionFacetUnsupportedLevel.support.js +2 -2
  284. package/src/sap/fe/core/support/CollectionFacetUnsupportedLevel.support.ts +1 -1
  285. package/src/sap/fe/core/support/CommonHelper.js +1 -1
  286. package/src/sap/fe/core/support/CommonHelper.ts +1 -1
  287. package/src/sap/fe/core/support/Diagnostics.js +36 -48
  288. package/src/sap/fe/core/support/InvalidAnnotationColumnKey.support.js +38 -0
  289. package/src/sap/fe/core/support/InvalidAnnotationColumnKey.support.ts +18 -0
  290. package/src/sap/fe/core/templating/DataModelPathHelper.js +97 -127
  291. package/src/sap/fe/core/templating/DataModelPathHelper.ts +112 -135
  292. package/src/sap/fe/core/templating/DisplayModeFormatter.js +114 -0
  293. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +86 -0
  294. package/src/sap/fe/core/templating/FieldControlHelper.js +8 -8
  295. package/src/sap/fe/core/templating/FieldControlHelper.ts +25 -7
  296. package/src/sap/fe/core/templating/FilterHelper.js +140 -78
  297. package/src/sap/fe/core/templating/FilterHelper.ts +149 -78
  298. package/src/sap/fe/core/templating/PropertyHelper.js +3 -3
  299. package/src/sap/fe/core/templating/PropertyHelper.ts +2 -2
  300. package/src/sap/fe/core/templating/UIFormatters.js +76 -135
  301. package/src/sap/fe/core/templating/UIFormatters.ts +76 -99
  302. package/src/sap/fe/core/type/Email.js +1 -1
  303. package/src/sap/fe/core/type/Email.ts +4 -6
  304. package/ui5.yaml +0 -3
  305. package/src/sap/fe/core/controls/filterbar.d.js +0 -8
  306. package/src/sap/fe/core/controls/filterbar.d.ts +0 -0
@@ -0,0 +1,355 @@
1
+ import Event from "sap/ui/base/Event";
2
+ import Control from "sap/ui/core/Control";
3
+ import SapPcpWebSocket from "sap/ui/core/ws/SapPcpWebSocket";
4
+ import MessageBox from "sap/m/MessageBox";
5
+ import { Activity, CollaborationUtils, Message, User, UserActivity } from "sap/fe/core/actions/collaboration/CollaborationCommon";
6
+ import View from "sap/ui/core/mvc/View";
7
+ import UriParameters from "sap/base/util/UriParameters";
8
+ import ODataMetaModel from "sap/ui/model/odata/v4/ODataMetaModel";
9
+ import Log from "sap/base/Log";
10
+ import Context from "sap/ui/model/odata/v4/Context";
11
+ import ResourceBundle from "sap/base/i18n/ResourceBundle";
12
+
13
+ const CONNECTED = "/collaboration/connected";
14
+ const CONNECTION = "/collaboration/connection";
15
+ const MYACTIVITY = "/collaboration/myActivity";
16
+ const ACTIVEUSERS = "/collaboration/activeUsers";
17
+ const ACTIVITIES = "/collaboration/activities";
18
+
19
+ export const isConnected = function(control: Control): boolean {
20
+ return !!control.getModel("internal").getProperty(CONNECTED);
21
+ };
22
+
23
+ export const send = function(control: Control, action: Activity, content: string | string[] | Context | Context[] | undefined) {
24
+ if (isConnected(control)) {
25
+ const contentArray = Array.isArray(content) ? content : [content];
26
+ let clientContent: string = "";
27
+ contentArray.forEach(function(c) {
28
+ if (c) {
29
+ clientContent += clientContent ? "|" : "";
30
+ clientContent += typeof c === "string" ? c : c.getPath();
31
+ }
32
+ });
33
+
34
+ const internalModel = control.getModel("internal") as any;
35
+ const webSocket = internalModel.getProperty(CONNECTION) as SapPcpWebSocket;
36
+
37
+ if (action === Activity.LiveChange) {
38
+ // To avoid unnecessary traffic we keep track of live changes and send it only once
39
+ const myActivity = internalModel.getProperty(MYACTIVITY);
40
+ if (myActivity === clientContent) {
41
+ return;
42
+ } else {
43
+ internalModel.setProperty(MYACTIVITY, clientContent);
44
+ }
45
+ } else {
46
+ // user finished the activity
47
+ internalModel.setProperty(MYACTIVITY, null);
48
+ }
49
+
50
+ webSocket.send("", {
51
+ clientAction: action,
52
+ clientContent: clientContent
53
+ });
54
+
55
+ if (action === Activity.Activate || action === Activity.Discard) {
56
+ disconnect(control);
57
+ }
58
+ }
59
+ };
60
+
61
+ export const connect = async function(view: View) {
62
+ const internalModel: any = view.getModel("internal");
63
+ const me = CollaborationUtils.getMe(view);
64
+ if (internalModel.getProperty(CONNECTION)) {
65
+ // connection already established
66
+ return;
67
+ }
68
+
69
+ // Retrieving ME from shell service
70
+ if (!me) {
71
+ // no me = no shell = not sure what to do
72
+ return;
73
+ }
74
+
75
+ const activeUsers: any[] = [me];
76
+ internalModel.setProperty("/collaboration", { activeUsers: activeUsers, activities: {} });
77
+ const bindingContext = view.getBindingContext() as Context;
78
+ const webSocketBaseURL = bindingContext
79
+ .getModel()
80
+ .getMetaModel()
81
+ .getObject("/@com.sap.vocabularies.Common.v1.WebSocketBaseURL");
82
+
83
+ if (!webSocketBaseURL) {
84
+ return;
85
+ }
86
+
87
+ const sDraftUUID = await bindingContext.requestProperty("DraftAdministrativeData/DraftUUID");
88
+ if (!sDraftUUID) {
89
+ return;
90
+ }
91
+
92
+ const webSocket = establishWebSocketConnection(webSocketBaseURL, sDraftUUID, view);
93
+
94
+ webSocket.attachMessage(function(event: Event) {
95
+ const message: Message = event.getParameter("pcpFields");
96
+ messageReceive(message, view, webSocket);
97
+ });
98
+ };
99
+
100
+ export const disconnect = function(control: Control) {
101
+ const internalModel = control.getModel("internal") as any;
102
+ const webSocket = internalModel.getProperty(CONNECTION) as SapPcpWebSocket;
103
+ webSocket.close();
104
+ internalModel.setProperty(CONNECTION, null);
105
+ };
106
+
107
+ function establishWebSocketConnection(socketBaseURL: string, draftUUID: string, view: View) {
108
+ const internalModel: any = view.getModel("internal");
109
+ const hostLocation = window.location;
110
+ let socketURI;
111
+
112
+ // Support useBackendUrl for local testing
113
+ const useBackendUrl = UriParameters.fromQuery(window.location.search).get("useBackendUrl");
114
+ if (useBackendUrl) {
115
+ socketURI = useBackendUrl.replace("https", "wss");
116
+ } else {
117
+ socketURI = hostLocation.protocol === "https:" ? "wss:" : "ws:";
118
+ socketURI += "//" + hostLocation.host;
119
+ }
120
+
121
+ socketURI += (socketBaseURL.startsWith("/") ? "" : "/") + socketBaseURL + "?draft=" + draftUUID;
122
+
123
+ const webSocket = new SapPcpWebSocket(socketURI, ["v10.pcp.sap.com"]); // TODO: use enum
124
+ internalModel.setProperty(CONNECTION, webSocket);
125
+
126
+ webSocket.attachOpen(function() {
127
+ internalModel.setProperty(CONNECTED, true);
128
+ });
129
+
130
+ webSocket.attachError(function() {
131
+ Log.error("The connection to the websocket channel " + socketBaseURL + " could not be established");
132
+ internalModel.setProperty(CONNECTED, false);
133
+ });
134
+
135
+ webSocket.attachClose(function() {
136
+ internalModel.setProperty(CONNECTED, false);
137
+ });
138
+
139
+ return webSocket;
140
+ }
141
+
142
+ function messageReceive(message: Message, view: View, webSocket: any) {
143
+ const internalModel: any = view.getModel("internal");
144
+ let activeUsers: User[] = internalModel.getProperty(ACTIVEUSERS);
145
+ let activities: UserActivity[];
146
+ let activityKey: string;
147
+ const metaPath: string = message.clientContent && (view.getModel().getMetaModel() as ODataMetaModel).getMetaPath(message.clientContent);
148
+ message.userAction = message.userAction || message.clientAction;
149
+
150
+ const sender: User = {
151
+ id: message.userID,
152
+ name: message.userDescription,
153
+ initials: CollaborationUtils.formatInitials(message.userDescription),
154
+ color: CollaborationUtils.getUserColor(message.userID, activeUsers, [])
155
+ };
156
+
157
+ switch (message.userAction) {
158
+ case Activity.Join:
159
+ case Activity.JoinEcho:
160
+ if (activeUsers.findIndex(user => user.id === sender.id) === -1) {
161
+ activeUsers.push(sender);
162
+ internalModel.setProperty(ACTIVEUSERS, activeUsers);
163
+ }
164
+
165
+ if (message.userAction === Activity.Join) {
166
+ // we echo our existence to the newly entered user and also send the current activity if there is any
167
+ webSocket.send("", {
168
+ clientAction: Activity.JoinEcho,
169
+ clientContent: internalModel.getProperty(MYACTIVITY)
170
+ });
171
+ // TODO: echo current activity
172
+ }
173
+
174
+ if (message.userAction === Activity.JoinEcho) {
175
+ if (message.clientContent) {
176
+ // another user was already typing therefore I want to see his activity immediately. Calling me again as a live change
177
+ message.userAction = Activity.LiveChange;
178
+ messageReceive(message, view, webSocket);
179
+ }
180
+ }
181
+
182
+ break;
183
+ case Activity.Leave:
184
+ // Removing the active user. Not removing "me" if I had the screen open in another session
185
+ activeUsers = activeUsers.filter(user => user.id !== sender.id || user.me);
186
+ internalModel.setProperty(ACTIVEUSERS, activeUsers);
187
+ const allActivities = internalModel.getProperty(ACTIVITIES) || {};
188
+ const removeUserActivities = function(bag: any) {
189
+ if (Array.isArray(bag)) {
190
+ return bag.filter(activity => activity.id !== sender.id);
191
+ } else {
192
+ for (const p in bag) {
193
+ bag[p] = removeUserActivities(bag[p]);
194
+ }
195
+ return bag;
196
+ }
197
+ };
198
+ removeUserActivities(allActivities);
199
+ internalModel.setProperty(ACTIVITIES, allActivities);
200
+ break;
201
+
202
+ case Activity.Change:
203
+ let currentActivities: any[] = internalModel.getProperty(ACTIVITIES + metaPath) || [];
204
+ activityKey = getActivityKey(message.clientContent);
205
+ currentActivities = currentActivities.filter(activity => activity.key !== activityKey);
206
+ internalModel.setProperty(ACTIVITIES + metaPath, currentActivities);
207
+
208
+ update(view, message, metaPath, Activity.Change);
209
+ break;
210
+ case Activity.Create:
211
+ // For create we actually just need to refresh the table
212
+ update(view, message, metaPath, Activity.Create);
213
+ break;
214
+ case Activity.Delete:
215
+ // For now also refresh the page but in case of deletion we need to inform the user
216
+ update(view, message, metaPath, Activity.Delete);
217
+ break;
218
+ case Activity.Activate:
219
+ disconnect(view);
220
+ MessageBox.information(getText("C_COLLABORATIONDRAFT_ACTIVATE", sender.name));
221
+ navigate(message.clientContent, view);
222
+ break;
223
+ case Activity.Discard:
224
+ disconnect(view);
225
+ MessageBox.information(getText("C_COLLABORATIONDRAFT_DISCARD", sender.name));
226
+ navigate(message.clientContent, view);
227
+ break;
228
+ /*
229
+ // TODO: Action to be implemented
230
+ case Activity.Action:
231
+ // Just for test reasons show a toast - to be checked with UX
232
+ MessageToast.show("User " + sender.name + " has executed action " + metaPath.split("|")[0]);
233
+ //update(view, message, metaPath, Activity.Delete);
234
+ break;
235
+ */
236
+ case Activity.LiveChange:
237
+ const activity: UserActivity = sender;
238
+ activity.key = getActivityKey(message.clientContent);
239
+
240
+ // stupid JSON model...
241
+ let initJSONModel: string = "";
242
+ const parts = metaPath.split("/");
243
+ for (let i = 1; i < parts.length - 1; i++) {
244
+ initJSONModel += "/" + parts[i];
245
+ if (!internalModel.getProperty(ACTIVITIES + initJSONModel)) {
246
+ internalModel.setProperty(ACTIVITIES + initJSONModel, {});
247
+ }
248
+ }
249
+
250
+ activities = internalModel.getProperty(ACTIVITIES + metaPath);
251
+ activities = activities ? activities.slice() : [];
252
+ activities.push(activity);
253
+ internalModel.setProperty(ACTIVITIES + metaPath, activities);
254
+ break;
255
+ case Activity.Undo:
256
+ // The user did a change but reverted it, therefore unblock the control
257
+ activities = internalModel.getProperty(ACTIVITIES + metaPath);
258
+ activityKey = getActivityKey(message.clientContent);
259
+ internalModel.setProperty(
260
+ ACTIVITIES + metaPath,
261
+ activities.filter(a => a.key !== activityKey)
262
+ );
263
+ break;
264
+ }
265
+ }
266
+
267
+ function update(view: View, message: Message, metaPath: string, action: Activity) {
268
+ const appComponent = CollaborationUtils.getAppComponent(view);
269
+ const metaModel = view.getModel().getMetaModel() as ODataMetaModel;
270
+ const currentPage = getCurrentPage(view);
271
+ const sideEffectsService = (appComponent as any).getSideEffectsService(); // TODO: add to appcomponent
272
+ const currentContext = currentPage.getBindingContext();
273
+ const currentPath = currentContext.getPath();
274
+ const currentMetaPath = metaModel.getMetaPath(currentPath);
275
+ let changedDocument = message.clientContent;
276
+
277
+ if (action === Activity.Delete) {
278
+ // check if user currently displays one deleted object
279
+ const deletedObjects = message.clientContent.split("|");
280
+ if (deletedObjects.findIndex(deletedObject => currentPath.startsWith(deletedObject)) > -1) {
281
+ // any other user deleted the object I'm currently looking at. Inform the user we will navigate to root now
282
+ MessageBox.information(getText("C_COLLABORATIONDRAFT_DELETE", message.userDescription), {
283
+ onClose: function() {
284
+ // TODO: Navigate to root? To be implemented
285
+ history.back();
286
+ }
287
+ });
288
+ }
289
+ // TODO: For now just take the first object to get the meta path and do a full refresh of the table
290
+ changedDocument = deletedObjects[0];
291
+ }
292
+
293
+ if (changedDocument.startsWith(currentPath)) {
294
+ // Execute SideEffects (TODO for Meet there should be one central method)
295
+ const activityPath = metaPath.replace(currentMetaPath, "").slice(1);
296
+ if (activityPath) {
297
+ // Request also the property itself
298
+ const sideEffects: any[] = [
299
+ {
300
+ $PropertyPath: activityPath
301
+ }
302
+ ];
303
+ const entityType = sideEffectsService.getEntityTypeFromContext(currentContext);
304
+ const entityTypeSideEffects = sideEffectsService.getODataEntitySideEffects(entityType);
305
+ // Poor man solution without checking source targets, just for POC, this is throw-way coding only
306
+ const object: any = Object; // just to overcome TS issues, will be anyway replaced
307
+ const relevantSideEffects = object.fromEntries(
308
+ object
309
+ .entries(entityTypeSideEffects)
310
+ .filter((x: any[]) => x[1].SourceProperties?.findIndex((source: any) => source.value === activityPath) > -1)
311
+ );
312
+ for (const p in relevantSideEffects) {
313
+ relevantSideEffects[p].TargetProperties.forEach(function(targetProperty: any) {
314
+ sideEffects.push({
315
+ $PropertyPath: targetProperty
316
+ });
317
+ });
318
+ }
319
+ sideEffectsService.requestSideEffects(sideEffects, currentContext, "$auto");
320
+ }
321
+ }
322
+
323
+ // Simulate any change so the edit flow shows the draft indicator and sets the page to dirty
324
+ currentPage.getController().editFlow.updateDocument(currentContext, Promise.resolve());
325
+ }
326
+
327
+ function navigate(path: string, view: View) {
328
+ // TODO: routing.navigate doesn't consider semantic bookmarking
329
+ const currentPage = getCurrentPage(view);
330
+ const targetContext = view
331
+ .getModel()
332
+ .bindContext(path)
333
+ .getBoundContext();
334
+ currentPage.getController().routing.navigate(targetContext);
335
+ }
336
+
337
+ function getCurrentPage(view: View) {
338
+ const appComponent = CollaborationUtils.getAppComponent(view);
339
+ // TODO: isn't there an easier way to get the current page?
340
+ // TODO: What about FCL?
341
+ return (appComponent.getRootControl() as any)
342
+ .getContent()[0]
343
+ .getCurrentPage()
344
+ .getComponentInstance()
345
+ .getRootControl();
346
+ }
347
+
348
+ function getActivityKey(x: string): string {
349
+ return x.substring(x.lastIndexOf("(") + 1, x.lastIndexOf(")"));
350
+ }
351
+
352
+ function getText(textId: string, ...args: string[]): string {
353
+ const oResourceModel = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core") as ResourceBundle;
354
+ return oResourceModel.getText(textId, args);
355
+ }
@@ -0,0 +1,136 @@
1
+ /*!
2
+ * SAP UI development toolkit for HTML5 (SAPUI5)
3
+ * (c) Copyright 2009-2021 SAP SE. All rights reserved
4
+ */
5
+ sap.ui.define(["sap/ui/core/Component"], function (Component) {
6
+ "use strict";
7
+
8
+ var _exports = {};
9
+
10
+ var Role;
11
+
12
+ (function (Role) {
13
+ Role["Owner"] = "O";
14
+ Role["Edit"] = "E";
15
+ })(Role || (Role = {}));
16
+
17
+ _exports.Role = Role;
18
+ var Activity;
19
+
20
+ (function (Activity) {
21
+ Activity["Join"] = "JOIN";
22
+ Activity["JoinEcho"] = "JOINECHO";
23
+ Activity["Leave"] = "LEAVE";
24
+ Activity["Change"] = "CHANGE";
25
+ Activity["Create"] = "CREATE";
26
+ Activity["Delete"] = "DELETE";
27
+ Activity["Action"] = "ACTION";
28
+ Activity["LiveChange"] = "LIVECHANGE";
29
+ Activity["Activate"] = "ACTIVATE";
30
+ Activity["Discard"] = "DISCARD";
31
+ Activity["Undo"] = "UNDO";
32
+ })(Activity || (Activity = {}));
33
+
34
+ _exports.Activity = Activity;
35
+
36
+ function formatInitials(fullName) {
37
+ // remove titles - those are the ones from S/4 to be checked if there are others
38
+ var academicTitles = ["Dr.", "Prof.", "Prof. Dr.", "B.A.", "MBA", "Ph.D."];
39
+ academicTitles.forEach(function (academicTitle) {
40
+ fullName = fullName.replace(academicTitle, "");
41
+ });
42
+ var initials;
43
+ var parts = fullName.trimStart().split(" ");
44
+
45
+ if (parts.length > 1) {
46
+ var _parts$shift, _parts$pop;
47
+
48
+ initials = ((parts === null || parts === void 0 ? void 0 : (_parts$shift = parts.shift()) === null || _parts$shift === void 0 ? void 0 : _parts$shift.charAt(0)) || "") + ((_parts$pop = parts.pop()) === null || _parts$pop === void 0 ? void 0 : _parts$pop.charAt(0));
49
+ } else {
50
+ initials = fullName.substring(0, 2);
51
+ }
52
+
53
+ return initials.toUpperCase();
54
+ }
55
+
56
+ function getUserColor(UserID, activeUsers, invitedUsers) {
57
+ // search if user is known
58
+ var user = activeUsers.find(function (u) {
59
+ return u.id === UserID;
60
+ });
61
+
62
+ if (user) {
63
+ return user.color;
64
+ } else {
65
+ var _loop = function (i) {
66
+ if (activeUsers.findIndex(function (u) {
67
+ return u.color === i;
68
+ }) === -1 && invitedUsers.findIndex(function (u) {
69
+ return u.color === i;
70
+ }) === -1) {
71
+ return {
72
+ v: i
73
+ };
74
+ }
75
+ };
76
+
77
+ // search for next free color
78
+ for (var i = 1; i <= 10; i++) {
79
+ var _ret = _loop(i);
80
+
81
+ if (typeof _ret === "object") return _ret.v;
82
+ } // this seems to be a popular object :) for now just return 10 for all.
83
+ // for invited we should start from 1 again so the colors are different
84
+
85
+
86
+ return 10;
87
+ }
88
+ } // copied from CommonUtils. Due to a cycle dependency I can't use CommonUtils here.
89
+ // That's to be fixed. the discard popover thingy shouldn't be in the common utils at all
90
+
91
+
92
+ function getAppComponent(oControl) {
93
+ if (oControl.isA("sap.fe.core.AppComponent")) {
94
+ return oControl;
95
+ }
96
+
97
+ var oOwner = Component.getOwnerComponentFor(oControl);
98
+
99
+ if (!oOwner) {
100
+ return oControl;
101
+ } else {
102
+ return getAppComponent(oOwner);
103
+ }
104
+ }
105
+
106
+ function getMe(view) {
107
+ var shellServiceHelper = getAppComponent(view).getShellServices();
108
+
109
+ if (!shellServiceHelper || !shellServiceHelper.hasUShell()) {
110
+ throw "No Shell... No User";
111
+ }
112
+
113
+ var me = {
114
+ initials: shellServiceHelper.getUser().getInitials(),
115
+ id: shellServiceHelper.getUser().getId(),
116
+ name: shellServiceHelper.getUser().getFullName(),
117
+ color: 6,
118
+ // same color as FLP...
119
+ role: Role.Owner,
120
+ me: true
121
+ };
122
+ me.name += " (You)"; // TODO resource bundle
123
+
124
+ return me;
125
+ }
126
+
127
+ var CollaborationUtils = {
128
+ formatInitials: formatInitials,
129
+ getUserColor: getUserColor,
130
+ getMe: getMe,
131
+ getAppComponent: getAppComponent
132
+ };
133
+ _exports.CollaborationUtils = CollaborationUtils;
134
+ return _exports;
135
+ }, false);
136
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkNvbGxhYm9yYXRpb25Db21tb24udHMiXSwibmFtZXMiOlsiUm9sZSIsIkFjdGl2aXR5IiwiZm9ybWF0SW5pdGlhbHMiLCJmdWxsTmFtZSIsImFjYWRlbWljVGl0bGVzIiwiZm9yRWFjaCIsImFjYWRlbWljVGl0bGUiLCJyZXBsYWNlIiwiaW5pdGlhbHMiLCJwYXJ0cyIsInRyaW1TdGFydCIsInNwbGl0IiwibGVuZ3RoIiwic2hpZnQiLCJjaGFyQXQiLCJwb3AiLCJzdWJzdHJpbmciLCJ0b1VwcGVyQ2FzZSIsImdldFVzZXJDb2xvciIsIlVzZXJJRCIsImFjdGl2ZVVzZXJzIiwiaW52aXRlZFVzZXJzIiwidXNlciIsImZpbmQiLCJ1IiwiaWQiLCJjb2xvciIsImkiLCJmaW5kSW5kZXgiLCJnZXRBcHBDb21wb25lbnQiLCJvQ29udHJvbCIsImlzQSIsIm9Pd25lciIsIkNvbXBvbmVudCIsImdldE93bmVyQ29tcG9uZW50Rm9yIiwiZ2V0TWUiLCJ2aWV3Iiwic2hlbGxTZXJ2aWNlSGVscGVyIiwiZ2V0U2hlbGxTZXJ2aWNlcyIsImhhc1VTaGVsbCIsIm1lIiwiZ2V0VXNlciIsImdldEluaXRpYWxzIiwiZ2V0SWQiLCJuYW1lIiwiZ2V0RnVsbE5hbWUiLCJyb2xlIiwiT3duZXIiLCJDb2xsYWJvcmF0aW9uVXRpbHMiXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7Ozs7OztNQWdCWUEsSTs7YUFBQUEsSTtBQUFBQSxJQUFBQSxJO0FBQUFBLElBQUFBLEk7S0FBQUEsSSxLQUFBQSxJOzs7TUFLQUMsUTs7YUFBQUEsUTtBQUFBQSxJQUFBQSxRO0FBQUFBLElBQUFBLFE7QUFBQUEsSUFBQUEsUTtBQUFBQSxJQUFBQSxRO0FBQUFBLElBQUFBLFE7QUFBQUEsSUFBQUEsUTtBQUFBQSxJQUFBQSxRO0FBQUFBLElBQUFBLFE7QUFBQUEsSUFBQUEsUTtBQUFBQSxJQUFBQSxRO0FBQUFBLElBQUFBLFE7S0FBQUEsUSxLQUFBQSxROzs7O0FBc0JaLFdBQVNDLGNBQVQsQ0FBd0JDLFFBQXhCLEVBQWtEO0FBQ2pEO0FBQ0EsUUFBTUMsY0FBYyxHQUFHLENBQUMsS0FBRCxFQUFRLE9BQVIsRUFBaUIsV0FBakIsRUFBOEIsTUFBOUIsRUFBc0MsS0FBdEMsRUFBNkMsT0FBN0MsQ0FBdkI7QUFDQUEsSUFBQUEsY0FBYyxDQUFDQyxPQUFmLENBQXVCLFVBQVNDLGFBQVQsRUFBd0I7QUFDOUNILE1BQUFBLFFBQVEsR0FBR0EsUUFBUSxDQUFDSSxPQUFULENBQWlCRCxhQUFqQixFQUFnQyxFQUFoQyxDQUFYO0FBQ0EsS0FGRDtBQUlBLFFBQUlFLFFBQUo7QUFDQSxRQUFNQyxLQUFLLEdBQUdOLFFBQVEsQ0FBQ08sU0FBVCxHQUFxQkMsS0FBckIsQ0FBMkIsR0FBM0IsQ0FBZDs7QUFFQSxRQUFJRixLQUFLLENBQUNHLE1BQU4sR0FBZSxDQUFuQixFQUFzQjtBQUFBOztBQUNyQkosTUFBQUEsUUFBUSxHQUFHLENBQUMsQ0FBQUMsS0FBSyxTQUFMLElBQUFBLEtBQUssV0FBTCw0QkFBQUEsS0FBSyxDQUFFSSxLQUFQLGdFQUFnQkMsTUFBaEIsQ0FBdUIsQ0FBdkIsTUFBNkIsRUFBOUIsbUJBQW9DTCxLQUFLLENBQUNNLEdBQU4sRUFBcEMsK0NBQW9DLFdBQWFELE1BQWIsQ0FBb0IsQ0FBcEIsQ0FBcEMsQ0FBWDtBQUNBLEtBRkQsTUFFTztBQUNOTixNQUFBQSxRQUFRLEdBQUdMLFFBQVEsQ0FBQ2EsU0FBVCxDQUFtQixDQUFuQixFQUFzQixDQUF0QixDQUFYO0FBQ0E7O0FBRUQsV0FBT1IsUUFBUSxDQUFDUyxXQUFULEVBQVA7QUFDQTs7QUFFRCxXQUFTQyxZQUFULENBQXNCQyxNQUF0QixFQUFzQ0MsV0FBdEMsRUFBMkRDLFlBQTNELEVBQWlGO0FBQ2hGO0FBQ0EsUUFBTUMsSUFBSSxHQUFHRixXQUFXLENBQUNHLElBQVosQ0FBaUIsVUFBQUMsQ0FBQztBQUFBLGFBQUlBLENBQUMsQ0FBQ0MsRUFBRixLQUFTTixNQUFiO0FBQUEsS0FBbEIsQ0FBYjs7QUFDQSxRQUFJRyxJQUFKLEVBQVU7QUFDVCxhQUFPQSxJQUFJLENBQUNJLEtBQVo7QUFDQSxLQUZELE1BRU87QUFBQSw0QkFFR0MsQ0FGSDtBQUdMLFlBQUlQLFdBQVcsQ0FBQ1EsU0FBWixDQUFzQixVQUFBSixDQUFDO0FBQUEsaUJBQUlBLENBQUMsQ0FBQ0UsS0FBRixLQUFZQyxDQUFoQjtBQUFBLFNBQXZCLE1BQThDLENBQUMsQ0FBL0MsSUFBb0ROLFlBQVksQ0FBQ08sU0FBYixDQUF1QixVQUFBSixDQUFDO0FBQUEsaUJBQUlBLENBQUMsQ0FBQ0UsS0FBRixLQUFZQyxDQUFoQjtBQUFBLFNBQXhCLE1BQStDLENBQUMsQ0FBeEcsRUFBMkc7QUFDMUc7QUFBQSxlQUFPQTtBQUFQO0FBQ0E7QUFMSTs7QUFDTjtBQUNBLFdBQUssSUFBSUEsQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsSUFBSSxFQUFyQixFQUF5QkEsQ0FBQyxFQUExQixFQUE4QjtBQUFBLHlCQUFyQkEsQ0FBcUI7O0FBQUE7QUFJN0IsT0FOSyxDQU9OO0FBQ0E7OztBQUNBLGFBQU8sRUFBUDtBQUNBO0FBQ0QsRyxDQUVEO0FBQ0E7OztBQUNBLFdBQVNFLGVBQVQsQ0FBeUJDLFFBQXpCLEVBQXNEO0FBQ3JELFFBQUlBLFFBQVEsQ0FBQ0MsR0FBVCxDQUFhLDBCQUFiLENBQUosRUFBOEM7QUFDN0MsYUFBT0QsUUFBUDtBQUNBOztBQUNELFFBQU1FLE1BQU0sR0FBR0MsU0FBUyxDQUFDQyxvQkFBVixDQUErQkosUUFBL0IsQ0FBZjs7QUFDQSxRQUFJLENBQUNFLE1BQUwsRUFBYTtBQUNaLGFBQU9GLFFBQVA7QUFDQSxLQUZELE1BRU87QUFDTixhQUFPRCxlQUFlLENBQUNHLE1BQUQsQ0FBdEI7QUFDQTtBQUNEOztBQUVELFdBQVNHLEtBQVQsQ0FBZUMsSUFBZixFQUFpQztBQUNoQyxRQUFNQyxrQkFBa0IsR0FBR1IsZUFBZSxDQUFDTyxJQUFELENBQWYsQ0FBc0JFLGdCQUF0QixFQUEzQjs7QUFDQSxRQUFJLENBQUNELGtCQUFELElBQXVCLENBQUNBLGtCQUFrQixDQUFDRSxTQUFuQixFQUE1QixFQUE0RDtBQUMzRCxZQUFNLHFCQUFOO0FBQ0E7O0FBQ0QsUUFBTUMsRUFBUSxHQUFHO0FBQ2hCaEMsTUFBQUEsUUFBUSxFQUFFNkIsa0JBQWtCLENBQUNJLE9BQW5CLEdBQTZCQyxXQUE3QixFQURNO0FBRWhCakIsTUFBQUEsRUFBRSxFQUFFWSxrQkFBa0IsQ0FBQ0ksT0FBbkIsR0FBNkJFLEtBQTdCLEVBRlk7QUFHaEJDLE1BQUFBLElBQUksRUFBRVAsa0JBQWtCLENBQUNJLE9BQW5CLEdBQTZCSSxXQUE3QixFQUhVO0FBSWhCbkIsTUFBQUEsS0FBSyxFQUFFLENBSlM7QUFJTjtBQUNWb0IsTUFBQUEsSUFBSSxFQUFFOUMsSUFBSSxDQUFDK0MsS0FMSztBQU1oQlAsTUFBQUEsRUFBRSxFQUFFO0FBTlksS0FBakI7QUFRQUEsSUFBQUEsRUFBRSxDQUFDSSxJQUFILElBQVcsUUFBWCxDQWJnQyxDQWFYOztBQUNyQixXQUFPSixFQUFQO0FBQ0E7O0FBRU0sTUFBTVEsa0JBQWtCLEdBQUc7QUFDakM5QyxJQUFBQSxjQUFjLEVBQUVBLGNBRGlCO0FBRWpDZ0IsSUFBQUEsWUFBWSxFQUFFQSxZQUZtQjtBQUdqQ2lCLElBQUFBLEtBQUssRUFBRUEsS0FIMEI7QUFJakNOLElBQUFBLGVBQWUsRUFBRUE7QUFKZ0IsR0FBM0IiLCJzb3VyY2VSb290IjoiLiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBWaWV3IGZyb20gXCJzYXAvdWkvY29yZS9tdmMvVmlld1wiO1xuaW1wb3J0IENvbXBvbmVudCBmcm9tIFwic2FwL3VpL2NvcmUvQ29tcG9uZW50XCI7XG5pbXBvcnQgQXBwQ29tcG9uZW50IGZyb20gXCJzYXAvZmUvY29yZS9BcHBDb21wb25lbnRcIjtcblxuZXhwb3J0IHR5cGUgVXNlciA9IHtcblx0aWQ6IHN0cmluZztcblx0aW5pdGlhbHM/OiBzdHJpbmc7XG5cdG5hbWU6IHN0cmluZztcblx0cm9sZT86IFJvbGU7XG5cdGNvbG9yPzogbnVtYmVyO1xuXHR0cmFuc2llbnQ/OiBib29sZWFuO1xuXHRtZT86IGJvb2xlYW47XG59O1xuXG5leHBvcnQgdHlwZSBVc2VyQWN0aXZpdHkgPSBVc2VyICYge1xuXHRrZXk/OiBzdHJpbmc7XG59O1xuXG5leHBvcnQgZW51bSBSb2xlIHtcblx0T3duZXIgPSBcIk9cIixcblx0RWRpdCA9IFwiRVwiXG59XG5cbmV4cG9ydCBlbnVtIEFjdGl2aXR5IHtcblx0Sm9pbiA9IFwiSk9JTlwiLFxuXHRKb2luRWNobyA9IFwiSk9JTkVDSE9cIixcblx0TGVhdmUgPSBcIkxFQVZFXCIsXG5cdENoYW5nZSA9IFwiQ0hBTkdFXCIsXG5cdENyZWF0ZSA9IFwiQ1JFQVRFXCIsXG5cdERlbGV0ZSA9IFwiREVMRVRFXCIsXG5cdEFjdGlvbiA9IFwiQUNUSU9OXCIsXG5cdExpdmVDaGFuZ2UgPSBcIkxJVkVDSEFOR0VcIixcblx0QWN0aXZhdGUgPSBcIkFDVElWQVRFXCIsXG5cdERpc2NhcmQgPSBcIkRJU0NBUkRcIixcblx0VW5kbyA9IFwiVU5ET1wiXG59XG5cbmV4cG9ydCB0eXBlIE1lc3NhZ2UgPSB7XG5cdHVzZXJEZXNjcmlwdGlvbjogc3RyaW5nO1xuXHR1c2VySUQ6IHN0cmluZztcblx0dXNlckFjdGlvbjogc3RyaW5nO1xuXHRjbGllbnRBY3Rpb246IHN0cmluZztcblx0Y2xpZW50Q29udGVudDogc3RyaW5nO1xufTtcblxuZnVuY3Rpb24gZm9ybWF0SW5pdGlhbHMoZnVsbE5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG5cdC8vIHJlbW92ZSB0aXRsZXMgLSB0aG9zZSBhcmUgdGhlIG9uZXMgZnJvbSBTLzQgdG8gYmUgY2hlY2tlZCBpZiB0aGVyZSBhcmUgb3RoZXJzXG5cdGNvbnN0IGFjYWRlbWljVGl0bGVzID0gW1wiRHIuXCIsIFwiUHJvZi5cIiwgXCJQcm9mLiBEci5cIiwgXCJCLkEuXCIsIFwiTUJBXCIsIFwiUGguRC5cIl07XG5cdGFjYWRlbWljVGl0bGVzLmZvckVhY2goZnVuY3Rpb24oYWNhZGVtaWNUaXRsZSkge1xuXHRcdGZ1bGxOYW1lID0gZnVsbE5hbWUucmVwbGFjZShhY2FkZW1pY1RpdGxlLCBcIlwiKTtcblx0fSk7XG5cblx0bGV0IGluaXRpYWxzOiBzdHJpbmc7XG5cdGNvbnN0IHBhcnRzID0gZnVsbE5hbWUudHJpbVN0YXJ0KCkuc3BsaXQoXCIgXCIpO1xuXG5cdGlmIChwYXJ0cy5sZW5ndGggPiAxKSB7XG5cdFx0aW5pdGlhbHMgPSAocGFydHM/LnNoaWZ0KCk/LmNoYXJBdCgwKSB8fCBcIlwiKSArIHBhcnRzLnBvcCgpPy5jaGFyQXQoMCk7XG5cdH0gZWxzZSB7XG5cdFx0aW5pdGlhbHMgPSBmdWxsTmFtZS5zdWJzdHJpbmcoMCwgMik7XG5cdH1cblxuXHRyZXR1cm4gaW5pdGlhbHMudG9VcHBlckNhc2UoKTtcbn1cblxuZnVuY3Rpb24gZ2V0VXNlckNvbG9yKFVzZXJJRDogc3RyaW5nLCBhY3RpdmVVc2VyczogVXNlcltdLCBpbnZpdGVkVXNlcnM6IFVzZXJbXSkge1xuXHQvLyBzZWFyY2ggaWYgdXNlciBpcyBrbm93blxuXHRjb25zdCB1c2VyID0gYWN0aXZlVXNlcnMuZmluZCh1ID0+IHUuaWQgPT09IFVzZXJJRCk7XG5cdGlmICh1c2VyKSB7XG5cdFx0cmV0dXJuIHVzZXIuY29sb3I7XG5cdH0gZWxzZSB7XG5cdFx0Ly8gc2VhcmNoIGZvciBuZXh0IGZyZWUgY29sb3Jcblx0XHRmb3IgKGxldCBpID0gMTsgaSA8PSAxMDsgaSsrKSB7XG5cdFx0XHRpZiAoYWN0aXZlVXNlcnMuZmluZEluZGV4KHUgPT4gdS5jb2xvciA9PT0gaSkgPT09IC0xICYmIGludml0ZWRVc2Vycy5maW5kSW5kZXgodSA9PiB1LmNvbG9yID09PSBpKSA9PT0gLTEpIHtcblx0XHRcdFx0cmV0dXJuIGk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdC8vIHRoaXMgc2VlbXMgdG8gYmUgYSBwb3B1bGFyIG9iamVjdCA6KSBmb3Igbm93IGp1c3QgcmV0dXJuIDEwIGZvciBhbGwuXG5cdFx0Ly8gZm9yIGludml0ZWQgd2Ugc2hvdWxkIHN0YXJ0IGZyb20gMSBhZ2FpbiBzbyB0aGUgY29sb3JzIGFyZSBkaWZmZXJlbnRcblx0XHRyZXR1cm4gMTA7XG5cdH1cbn1cblxuLy8gY29waWVkIGZyb20gQ29tbW9uVXRpbHMuIER1ZSB0byBhIGN5Y2xlIGRlcGVuZGVuY3kgSSBjYW4ndCB1c2UgQ29tbW9uVXRpbHMgaGVyZS5cbi8vIFRoYXQncyB0byBiZSBmaXhlZC4gdGhlIGRpc2NhcmQgcG9wb3ZlciB0aGluZ3kgc2hvdWxkbid0IGJlIGluIHRoZSBjb21tb24gdXRpbHMgYXQgYWxsXG5mdW5jdGlvbiBnZXRBcHBDb21wb25lbnQob0NvbnRyb2w6IGFueSk6IEFwcENvbXBvbmVudCB7XG5cdGlmIChvQ29udHJvbC5pc0EoXCJzYXAuZmUuY29yZS5BcHBDb21wb25lbnRcIikpIHtcblx0XHRyZXR1cm4gb0NvbnRyb2w7XG5cdH1cblx0Y29uc3Qgb093bmVyID0gQ29tcG9uZW50LmdldE93bmVyQ29tcG9uZW50Rm9yKG9Db250cm9sKTtcblx0aWYgKCFvT3duZXIpIHtcblx0XHRyZXR1cm4gb0NvbnRyb2w7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGdldEFwcENvbXBvbmVudChvT3duZXIpO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGdldE1lKHZpZXc6IFZpZXcpOiBVc2VyIHtcblx0Y29uc3Qgc2hlbGxTZXJ2aWNlSGVscGVyID0gZ2V0QXBwQ29tcG9uZW50KHZpZXcpLmdldFNoZWxsU2VydmljZXMoKTtcblx0aWYgKCFzaGVsbFNlcnZpY2VIZWxwZXIgfHwgIXNoZWxsU2VydmljZUhlbHBlci5oYXNVU2hlbGwoKSkge1xuXHRcdHRocm93IFwiTm8gU2hlbGwuLi4gTm8gVXNlclwiO1xuXHR9XG5cdGNvbnN0IG1lOiBVc2VyID0ge1xuXHRcdGluaXRpYWxzOiBzaGVsbFNlcnZpY2VIZWxwZXIuZ2V0VXNlcigpLmdldEluaXRpYWxzKCksXG5cdFx0aWQ6IHNoZWxsU2VydmljZUhlbHBlci5nZXRVc2VyKCkuZ2V0SWQoKSxcblx0XHRuYW1lOiBzaGVsbFNlcnZpY2VIZWxwZXIuZ2V0VXNlcigpLmdldEZ1bGxOYW1lKCksXG5cdFx0Y29sb3I6IDYsIC8vICBzYW1lIGNvbG9yIGFzIEZMUC4uLlxuXHRcdHJvbGU6IFJvbGUuT3duZXIsXG5cdFx0bWU6IHRydWVcblx0fTtcblx0bWUubmFtZSArPSBcIiAoWW91KVwiOyAvLyBUT0RPIHJlc291cmNlIGJ1bmRsZVxuXHRyZXR1cm4gbWU7XG59XG5cbmV4cG9ydCBjb25zdCBDb2xsYWJvcmF0aW9uVXRpbHMgPSB7XG5cdGZvcm1hdEluaXRpYWxzOiBmb3JtYXRJbml0aWFscyxcblx0Z2V0VXNlckNvbG9yOiBnZXRVc2VyQ29sb3IsXG5cdGdldE1lOiBnZXRNZSxcblx0Z2V0QXBwQ29tcG9uZW50OiBnZXRBcHBDb21wb25lbnRcbn07XG4iXX0=
@@ -0,0 +1,119 @@
1
+ import View from "sap/ui/core/mvc/View";
2
+ import Component from "sap/ui/core/Component";
3
+ import AppComponent from "sap/fe/core/AppComponent";
4
+
5
+ export type User = {
6
+ id: string;
7
+ initials?: string;
8
+ name: string;
9
+ role?: Role;
10
+ color?: number;
11
+ transient?: boolean;
12
+ me?: boolean;
13
+ };
14
+
15
+ export type UserActivity = User & {
16
+ key?: string;
17
+ };
18
+
19
+ export enum Role {
20
+ Owner = "O",
21
+ Edit = "E"
22
+ }
23
+
24
+ export enum Activity {
25
+ Join = "JOIN",
26
+ JoinEcho = "JOINECHO",
27
+ Leave = "LEAVE",
28
+ Change = "CHANGE",
29
+ Create = "CREATE",
30
+ Delete = "DELETE",
31
+ Action = "ACTION",
32
+ LiveChange = "LIVECHANGE",
33
+ Activate = "ACTIVATE",
34
+ Discard = "DISCARD",
35
+ Undo = "UNDO"
36
+ }
37
+
38
+ export type Message = {
39
+ userDescription: string;
40
+ userID: string;
41
+ userAction: string;
42
+ clientAction: string;
43
+ clientContent: string;
44
+ };
45
+
46
+ function formatInitials(fullName: string): string {
47
+ // remove titles - those are the ones from S/4 to be checked if there are others
48
+ const academicTitles = ["Dr.", "Prof.", "Prof. Dr.", "B.A.", "MBA", "Ph.D."];
49
+ academicTitles.forEach(function(academicTitle) {
50
+ fullName = fullName.replace(academicTitle, "");
51
+ });
52
+
53
+ let initials: string;
54
+ const parts = fullName.trimStart().split(" ");
55
+
56
+ if (parts.length > 1) {
57
+ initials = (parts?.shift()?.charAt(0) || "") + parts.pop()?.charAt(0);
58
+ } else {
59
+ initials = fullName.substring(0, 2);
60
+ }
61
+
62
+ return initials.toUpperCase();
63
+ }
64
+
65
+ function getUserColor(UserID: string, activeUsers: User[], invitedUsers: User[]) {
66
+ // search if user is known
67
+ const user = activeUsers.find(u => u.id === UserID);
68
+ if (user) {
69
+ return user.color;
70
+ } else {
71
+ // search for next free color
72
+ for (let i = 1; i <= 10; i++) {
73
+ if (activeUsers.findIndex(u => u.color === i) === -1 && invitedUsers.findIndex(u => u.color === i) === -1) {
74
+ return i;
75
+ }
76
+ }
77
+ // this seems to be a popular object :) for now just return 10 for all.
78
+ // for invited we should start from 1 again so the colors are different
79
+ return 10;
80
+ }
81
+ }
82
+
83
+ // copied from CommonUtils. Due to a cycle dependency I can't use CommonUtils here.
84
+ // That's to be fixed. the discard popover thingy shouldn't be in the common utils at all
85
+ function getAppComponent(oControl: any): AppComponent {
86
+ if (oControl.isA("sap.fe.core.AppComponent")) {
87
+ return oControl;
88
+ }
89
+ const oOwner = Component.getOwnerComponentFor(oControl);
90
+ if (!oOwner) {
91
+ return oControl;
92
+ } else {
93
+ return getAppComponent(oOwner);
94
+ }
95
+ }
96
+
97
+ function getMe(view: View): User {
98
+ const shellServiceHelper = getAppComponent(view).getShellServices();
99
+ if (!shellServiceHelper || !shellServiceHelper.hasUShell()) {
100
+ throw "No Shell... No User";
101
+ }
102
+ const me: User = {
103
+ initials: shellServiceHelper.getUser().getInitials(),
104
+ id: shellServiceHelper.getUser().getId(),
105
+ name: shellServiceHelper.getUser().getFullName(),
106
+ color: 6, // same color as FLP...
107
+ role: Role.Owner,
108
+ me: true
109
+ };
110
+ me.name += " (You)"; // TODO resource bundle
111
+ return me;
112
+ }
113
+
114
+ export const CollaborationUtils = {
115
+ formatInitials: formatInitials,
116
+ getUserColor: getUserColor,
117
+ getMe: getMe,
118
+ getAppComponent: getAppComponent
119
+ };