@sapui5/sap.cux.home 1.135.0 → 1.136.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 (436) hide show
  1. package/package.json +1 -1
  2. package/src/sap/cux/home/AdvancedSettingsPanel-dbg.js +23 -5
  3. package/src/sap/cux/home/AdvancedSettingsPanel-dbg.js.map +1 -1
  4. package/src/sap/cux/home/AdvancedSettingsPanel.d.ts +7 -0
  5. package/src/sap/cux/home/AdvancedSettingsPanel.d.ts.map +1 -1
  6. package/src/sap/cux/home/AdvancedSettingsPanel.js +1 -1
  7. package/src/sap/cux/home/AdvancedSettingsPanel.js.map +1 -1
  8. package/src/sap/cux/home/AdvancedSettingsPanel.ts +24 -5
  9. package/src/sap/cux/home/AppsAdditionPanel-dbg.js +919 -0
  10. package/src/sap/cux/home/AppsAdditionPanel-dbg.js.map +1 -0
  11. package/src/sap/cux/home/AppsAdditionPanel.d.ts +293 -0
  12. package/src/sap/cux/home/AppsAdditionPanel.d.ts.map +1 -0
  13. package/src/sap/cux/home/AppsAdditionPanel.js +6 -0
  14. package/src/sap/cux/home/AppsAdditionPanel.js.map +1 -0
  15. package/src/sap/cux/home/AppsAdditionPanel.ts +757 -0
  16. package/src/sap/cux/home/AppsContainer-dbg.js +42 -28
  17. package/src/sap/cux/home/AppsContainer-dbg.js.map +1 -1
  18. package/src/sap/cux/home/AppsContainer.d.ts +17 -1
  19. package/src/sap/cux/home/AppsContainer.d.ts.map +1 -1
  20. package/src/sap/cux/home/AppsContainer.js +1 -1
  21. package/src/sap/cux/home/AppsContainer.js.map +1 -1
  22. package/src/sap/cux/home/AppsContainer.ts +27 -6
  23. package/src/sap/cux/home/AppsContainerGenericPlaceholder-dbg.js +261 -0
  24. package/src/sap/cux/home/AppsContainerGenericPlaceholder-dbg.js.map +1 -0
  25. package/src/sap/cux/home/AppsContainerGenericPlaceholder.d.ts +8 -0
  26. package/src/sap/cux/home/AppsContainerGenericPlaceholder.d.ts.map +1 -0
  27. package/src/sap/cux/home/AppsContainerGenericPlaceholder.js +6 -0
  28. package/src/sap/cux/home/AppsContainerGenericPlaceholder.js.map +1 -0
  29. package/src/sap/cux/home/AppsContainerGenericPlaceholder.ts +251 -0
  30. package/src/sap/cux/home/BaseAppPanel-dbg.js +4 -5
  31. package/src/sap/cux/home/BaseAppPanel-dbg.js.map +1 -1
  32. package/src/sap/cux/home/BaseAppPanel.d.ts.map +1 -1
  33. package/src/sap/cux/home/BaseAppPanel.js +1 -1
  34. package/src/sap/cux/home/BaseAppPanel.js.map +1 -1
  35. package/src/sap/cux/home/BaseAppPanel.ts +3 -5
  36. package/src/sap/cux/home/BaseAppPersPanel-dbg.js +2 -1
  37. package/src/sap/cux/home/BaseAppPersPanel-dbg.js.map +1 -1
  38. package/src/sap/cux/home/BaseAppPersPanel.d.ts.map +1 -1
  39. package/src/sap/cux/home/BaseAppPersPanel.js +1 -1
  40. package/src/sap/cux/home/BaseAppPersPanel.js.map +1 -1
  41. package/src/sap/cux/home/BaseAppPersPanel.ts +2 -1
  42. package/src/sap/cux/home/BaseContainer-dbg.js +24 -3
  43. package/src/sap/cux/home/BaseContainer-dbg.js.map +1 -1
  44. package/src/sap/cux/home/BaseContainer.d.ts +10 -0
  45. package/src/sap/cux/home/BaseContainer.d.ts.map +1 -1
  46. package/src/sap/cux/home/BaseContainer.js +1 -1
  47. package/src/sap/cux/home/BaseContainer.js.map +1 -1
  48. package/src/sap/cux/home/BaseContainer.ts +24 -2
  49. package/src/sap/cux/home/BaseContainerRenderer-dbg.js +18 -1
  50. package/src/sap/cux/home/BaseContainerRenderer-dbg.js.map +1 -1
  51. package/src/sap/cux/home/BaseContainerRenderer.d.ts +4 -4
  52. package/src/sap/cux/home/BaseContainerRenderer.d.ts.map +1 -1
  53. package/src/sap/cux/home/BaseContainerRenderer.js +1 -1
  54. package/src/sap/cux/home/BaseContainerRenderer.js.map +1 -1
  55. package/src/sap/cux/home/BaseContainerRenderer.ts +25 -4
  56. package/src/sap/cux/home/BaseLayout-dbg.js +22 -2
  57. package/src/sap/cux/home/BaseLayout-dbg.js.map +1 -1
  58. package/src/sap/cux/home/BaseLayout.d.ts +6 -0
  59. package/src/sap/cux/home/BaseLayout.d.ts.map +1 -1
  60. package/src/sap/cux/home/BaseLayout.js +1 -1
  61. package/src/sap/cux/home/BaseLayout.js.map +1 -1
  62. package/src/sap/cux/home/BaseLayout.ts +23 -2
  63. package/src/sap/cux/home/BaseNewsItem-dbg.js +3 -3
  64. package/src/sap/cux/home/BaseNewsItem-dbg.js.map +1 -1
  65. package/src/sap/cux/home/BaseNewsItem.js +1 -1
  66. package/src/sap/cux/home/BaseNewsItem.js.map +1 -1
  67. package/src/sap/cux/home/BaseNewsItem.ts +3 -3
  68. package/src/sap/cux/home/BaseNewsPanel-dbg.js +4 -5
  69. package/src/sap/cux/home/BaseNewsPanel-dbg.js.map +1 -1
  70. package/src/sap/cux/home/BaseNewsPanel.d.ts.map +1 -1
  71. package/src/sap/cux/home/BaseNewsPanel.js +1 -1
  72. package/src/sap/cux/home/BaseNewsPanel.js.map +1 -1
  73. package/src/sap/cux/home/BaseNewsPanel.ts +5 -4
  74. package/src/sap/cux/home/BasePanel-dbg.js +1 -1
  75. package/src/sap/cux/home/BasePanel-dbg.js.map +1 -1
  76. package/src/sap/cux/home/BasePanel.js +1 -1
  77. package/src/sap/cux/home/BasePanel.js.map +1 -1
  78. package/src/sap/cux/home/BasePanel.ts +1 -1
  79. package/src/sap/cux/home/BaseSettingsDialog-dbg.js +11 -0
  80. package/src/sap/cux/home/BaseSettingsDialog-dbg.js.map +1 -1
  81. package/src/sap/cux/home/BaseSettingsDialog.d.ts.map +1 -1
  82. package/src/sap/cux/home/BaseSettingsDialog.js +1 -1
  83. package/src/sap/cux/home/BaseSettingsDialog.js.map +1 -1
  84. package/src/sap/cux/home/BaseSettingsDialog.ts +12 -0
  85. package/src/sap/cux/home/BaseSettingsPanel-dbg.js +67 -2
  86. package/src/sap/cux/home/BaseSettingsPanel-dbg.js.map +1 -1
  87. package/src/sap/cux/home/BaseSettingsPanel.d.ts +42 -0
  88. package/src/sap/cux/home/BaseSettingsPanel.d.ts.map +1 -1
  89. package/src/sap/cux/home/BaseSettingsPanel.gen.d.ts +75 -0
  90. package/src/sap/cux/home/BaseSettingsPanel.js +1 -1
  91. package/src/sap/cux/home/BaseSettingsPanel.js.map +1 -1
  92. package/src/sap/cux/home/BaseSettingsPanel.ts +70 -2
  93. package/src/sap/cux/home/CardsPanel-dbg.js +548 -168
  94. package/src/sap/cux/home/CardsPanel-dbg.js.map +1 -1
  95. package/src/sap/cux/home/CardsPanel.d.ts +121 -15
  96. package/src/sap/cux/home/CardsPanel.d.ts.map +1 -1
  97. package/src/sap/cux/home/CardsPanel.gen.d.ts +78 -0
  98. package/src/sap/cux/home/CardsPanel.js +1 -1
  99. package/src/sap/cux/home/CardsPanel.js.map +1 -1
  100. package/src/sap/cux/home/CardsPanel.ts +450 -97
  101. package/src/sap/cux/home/ContentAdditionDialog-dbg.js +353 -0
  102. package/src/sap/cux/home/ContentAdditionDialog-dbg.js.map +1 -0
  103. package/src/sap/cux/home/ContentAdditionDialog.d.ts +82 -0
  104. package/src/sap/cux/home/ContentAdditionDialog.d.ts.map +1 -0
  105. package/src/sap/cux/home/ContentAdditionDialog.js +6 -0
  106. package/src/sap/cux/home/ContentAdditionDialog.js.map +1 -0
  107. package/src/sap/cux/home/ContentAdditionDialog.ts +214 -0
  108. package/src/sap/cux/home/ErrorPanel-dbg.js +3 -3
  109. package/src/sap/cux/home/ErrorPanel-dbg.js.map +1 -1
  110. package/src/sap/cux/home/ErrorPanel.d.ts.map +1 -1
  111. package/src/sap/cux/home/ErrorPanel.js +1 -1
  112. package/src/sap/cux/home/ErrorPanel.js.map +1 -1
  113. package/src/sap/cux/home/ErrorPanel.ts +4 -2
  114. package/src/sap/cux/home/FavAppPanel-dbg.js +352 -333
  115. package/src/sap/cux/home/FavAppPanel-dbg.js.map +1 -1
  116. package/src/sap/cux/home/FavAppPanel.d.ts.map +1 -1
  117. package/src/sap/cux/home/FavAppPanel.js +1 -1
  118. package/src/sap/cux/home/FavAppPanel.js.map +1 -1
  119. package/src/sap/cux/home/FavAppPanel.ts +63 -54
  120. package/src/sap/cux/home/InsightsAdditionPanel-dbg.js +97 -0
  121. package/src/sap/cux/home/InsightsAdditionPanel-dbg.js.map +1 -0
  122. package/src/sap/cux/home/InsightsAdditionPanel.d.ts +57 -0
  123. package/src/sap/cux/home/InsightsAdditionPanel.d.ts.map +1 -0
  124. package/src/sap/cux/home/InsightsAdditionPanel.js +6 -0
  125. package/src/sap/cux/home/InsightsAdditionPanel.js.map +1 -0
  126. package/src/sap/cux/home/InsightsAdditionPanel.ts +94 -0
  127. package/src/sap/cux/home/InsightsContainer-dbg.js +22 -2
  128. package/src/sap/cux/home/InsightsContainer-dbg.js.map +1 -1
  129. package/src/sap/cux/home/InsightsContainer.d.ts +14 -0
  130. package/src/sap/cux/home/InsightsContainer.d.ts.map +1 -1
  131. package/src/sap/cux/home/InsightsContainer.js +1 -1
  132. package/src/sap/cux/home/InsightsContainer.js.map +1 -1
  133. package/src/sap/cux/home/InsightsContainer.ts +22 -1
  134. package/src/sap/cux/home/InsightsContainerGenericPlaceholder-dbg.js +401 -0
  135. package/src/sap/cux/home/InsightsContainerGenericPlaceholder-dbg.js.map +1 -0
  136. package/src/sap/cux/home/InsightsContainerGenericPlaceholder.d.ts +8 -0
  137. package/src/sap/cux/home/InsightsContainerGenericPlaceholder.d.ts.map +1 -0
  138. package/src/sap/cux/home/InsightsContainerGenericPlaceholder.js +6 -0
  139. package/src/sap/cux/home/InsightsContainerGenericPlaceholder.js.map +1 -0
  140. package/src/sap/cux/home/InsightsContainerGenericPlaceholder.ts +391 -0
  141. package/src/sap/cux/home/KeyUserLayoutSettingsPanel-dbg.js +10 -9
  142. package/src/sap/cux/home/KeyUserLayoutSettingsPanel-dbg.js.map +1 -1
  143. package/src/sap/cux/home/KeyUserLayoutSettingsPanel.d.ts.map +1 -1
  144. package/src/sap/cux/home/KeyUserLayoutSettingsPanel.js +1 -1
  145. package/src/sap/cux/home/KeyUserLayoutSettingsPanel.js.map +1 -1
  146. package/src/sap/cux/home/KeyUserLayoutSettingsPanel.ts +9 -8
  147. package/src/sap/cux/home/KeyUserNewsPagesSettingsPanel-dbg.js +2 -2
  148. package/src/sap/cux/home/KeyUserNewsPagesSettingsPanel-dbg.js.map +1 -1
  149. package/src/sap/cux/home/KeyUserNewsPagesSettingsPanel.js +1 -1
  150. package/src/sap/cux/home/KeyUserNewsPagesSettingsPanel.js.map +1 -1
  151. package/src/sap/cux/home/KeyUserNewsPagesSettingsPanel.ts +2 -2
  152. package/src/sap/cux/home/KeyUserPagesSettingsPanel-dbg.js +6 -6
  153. package/src/sap/cux/home/KeyUserPagesSettingsPanel-dbg.js.map +1 -1
  154. package/src/sap/cux/home/KeyUserPagesSettingsPanel.js +1 -1
  155. package/src/sap/cux/home/KeyUserPagesSettingsPanel.js.map +1 -1
  156. package/src/sap/cux/home/KeyUserPagesSettingsPanel.ts +6 -6
  157. package/src/sap/cux/home/Layout-dbg.js +58 -33
  158. package/src/sap/cux/home/Layout-dbg.js.map +1 -1
  159. package/src/sap/cux/home/Layout.d.ts +13 -0
  160. package/src/sap/cux/home/Layout.d.ts.map +1 -1
  161. package/src/sap/cux/home/Layout.js +1 -1
  162. package/src/sap/cux/home/Layout.js.map +1 -1
  163. package/src/sap/cux/home/Layout.ts +48 -20
  164. package/src/sap/cux/home/LayoutSettingsPanel-dbg.js +1 -10
  165. package/src/sap/cux/home/LayoutSettingsPanel-dbg.js.map +1 -1
  166. package/src/sap/cux/home/LayoutSettingsPanel.d.ts.map +1 -1
  167. package/src/sap/cux/home/LayoutSettingsPanel.js +1 -1
  168. package/src/sap/cux/home/LayoutSettingsPanel.js.map +1 -1
  169. package/src/sap/cux/home/LayoutSettingsPanel.ts +2 -10
  170. package/src/sap/cux/home/NewsAndPagesContainer-dbg.js +35 -17
  171. package/src/sap/cux/home/NewsAndPagesContainer-dbg.js.map +1 -1
  172. package/src/sap/cux/home/NewsAndPagesContainer.d.ts +7 -0
  173. package/src/sap/cux/home/NewsAndPagesContainer.d.ts.map +1 -1
  174. package/src/sap/cux/home/NewsAndPagesContainer.js +1 -1
  175. package/src/sap/cux/home/NewsAndPagesContainer.js.map +1 -1
  176. package/src/sap/cux/home/NewsAndPagesContainer.ts +40 -16
  177. package/src/sap/cux/home/NewsAndPagesContainerGenericPlaceholder-dbg.js +164 -0
  178. package/src/sap/cux/home/NewsAndPagesContainerGenericPlaceholder-dbg.js.map +1 -0
  179. package/src/sap/cux/home/NewsAndPagesContainerGenericPlaceholder.d.ts +8 -0
  180. package/src/sap/cux/home/NewsAndPagesContainerGenericPlaceholder.d.ts.map +1 -0
  181. package/src/sap/cux/home/NewsAndPagesContainerGenericPlaceholder.js +6 -0
  182. package/src/sap/cux/home/NewsAndPagesContainerGenericPlaceholder.js.map +1 -0
  183. package/src/sap/cux/home/NewsAndPagesContainerGenericPlaceholder.ts +154 -0
  184. package/src/sap/cux/home/NewsGroup-dbg.js +112 -79
  185. package/src/sap/cux/home/NewsGroup-dbg.js.map +1 -1
  186. package/src/sap/cux/home/NewsGroup.d.ts +1 -0
  187. package/src/sap/cux/home/NewsGroup.d.ts.map +1 -1
  188. package/src/sap/cux/home/NewsGroup.js +1 -1
  189. package/src/sap/cux/home/NewsGroup.js.map +1 -1
  190. package/src/sap/cux/home/NewsGroup.ts +136 -100
  191. package/src/sap/cux/home/NewsPanel-dbg.js +541 -173
  192. package/src/sap/cux/home/NewsPanel-dbg.js.map +1 -1
  193. package/src/sap/cux/home/NewsPanel.d.ts +156 -16
  194. package/src/sap/cux/home/NewsPanel.d.ts.map +1 -1
  195. package/src/sap/cux/home/NewsPanel.js +1 -1
  196. package/src/sap/cux/home/NewsPanel.js.map +1 -1
  197. package/src/sap/cux/home/NewsPanel.ts +452 -82
  198. package/src/sap/cux/home/NewsSettingsPanel-dbg.js +61 -20
  199. package/src/sap/cux/home/NewsSettingsPanel-dbg.js.map +1 -1
  200. package/src/sap/cux/home/NewsSettingsPanel.d.ts +14 -0
  201. package/src/sap/cux/home/NewsSettingsPanel.d.ts.map +1 -1
  202. package/src/sap/cux/home/NewsSettingsPanel.js +1 -1
  203. package/src/sap/cux/home/NewsSettingsPanel.js.map +1 -1
  204. package/src/sap/cux/home/NewsSettingsPanel.ts +75 -21
  205. package/src/sap/cux/home/NoDataContainer-dbg.js +3 -3
  206. package/src/sap/cux/home/NoDataContainer-dbg.js.map +1 -1
  207. package/src/sap/cux/home/NoDataContainer.d.ts +1 -0
  208. package/src/sap/cux/home/NoDataContainer.d.ts.map +1 -1
  209. package/src/sap/cux/home/NoDataContainer.js +1 -1
  210. package/src/sap/cux/home/NoDataContainer.js.map +1 -1
  211. package/src/sap/cux/home/NoDataContainer.ts +4 -2
  212. package/src/sap/cux/home/PagePanel-dbg.js +86 -75
  213. package/src/sap/cux/home/PagePanel-dbg.js.map +1 -1
  214. package/src/sap/cux/home/PagePanel.d.ts +25 -3
  215. package/src/sap/cux/home/PagePanel.d.ts.map +1 -1
  216. package/src/sap/cux/home/PagePanel.js +1 -1
  217. package/src/sap/cux/home/PagePanel.js.map +1 -1
  218. package/src/sap/cux/home/PagePanel.ts +91 -76
  219. package/src/sap/cux/home/PageSettingsPanel-dbg.js +16 -15
  220. package/src/sap/cux/home/PageSettingsPanel-dbg.js.map +1 -1
  221. package/src/sap/cux/home/PageSettingsPanel.d.ts.map +1 -1
  222. package/src/sap/cux/home/PageSettingsPanel.js +1 -1
  223. package/src/sap/cux/home/PageSettingsPanel.js.map +1 -1
  224. package/src/sap/cux/home/PageSettingsPanel.ts +15 -14
  225. package/src/sap/cux/home/RecentAppPanel-dbg.js +2 -2
  226. package/src/sap/cux/home/RecentAppPanel-dbg.js.map +1 -1
  227. package/src/sap/cux/home/RecentAppPanel.js +1 -1
  228. package/src/sap/cux/home/RecentAppPanel.js.map +1 -1
  229. package/src/sap/cux/home/RecentAppPanel.ts +2 -2
  230. package/src/sap/cux/home/RecommendedAppPanel-dbg.js +4 -3
  231. package/src/sap/cux/home/RecommendedAppPanel-dbg.js.map +1 -1
  232. package/src/sap/cux/home/RecommendedAppPanel.d.ts.map +1 -1
  233. package/src/sap/cux/home/RecommendedAppPanel.js +1 -1
  234. package/src/sap/cux/home/RecommendedAppPanel.js.map +1 -1
  235. package/src/sap/cux/home/RecommendedAppPanel.ts +4 -2
  236. package/src/sap/cux/home/SettingsDialog-dbg.js +4 -3
  237. package/src/sap/cux/home/SettingsDialog-dbg.js.map +1 -1
  238. package/src/sap/cux/home/SettingsDialog.d.ts.map +1 -1
  239. package/src/sap/cux/home/SettingsDialog.js +1 -1
  240. package/src/sap/cux/home/SettingsDialog.js.map +1 -1
  241. package/src/sap/cux/home/SettingsDialog.ts +4 -2
  242. package/src/sap/cux/home/TaskPanel-dbg.js +16 -12
  243. package/src/sap/cux/home/TaskPanel-dbg.js.map +1 -1
  244. package/src/sap/cux/home/TaskPanel.d.ts +1 -2
  245. package/src/sap/cux/home/TaskPanel.d.ts.map +1 -1
  246. package/src/sap/cux/home/TaskPanel.js +1 -1
  247. package/src/sap/cux/home/TaskPanel.js.map +1 -1
  248. package/src/sap/cux/home/TaskPanel.ts +19 -12
  249. package/src/sap/cux/home/TilesPanel-dbg.js +9 -8
  250. package/src/sap/cux/home/TilesPanel-dbg.js.map +1 -1
  251. package/src/sap/cux/home/TilesPanel.d.ts.map +1 -1
  252. package/src/sap/cux/home/TilesPanel.js +1 -1
  253. package/src/sap/cux/home/TilesPanel.js.map +1 -1
  254. package/src/sap/cux/home/TilesPanel.ts +15 -8
  255. package/src/sap/cux/home/ToDoPanel-dbg.js +34 -25
  256. package/src/sap/cux/home/ToDoPanel-dbg.js.map +1 -1
  257. package/src/sap/cux/home/ToDoPanel.d.ts +0 -7
  258. package/src/sap/cux/home/ToDoPanel.d.ts.map +1 -1
  259. package/src/sap/cux/home/ToDoPanel.js +1 -1
  260. package/src/sap/cux/home/ToDoPanel.js.map +1 -1
  261. package/src/sap/cux/home/ToDoPanel.ts +27 -29
  262. package/src/sap/cux/home/ToDosContainer-dbg.js +27 -18
  263. package/src/sap/cux/home/ToDosContainer-dbg.js.map +1 -1
  264. package/src/sap/cux/home/ToDosContainer.d.ts +7 -0
  265. package/src/sap/cux/home/ToDosContainer.d.ts.map +1 -1
  266. package/src/sap/cux/home/ToDosContainer.js +1 -1
  267. package/src/sap/cux/home/ToDosContainer.js.map +1 -1
  268. package/src/sap/cux/home/ToDosContainer.ts +10 -0
  269. package/src/sap/cux/home/ToDosContainerGenericPlaceholder-dbg.js +84 -0
  270. package/src/sap/cux/home/ToDosContainerGenericPlaceholder-dbg.js.map +1 -0
  271. package/src/sap/cux/home/ToDosContainerGenericPlaceholder.d.ts +8 -0
  272. package/src/sap/cux/home/ToDosContainerGenericPlaceholder.d.ts.map +1 -0
  273. package/src/sap/cux/home/ToDosContainerGenericPlaceholder.js +6 -0
  274. package/src/sap/cux/home/ToDosContainerGenericPlaceholder.js.map +1 -0
  275. package/src/sap/cux/home/ToDosContainerGenericPlaceholder.ts +74 -0
  276. package/src/sap/cux/home/i18n/messagebundle.properties +63 -1
  277. package/src/sap/cux/home/i18n/messagebundle_ar.properties +42 -1
  278. package/src/sap/cux/home/i18n/messagebundle_bg.properties +43 -1
  279. package/src/sap/cux/home/i18n/messagebundle_ca.properties +43 -1
  280. package/src/sap/cux/home/i18n/messagebundle_cnr.properties +43 -1
  281. package/src/sap/cux/home/i18n/messagebundle_cs.properties +43 -1
  282. package/src/sap/cux/home/i18n/messagebundle_cy.properties +43 -1
  283. package/src/sap/cux/home/i18n/messagebundle_da.properties +43 -1
  284. package/src/sap/cux/home/i18n/messagebundle_de.properties +43 -1
  285. package/src/sap/cux/home/i18n/messagebundle_el.properties +44 -2
  286. package/src/sap/cux/home/i18n/messagebundle_en.properties +43 -246
  287. package/src/sap/cux/home/i18n/messagebundle_en_GB.properties +43 -1
  288. package/src/sap/cux/home/i18n/messagebundle_en_US_sappsd.properties +43 -1
  289. package/src/sap/cux/home/i18n/messagebundle_en_US_saprigi.properties +31 -1
  290. package/src/sap/cux/home/i18n/messagebundle_en_US_saptrc.properties +43 -1
  291. package/src/sap/cux/home/i18n/messagebundle_es.properties +43 -1
  292. package/src/sap/cux/home/i18n/messagebundle_es_MX.properties +43 -1
  293. package/src/sap/cux/home/i18n/messagebundle_et.properties +43 -1
  294. package/src/sap/cux/home/i18n/messagebundle_fi.properties +43 -1
  295. package/src/sap/cux/home/i18n/messagebundle_fr.properties +43 -1
  296. package/src/sap/cux/home/i18n/messagebundle_fr_CA.properties +42 -1
  297. package/src/sap/cux/home/i18n/messagebundle_hi.properties +43 -1
  298. package/src/sap/cux/home/i18n/messagebundle_hr.properties +42 -1
  299. package/src/sap/cux/home/i18n/messagebundle_hu.properties +43 -1
  300. package/src/sap/cux/home/i18n/messagebundle_id.properties +47 -5
  301. package/src/sap/cux/home/i18n/messagebundle_it.properties +43 -1
  302. package/src/sap/cux/home/i18n/messagebundle_iw.properties +43 -1
  303. package/src/sap/cux/home/i18n/messagebundle_ja.properties +43 -1
  304. package/src/sap/cux/home/i18n/messagebundle_kk.properties +43 -1
  305. package/src/sap/cux/home/i18n/messagebundle_ko.properties +43 -1
  306. package/src/sap/cux/home/i18n/messagebundle_lt.properties +42 -1
  307. package/src/sap/cux/home/i18n/messagebundle_lv.properties +43 -1
  308. package/src/sap/cux/home/i18n/messagebundle_mk.properties +43 -1
  309. package/src/sap/cux/home/i18n/messagebundle_ms.properties +43 -1
  310. package/src/sap/cux/home/i18n/messagebundle_nl.properties +43 -1
  311. package/src/sap/cux/home/i18n/messagebundle_no.properties +44 -2
  312. package/src/sap/cux/home/i18n/messagebundle_pl.properties +44 -2
  313. package/src/sap/cux/home/i18n/messagebundle_pt.properties +43 -1
  314. package/src/sap/cux/home/i18n/messagebundle_pt_PT.properties +43 -1
  315. package/src/sap/cux/home/i18n/messagebundle_ro.properties +43 -1
  316. package/src/sap/cux/home/i18n/messagebundle_ru.properties +43 -1
  317. package/src/sap/cux/home/i18n/messagebundle_sh.properties +43 -1
  318. package/src/sap/cux/home/i18n/messagebundle_sk.properties +42 -1
  319. package/src/sap/cux/home/i18n/messagebundle_sl.properties +44 -2
  320. package/src/sap/cux/home/i18n/messagebundle_sr.properties +43 -1
  321. package/src/sap/cux/home/i18n/messagebundle_sv.properties +43 -1
  322. package/src/sap/cux/home/i18n/messagebundle_th.properties +43 -2
  323. package/src/sap/cux/home/i18n/messagebundle_tr.properties +42 -1
  324. package/src/sap/cux/home/i18n/messagebundle_uk.properties +43 -1
  325. package/src/sap/cux/home/i18n/messagebundle_vi.properties +42 -1
  326. package/src/sap/cux/home/i18n/messagebundle_zh_CN.properties +43 -1
  327. package/src/sap/cux/home/i18n/messagebundle_zh_TW.properties +42 -1
  328. package/src/sap/cux/home/interface/AppsInterface-dbg.js.map +1 -1
  329. package/src/sap/cux/home/interface/AppsInterface.d.ts +5 -3
  330. package/src/sap/cux/home/interface/AppsInterface.d.ts.map +1 -1
  331. package/src/sap/cux/home/interface/AppsInterface.ts +5 -3
  332. package/src/sap/cux/home/interface/CardsInterface-dbg.js +32 -0
  333. package/src/sap/cux/home/interface/CardsInterface-dbg.js.map +1 -1
  334. package/src/sap/cux/home/interface/CardsInterface.d.ts +320 -55
  335. package/src/sap/cux/home/interface/CardsInterface.d.ts.map +1 -1
  336. package/src/sap/cux/home/interface/CardsInterface.js +5 -1
  337. package/src/sap/cux/home/interface/CardsInterface.js.map +1 -1
  338. package/src/sap/cux/home/interface/CardsInterface.ts +359 -55
  339. package/src/sap/cux/home/library-preload.js +88 -45
  340. package/src/sap/cux/home/library-preload.js.map +1 -1
  341. package/src/sap/cux/home/manifest.json +4 -4
  342. package/src/sap/cux/home/themes/base/AppsContainer.less +12 -0
  343. package/src/sap/cux/home/themes/base/BaseLayout.less +1 -0
  344. package/src/sap/cux/home/themes/base/ContentAdditionDialog.less +69 -0
  345. package/src/sap/cux/home/themes/base/NewsAndPagesContainer.less +37 -12
  346. package/src/sap/cux/home/themes/base/PlaceHolder.less +1374 -0
  347. package/src/sap/cux/home/themes/base/ToDosContainer.less +1 -1
  348. package/src/sap/cux/home/themes/base/library-RTL.css +2 -2
  349. package/src/sap/cux/home/themes/base/library-parameters.json +1 -1
  350. package/src/sap/cux/home/themes/base/library.css +2 -2
  351. package/src/sap/cux/home/themes/base/library.source.less +2 -0
  352. package/src/sap/cux/home/themes/sap_fiori_3/library-RTL.css +2 -2
  353. package/src/sap/cux/home/themes/sap_fiori_3/library-parameters.json +1 -1
  354. package/src/sap/cux/home/themes/sap_fiori_3/library.css +2 -2
  355. package/src/sap/cux/home/themes/sap_fiori_3_dark/library-RTL.css +2 -2
  356. package/src/sap/cux/home/themes/sap_fiori_3_dark/library-parameters.json +1 -1
  357. package/src/sap/cux/home/themes/sap_fiori_3_dark/library.css +2 -2
  358. package/src/sap/cux/home/themes/sap_fiori_3_hcb/AppsContainer.less +1 -0
  359. package/src/sap/cux/home/themes/sap_fiori_3_hcb/library-RTL.css +2 -2
  360. package/src/sap/cux/home/themes/sap_fiori_3_hcb/library-parameters.json +1 -1
  361. package/src/sap/cux/home/themes/sap_fiori_3_hcb/library.css +2 -2
  362. package/src/sap/cux/home/themes/sap_fiori_3_hcb/library.source.less +2 -0
  363. package/src/sap/cux/home/themes/sap_fiori_3_hcw/AppsContainer.less +1 -0
  364. package/src/sap/cux/home/themes/sap_fiori_3_hcw/library-RTL.css +2 -2
  365. package/src/sap/cux/home/themes/sap_fiori_3_hcw/library-parameters.json +1 -1
  366. package/src/sap/cux/home/themes/sap_fiori_3_hcw/library.css +2 -2
  367. package/src/sap/cux/home/themes/sap_fiori_3_hcw/library.source.less +2 -0
  368. package/src/sap/cux/home/themes/sap_horizon/library-RTL.css +2 -2
  369. package/src/sap/cux/home/themes/sap_horizon/library-parameters.json +1 -1
  370. package/src/sap/cux/home/themes/sap_horizon/library.css +2 -2
  371. package/src/sap/cux/home/themes/sap_horizon_dark/library-RTL.css +2 -2
  372. package/src/sap/cux/home/themes/sap_horizon_dark/library-parameters.json +1 -1
  373. package/src/sap/cux/home/themes/sap_horizon_dark/library.css +2 -2
  374. package/src/sap/cux/home/themes/sap_horizon_hcb/AppsContainer.less +1 -0
  375. package/src/sap/cux/home/themes/sap_horizon_hcb/library-RTL.css +2 -2
  376. package/src/sap/cux/home/themes/sap_horizon_hcb/library-parameters.json +1 -1
  377. package/src/sap/cux/home/themes/sap_horizon_hcb/library.css +2 -2
  378. package/src/sap/cux/home/themes/sap_horizon_hcb/library.source.less +2 -0
  379. package/src/sap/cux/home/themes/sap_horizon_hcw/AppsContainer.less +1 -0
  380. package/src/sap/cux/home/themes/sap_horizon_hcw/library-RTL.css +2 -2
  381. package/src/sap/cux/home/themes/sap_horizon_hcw/library-parameters.json +1 -1
  382. package/src/sap/cux/home/themes/sap_horizon_hcw/library.css +2 -2
  383. package/src/sap/cux/home/themes/sap_horizon_hcw/library.source.less +2 -0
  384. package/src/sap/cux/home/utils/AppManager-dbg.js +405 -440
  385. package/src/sap/cux/home/utils/AppManager-dbg.js.map +1 -1
  386. package/src/sap/cux/home/utils/AppManager.d.ts +88 -124
  387. package/src/sap/cux/home/utils/AppManager.d.ts.map +1 -1
  388. package/src/sap/cux/home/utils/AppManager.js +1 -1
  389. package/src/sap/cux/home/utils/AppManager.js.map +1 -1
  390. package/src/sap/cux/home/utils/AppManager.ts +351 -542
  391. package/src/sap/cux/home/utils/Constants-dbg.js +25 -1
  392. package/src/sap/cux/home/utils/Constants-dbg.js.map +1 -1
  393. package/src/sap/cux/home/utils/Constants.d.ts +17 -0
  394. package/src/sap/cux/home/utils/Constants.d.ts.map +1 -1
  395. package/src/sap/cux/home/utils/Constants.js +1 -1
  396. package/src/sap/cux/home/utils/Constants.js.map +1 -1
  397. package/src/sap/cux/home/utils/Constants.ts +20 -1
  398. package/src/sap/cux/home/utils/Device-dbg.js +49 -1
  399. package/src/sap/cux/home/utils/Device-dbg.js.map +1 -1
  400. package/src/sap/cux/home/utils/Device.d.ts +13 -0
  401. package/src/sap/cux/home/utils/Device.d.ts.map +1 -1
  402. package/src/sap/cux/home/utils/Device.js +1 -1
  403. package/src/sap/cux/home/utils/Device.js.map +1 -1
  404. package/src/sap/cux/home/utils/Device.ts +58 -1
  405. package/src/sap/cux/home/utils/InsightsUtils-dbg.js +25 -0
  406. package/src/sap/cux/home/utils/InsightsUtils-dbg.js.map +1 -1
  407. package/src/sap/cux/home/utils/InsightsUtils.d.ts +14 -0
  408. package/src/sap/cux/home/utils/InsightsUtils.d.ts.map +1 -1
  409. package/src/sap/cux/home/utils/InsightsUtils.js +1 -1
  410. package/src/sap/cux/home/utils/InsightsUtils.js.map +1 -1
  411. package/src/sap/cux/home/utils/InsightsUtils.ts +25 -0
  412. package/src/sap/cux/home/utils/PerformanceUtils-dbg.js +5 -2
  413. package/src/sap/cux/home/utils/PerformanceUtils-dbg.js.map +1 -1
  414. package/src/sap/cux/home/utils/PerformanceUtils.d.ts +1 -0
  415. package/src/sap/cux/home/utils/PerformanceUtils.d.ts.map +1 -1
  416. package/src/sap/cux/home/utils/PerformanceUtils.js +1 -1
  417. package/src/sap/cux/home/utils/PerformanceUtils.js.map +1 -1
  418. package/src/sap/cux/home/utils/PerformanceUtils.ts +5 -1
  419. package/src/sap/cux/home/utils/RecommendedCardUtil-dbg.js +1599 -0
  420. package/src/sap/cux/home/utils/RecommendedCardUtil-dbg.js.map +1 -0
  421. package/src/sap/cux/home/utils/RecommendedCardUtil.d.ts +534 -0
  422. package/src/sap/cux/home/utils/RecommendedCardUtil.d.ts.map +1 -0
  423. package/src/sap/cux/home/utils/RecommendedCardUtil.js +6 -0
  424. package/src/sap/cux/home/utils/RecommendedCardUtil.js.map +1 -0
  425. package/src/sap/cux/home/utils/RecommendedCardUtil.ts +1945 -0
  426. package/src/sap/cux/home/utils/SituationUtils-dbg.js +1 -1
  427. package/src/sap/cux/home/utils/SituationUtils-dbg.js.map +1 -1
  428. package/src/sap/cux/home/utils/SituationUtils.js +1 -1
  429. package/src/sap/cux/home/utils/SituationUtils.js.map +1 -1
  430. package/src/sap/cux/home/utils/SituationUtils.ts +1 -1
  431. package/src/sap/cux/home/utils/UshellPersonalizer-dbg.js.map +1 -1
  432. package/src/sap/cux/home/utils/UshellPersonalizer.d.ts +4 -1
  433. package/src/sap/cux/home/utils/UshellPersonalizer.d.ts.map +1 -1
  434. package/src/sap/cux/home/utils/UshellPersonalizer.js.map +1 -1
  435. package/src/sap/cux/home/utils/UshellPersonalizer.ts +2 -1
  436. package/src/sap/cux/home/utils/fragment/appsAdditionContent.fragment.xml +126 -0
@@ -22,6 +22,8 @@ import NewsAndPagesContainer from "./NewsAndPagesContainer";
22
22
  import NewsGroup from "./NewsGroup";
23
23
  import NewsItem from "./NewsItem";
24
24
  import { NewsType } from "./library";
25
+ import { DEFAULT_NEWS_URL } from "./utils/Constants";
26
+ import { recycleId } from "./utils/DataFormatUtils";
25
27
  import { DeviceType } from "./utils/Device";
26
28
  import { addFESRId } from "./utils/FESRUtil";
27
29
  import HttpHelper from "./utils/HttpHelper";
@@ -38,7 +40,14 @@ interface INewsResponse {
38
40
  }
39
41
 
40
42
  export interface ICustomNewsFeed {
41
- [key: string]: string | boolean | INewsLink | number | INewsLink[] | INewsParam;
43
+ title: string;
44
+ subTitle?: string;
45
+ description?: string;
46
+ footer_text?: Record<string, string>;
47
+ mandatory_text?: string;
48
+ _group_to_image?: Record<string, string>;
49
+ _group_to_article?: ICustomNewsFeed[];
50
+ [key: string]: unknown;
42
51
  }
43
52
 
44
53
  export interface INewsItem {
@@ -58,6 +67,12 @@ interface IAppConfiguration {
58
67
  };
59
68
  }
60
69
 
70
+ interface ODataResponse {
71
+ "@odata.context": string;
72
+ "@odata.metadataEtag": string;
73
+ value: ICustomNewsFeed[];
74
+ }
75
+
61
76
  interface IAvailableApp {
62
77
  semanticObject?: string;
63
78
  action?: string;
@@ -86,7 +101,10 @@ interface IAppParameter {
86
101
  };
87
102
  required: boolean;
88
103
  }
89
-
104
+ interface IFavNewsFeed {
105
+ items: string[];
106
+ showAllPreparationRequired?: boolean;
107
+ }
90
108
  export interface INewsLink {
91
109
  [key: string]: string;
92
110
  }
@@ -100,7 +118,6 @@ export type FileFormat = "xlsx" | "csv";
100
118
  const BASE_URL = "/sap/opu/odata4/ui2/insights_srv/srvd/ui2/",
101
119
  NEWS_FEED_READ_API = BASE_URL + "insights_read_srv/0001/" + "NEWS_FEED",
102
120
  NEWS_FEED_TRANSLATION_API = BASE_URL + "insights_read_srv/0001/" + "NewsFeedColumnTranslation",
103
- NEWS_FEED_COUNT_URL = NEWS_FEED_READ_API + "/$count",
104
121
  DEFAULT_FEED_COUNT = 7,
105
122
  fnImagePlaceholder = function (sPath: string, N: number) {
106
123
  return Array.from({ length: N }, function (v, i) {
@@ -165,8 +182,11 @@ export default class NewsPanel extends BaseNewsPanel {
165
182
  private image!: number;
166
183
  private customNewsFeedCache: Map<string, unknown>;
167
184
  private bNewsLoad!: boolean;
168
- private aFavNewsFeed!: { items: string[]; showAllPreparationRequired: boolean };
185
+ private favNewsFeed!: IFavNewsFeed;
169
186
  private _eventBus!: EventBus;
187
+ private _defaultNews!: ODataResponse;
188
+ private mandatoryNewsFeed!: string[];
189
+ private _defaultNewsPromise: Promise<ODataResponse> | null = null;
170
190
 
171
191
  static readonly metadata: MetadataOptions = {
172
192
  library: "sap.cux.home",
@@ -260,7 +280,7 @@ export default class NewsPanel extends BaseNewsPanel {
260
280
  frameType: "Stretch" as FrameType
261
281
  })
262
282
  ]
263
- }).addStyleClass("newsTileMaxWidth");
283
+ }).addStyleClass("newsTileMaxWidth sapUiSmallMarginTop");
264
284
  addFESRId(this.oNewsTile, "newsSlidePress");
265
285
  this.getNewsWrapper().addContent(this.oNewsTile);
266
286
  this.getNewsWrapper().addStyleClass("newsWrapper");
@@ -274,6 +294,24 @@ export default class NewsPanel extends BaseNewsPanel {
274
294
  });
275
295
  this.addAggregation("menuItems", this.oManageMenuItem);
276
296
  addFESRId(this.oManageMenuItem, "manageNews");
297
+ let defaultNewsEnabled = this.isURLParamEnabled("default-News");
298
+ // if Default News url param is enabled, show default news only
299
+ if (defaultNewsEnabled) {
300
+ this.setUrl(DEFAULT_NEWS_URL);
301
+ this.setProperty("showCustom", false);
302
+ }
303
+ }
304
+
305
+ /**
306
+ *
307
+ * @param paramName name of parameter
308
+ * This method checks if the URL parameter is enabled.
309
+ * @returns {boolean} True if the parameter is enabled, false otherwise.
310
+ * @private
311
+ */
312
+ public isURLParamEnabled(paramName: string): boolean {
313
+ const urlParams = new URLSearchParams(window.location.search);
314
+ return urlParams.get(paramName)?.toUpperCase() === "TRUE";
277
315
  }
278
316
 
279
317
  /**
@@ -283,12 +321,25 @@ export default class NewsPanel extends BaseNewsPanel {
283
321
  * @returns {Promise} A promise that resolves when the news data is retrieved.
284
322
  */
285
323
  public async getData() {
286
- const sUrl: string = this.getUrl();
287
- if (sUrl && !this.getProperty("showCustom")) {
324
+ let sUrl: string = this.getUrl();
325
+ let defaultNewsEnabled = this.isURLParamEnabled("default-News");
326
+ this.mandatoryNewsFeed = [];
327
+ if (!this.favNewsFeed) {
328
+ await this.setFavNewsFeed(defaultNewsEnabled);
329
+ }
330
+
331
+ if (sUrl && sUrl !== DEFAULT_NEWS_URL && !this.getProperty("showCustom")) {
332
+ //rss feed scenario
288
333
  this.oNewsModel = await this.initializeXmlModel(sUrl);
289
334
  this.oNewsTile.setModel(this.oNewsModel);
290
335
  this.oManageMenuItem.setVisible(false);
336
+ } else if (sUrl == DEFAULT_NEWS_URL && !this.getProperty("showCustom")) {
337
+ // default news scenario
338
+ this.bNewsLoad = this.bNewsLoad || false;
339
+ this.oManageMenuItem.setVisible(true);
340
+ void this.setCustomNewsFeed("");
291
341
  } else if (this.getProperty("showCustom")) {
342
+ //custom news scenario
292
343
  this.bNewsLoad = this.bNewsLoad || false;
293
344
  this.oManageMenuItem.setVisible(true);
294
345
  const sCustomNewsFeedKey = this.getCustomFeedKey();
@@ -301,7 +352,24 @@ export default class NewsPanel extends BaseNewsPanel {
301
352
  this.handleFeedError();
302
353
  }
303
354
  this.fireEvent("loaded");
304
- this._adjustLayout();
355
+ this.adjustLayout();
356
+ }
357
+
358
+ /**
359
+ * Retrieves the current news group data based on the provided id.
360
+ *
361
+ * @param id - The group ID
362
+ * @returns The news group object that matches the extracted group ID, or `undefined`
363
+ * if no matching group is found.
364
+ * @private
365
+ */
366
+ public getCurrentNewsGroup(id: string) {
367
+ let aValues = this._defaultNews.value;
368
+ let aGroupId = id.split("-");
369
+ // find the groupid from the sId
370
+ let groupId = aGroupId?.[aGroupId.length - 1];
371
+ let currentGroup = aValues.find((oGroup) => oGroup.group_id === groupId);
372
+ return currentGroup;
305
373
  }
306
374
 
307
375
  /**
@@ -368,7 +436,7 @@ export default class NewsPanel extends BaseNewsPanel {
368
436
  */
369
437
  private async loadNewsFeed(oDocument: Document, noOfFeeds: number) {
370
438
  let oBindingInfo: IBindingInfo;
371
- if (!oDocument?.querySelector("customFeed")) {
439
+ if (!oDocument?.querySelector("customFeed") && !oDocument?.querySelector("defaultFeed")) {
372
440
  await this.extractAllImageUrls(oDocument, noOfFeeds || DEFAULT_FEED_COUNT);
373
441
  }
374
442
 
@@ -382,7 +450,11 @@ export default class NewsPanel extends BaseNewsPanel {
382
450
  path: "/entry/",
383
451
  length: noOfFeeds || DEFAULT_FEED_COUNT
384
452
  };
385
- } else if (!!oDocument?.querySelector("customFeed") && !!oDocument?.querySelector("item")) {
453
+ } else if (
454
+ (!!oDocument?.querySelector("customFeed") || !!oDocument?.querySelector("defaultFeed")) &&
455
+ !!oDocument?.querySelector("item")
456
+ ) {
457
+ this.destroyAggregation("newsItems");
386
458
  oBindingInfo = {
387
459
  path: "/item/",
388
460
  length: noOfFeeds || DEFAULT_FEED_COUNT
@@ -399,7 +471,7 @@ export default class NewsPanel extends BaseNewsPanel {
399
471
  * @returns {void}
400
472
  */
401
473
  public handleFeedError(): void {
402
- if (this.getProperty("showCustom")) {
474
+ if (this.getProperty("showCustom") || this.getUrl() === DEFAULT_NEWS_URL) {
403
475
  this.generateErrorMessage().setVisible(true);
404
476
  this.oNewsTile.setVisible(false);
405
477
  } else {
@@ -419,14 +491,19 @@ export default class NewsPanel extends BaseNewsPanel {
419
491
  await this.getData();
420
492
  }
421
493
 
422
- private _adjustLayout() {
494
+ /**
495
+ * Adjust layout based on the device type
496
+ *
497
+ * @private
498
+ */
499
+ public adjustLayout() {
423
500
  if (this.getDeviceType() === DeviceType.Mobile) {
424
501
  this.oNewsTile.setHeight("11rem");
425
502
  this.generateErrorMessage().setWidth("100%");
503
+ this.oNewsTile.removeStyleClass("sapUiSmallMarginTop");
426
504
  } else {
427
505
  this.oNewsTile.setHeight("17rem");
428
506
  (this.getNewsWrapper()?.getParent() as FlexBox).setWidth("100%");
429
- this.oNewsTile.addStyleClass("sapUiSmallMarginTopBottom");
430
507
  }
431
508
  }
432
509
 
@@ -437,33 +514,38 @@ export default class NewsPanel extends BaseNewsPanel {
437
514
  */
438
515
  private bindNewsTile(oSlideTile: SlideTile, oBindingInfo: IBindingInfo): void {
439
516
  if (oBindingInfo) {
440
- oSlideTile.bindAggregation("tiles", {
441
- path: oBindingInfo.path,
442
- length: oBindingInfo.length,
443
- templateShareable: false,
444
- factory: (sId: string, oContext: Context) => {
445
- const newsInfo = oContext.getObject() as XMLDocument;
446
- let oTile;
447
- if (newsInfo.getElementsByTagName("link").length > 0) {
448
- oTile = new NewsItem("", {
449
- url: newsInfo.getElementsByTagName("link")[0].textContent as string,
450
- title: newsInfo.getElementsByTagName("title")[0].textContent as string,
451
- subTitle: newsInfo.getElementsByTagName("description")[0].textContent as string,
452
- imageUrl: newsInfo.getElementsByTagName("imageUrl")[0].textContent as string,
453
- footer: this.formatDate(newsInfo.getElementsByTagName("pubDate")[0].textContent as string)
454
- });
455
- } else {
456
- oTile = new NewsGroup("", {
457
- title: newsInfo.getElementsByTagName("title")[0].textContent as string,
458
- subTitle: this._i18nBundle.getText("newsFeedDescription") as string,
459
- imageUrl: newsInfo.getElementsByTagName("imageUrl")[0].textContent as string,
460
- footer: newsInfo.getElementsByTagName("footer")[0].textContent as string
461
- });
517
+ if (!oSlideTile.getBinding("tiles")) {
518
+ oSlideTile.bindAggregation("tiles", {
519
+ path: oBindingInfo.path,
520
+ length: oBindingInfo.length,
521
+ templateShareable: false,
522
+ factory: (sId: string, oContext: Context) => {
523
+ const newsInfo = oContext.getObject() as XMLDocument;
524
+ let oTile;
525
+ if (newsInfo.getElementsByTagName("link").length > 0) {
526
+ oTile = new NewsItem(recycleId(`${sId}-news-item`), {
527
+ url: newsInfo.getElementsByTagName("link")[0].textContent as string,
528
+ title: newsInfo.getElementsByTagName("title")[0].textContent as string,
529
+ subTitle: newsInfo.getElementsByTagName("description")[0].textContent as string,
530
+ imageUrl: newsInfo.getElementsByTagName("imageUrl")[0].textContent as string,
531
+ footer: this.formatDate(newsInfo.getElementsByTagName("pubDate")[0].textContent as string)
532
+ });
533
+ } else {
534
+ let sGroupId = (newsInfo.getElementsByTagName("id")?.[0]?.textContent as string) ?? "";
535
+ let newsId = sGroupId ? sId + "-newsgroup-" + sGroupId : sId + "-newsgroup";
536
+ let subTitleNews = newsInfo.getElementsByTagName("subTitle")?.[0]?.textContent ?? "";
537
+ oTile = new NewsGroup(recycleId(newsId), {
538
+ title: newsInfo.getElementsByTagName("title")[0].textContent as string,
539
+ subTitle: subTitleNews || (this._i18nBundle.getText("newsFeedDescription") as string),
540
+ imageUrl: newsInfo.getElementsByTagName("imageUrl")?.[0]?.textContent as string,
541
+ footer: newsInfo.getElementsByTagName("footer")?.[0]?.textContent as string
542
+ });
543
+ }
544
+ this.addAggregation("newsItems", oTile, true);
545
+ return oTile.getTile();
462
546
  }
463
- this.addAggregation("newsItems", oTile, true);
464
- return oTile.getTile();
465
- }
466
- });
547
+ });
548
+ }
467
549
  }
468
550
  }
469
551
 
@@ -498,10 +580,11 @@ export default class NewsPanel extends BaseNewsPanel {
498
580
 
499
581
  /**
500
582
  * Returns the favourite news feed for the custom news
501
- * @returns {any}
583
+ * @returns {IFavNewsFeed}
584
+ * @private
502
585
  */
503
586
  public getFavNewsFeed() {
504
- return this.aFavNewsFeed;
587
+ return this.favNewsFeed;
505
588
  }
506
589
 
507
590
  /**
@@ -526,37 +609,71 @@ export default class NewsPanel extends BaseNewsPanel {
526
609
  .catch(fnLoadPlaceholderImage);
527
610
  }
528
611
 
612
+ /**
613
+ * Checks if the custom file format is CSV based on the custom file name.
614
+ *
615
+ * @param {string} fileName - The custom file name.
616
+ * @returns {boolean} True if the file format is CSV, otherwise false.
617
+ */
618
+ private isCSVFileFormat(fileName: string): boolean {
619
+ return fileName.split(".").pop()?.toLowerCase() === ("csv" as string);
620
+ }
621
+ /**
622
+ * Sets the favorite news feed for the user by retrieving personalization data.
623
+ *
624
+ * This method asynchronously fetches the user's personalization data and updates
625
+ * the `favNewsFeed` property with the favorite news feed information.
626
+ *
627
+ * @returns {Promise<void>} A promise that resolves when the favorite news feed is set.
628
+ * @private
629
+ */
630
+ private async setFavNewsFeed(defaultFeed?: boolean): Promise<void> {
631
+ const personalizer = await this._getUserPersonalization();
632
+ const persData = await personalizer?.read();
633
+ this.favNewsFeed = (defaultFeed ? persData?.defaultNewsFeed : persData?.favNewsFeed) as IFavNewsFeed;
634
+ }
635
+
529
636
  /**
530
637
  * This method retrieves the count and feeds of the custom news feed asynchronously.
531
638
  * If the count is not zero, it loads the custom news feed data and returns the feeds.
532
639
  * @param {string} sFeedId - The ID of the custom news feed to set.
533
640
  * @returns {Promise} A promise that resolves to an array of news feeds.
641
+ * @private
534
642
  */
535
643
  public async setCustomNewsFeed(sFeedId: string): Promise<void> {
536
644
  try {
537
645
  this.oNewsTile.setVisible(true);
538
646
  this.generateErrorMessage().setVisible(false);
539
- const personalizer = await this._getUserPersonalization();
540
- const persData = await personalizer?.read();
541
- this.aFavNewsFeed = persData?.favNewsFeed as { items: string[]; showAllPreparationRequired: boolean };
542
- let [iFeedCount, aFeeds] = await Promise.all([
543
- this.getCustomNewsFeedCount(sFeedId),
544
- this.getCustomNewsFeed(sFeedId, this.aFavNewsFeed ? this.aFavNewsFeed.showAllPreparationRequired : true)
545
- ]);
546
- if (aFeeds.length === 0 || iFeedCount === 0) {
547
- throw new Error();
647
+ await this.setFavNewsFeed(!sFeedId);
648
+ const customFileName = this.getProperty("customFileName") as string;
649
+ const showAllPrepRequired = this.isCSVFileFormat(customFileName)
650
+ ? false
651
+ : (this.favNewsFeed?.showAllPreparationRequired ?? true);
652
+
653
+ if (this.isCSVFileFormat(customFileName)) {
654
+ CUSTOM_NEWS_FEED.EXCLUDE_FIELDS.push("PreparationRequired");
655
+ }
656
+ let aFeeds;
657
+ if (sFeedId) {
658
+ aFeeds = await this.getCustomNewsFeed(sFeedId, showAllPrepRequired);
659
+ } else {
660
+ aFeeds = await this.getCustomNewsFeed("", true);
661
+ }
662
+
663
+ if (aFeeds.length === 0) {
664
+ throw new Error("Error: No news feed available");
548
665
  }
549
666
  //filer selected feeds from all news feed
550
- if (this.aFavNewsFeed?.items?.length) {
667
+ if (this.favNewsFeed?.items?.length) {
551
668
  aFeeds = aFeeds.filter((oNewsFeed) => {
552
- return this.aFavNewsFeed?.items.includes(oNewsFeed.title as string);
669
+ //return this.favNewsFeed?.items.includes(oNewsFeed.title) || this.mandatoryNewsFeed.includes(oNewsFeed.title);
670
+ return this.favNewsFeed?.items.includes(oNewsFeed.title);
553
671
  });
554
- } else if (this.aFavNewsFeed?.items?.length === 0) {
672
+ } else if (this.favNewsFeed?.items?.length === 0) {
555
673
  (this.getParent() as NewsAndPagesContainer)?.panelLoadedFn("News", { loaded: true, count: 0 });
556
- throw new Error("Error: No news feed available");
674
+ throw new Error("Error: No fav news feed available");
557
675
  }
558
- (this.getNewsWrapper()?.getParent() as FlexBox).addStyleClass("sapMNewsFlex");
559
- this.loadCustomNewsFeed(aFeeds);
676
+ await this.loadCustomNewsFeed(aFeeds, sFeedId ? "customFeed" : "defaultFeed");
560
677
  } catch (err) {
561
678
  Log.error(err as string);
562
679
  this.handleFeedError();
@@ -564,16 +681,141 @@ export default class NewsPanel extends BaseNewsPanel {
564
681
  }
565
682
 
566
683
  /**
567
- * Retrieves the count of custom news feed items identified by the provided feed ID.
568
- * @param {string} sFeedId - The ID of the custom news feed.
569
- * @returns {Promise} A Promise that resolves to the count of custom news feed items.
684
+ * Filters the provided list of news groups to include only those that are marked as mandatory.
685
+ *
686
+ * A news group is considered mandatory if:
687
+ * - Its `mandatory_text` property (at the top level) is set to "TRUE" (case-insensitive).
688
+ * - Any of its associated articles (in the `_group_to_article` array) has a `mandatory_text` property set to "TRUE" (case-insensitive).
689
+ *
690
+ * If any article within a group is marked as mandatory, the group's `mandatory_text` property
691
+ * is updated to "TRUE".
692
+ *
693
+ * @param newsGroups - An array of news groups to filter. Each group is expected to implement the `ICustomNewsFeed` interface.
694
+ * @returns An array of news groups that are marked as mandatory.
695
+ * @private
696
+ */
697
+ private filterMandatoryNews(newsGroups: ICustomNewsFeed[]) {
698
+ return newsGroups.filter((group) => {
699
+ // Check top-level mandatory_text
700
+ const isTopLevelMandatory = group.mandatory_text?.toUpperCase() === "TRUE";
701
+
702
+ // Check if any inner _group_to_article has mandatory_text true
703
+ const isAnyArticleMandatory = group._group_to_article?.some(function (article) {
704
+ //make mandatory_test true at group level if any article is mandatory
705
+ if (article.mandatory_text?.toUpperCase() === "TRUE") {
706
+ group.mandatory_text = "TRUE";
707
+ return true;
708
+ }
709
+ });
710
+
711
+ return isTopLevelMandatory || isAnyArticleMandatory;
712
+ });
713
+ }
714
+
715
+ /**
716
+ * Retrieves the default news feed details from the given OData response.
717
+ *
718
+ * @param newsResponse - The OData response containing the news feed data.
719
+ * @param showAllPreparationRequired - A boolean flag indicating whether to filter news items that require preparation.
720
+ * @returns An array of default news feed items.
721
+ * @private
722
+ */
723
+ private getDefaultNewsFeedDetails(newsResponse: ODataResponse) {
724
+ let aNews: ICustomNewsFeed[] = JSON.parse(JSON.stringify(newsResponse.value || [])) as ICustomNewsFeed[];
725
+ const aDefaultNews: ICustomNewsFeed[] = [];
726
+ const oDefaultFeedDict = {} as Record<string, string>;
727
+ this.mandatoryNewsFeed = [];
728
+ if (aNews?.length > 0) {
729
+ this.mandatoryNewsFeed = this.filterMandatoryNews(aNews).map((oFeed) => oFeed.title);
730
+
731
+ for (const oFeed of aNews) {
732
+ const title = oFeed.title;
733
+ let subTitle = "";
734
+ if (!oDefaultFeedDict[title]) {
735
+ subTitle = oFeed.subTitle || oFeed.description || "";
736
+ aDefaultNews.push({
737
+ title: title,
738
+ footer: oFeed.footer_text,
739
+ imageUrl: this.getDefaultFeedImage(oFeed),
740
+ id: oFeed.group_id,
741
+ subTitle: subTitle || ""
742
+ });
743
+ oDefaultFeedDict[title] = title;
744
+ }
745
+ }
746
+ }
747
+ return aDefaultNews;
748
+ }
749
+
750
+ /**
751
+ * Returns the mandatory news feed details
752
+ * If the mandatory news feed is not set, it returns an empty array.
753
+ *
754
+ * @returns {ICustomNewsFeed[]} The mandatory news feed details.
755
+ * @private
570
756
  */
571
- public async getCustomNewsFeedCount(sFeedId: string): Promise<number> {
572
- let sUrl = encodeURI(NEWS_FEED_COUNT_URL + "?$filter=ChangeId" + " eq " + "'" + sFeedId + "'");
573
- if (!this.customNewsFeedCache.has(sUrl)) {
574
- this.customNewsFeedCache.set(sUrl, HttpHelper.GetJSON(sUrl));
757
+ public getMandatoryDefaultNewsFeed() {
758
+ return this.mandatoryNewsFeed || [];
759
+ }
760
+
761
+ /**
762
+ * Retrieves the default news response, either from cache or by fetching it.
763
+ * @returns {Promise<ODataResponse>} A promise that resolves to the default news data
764
+ * @private
765
+ */
766
+ private getDefaultNewsResponse(): Promise<ODataResponse> {
767
+ // Return cached data if available
768
+ if (this._defaultNews) {
769
+ return Promise.resolve(this._defaultNews);
770
+ }
771
+
772
+ if (!this._defaultNewsPromise) {
773
+ this._defaultNewsPromise = this.fetchDefaultNews();
774
+ }
775
+
776
+ return this._defaultNewsPromise;
777
+ }
778
+
779
+ /**
780
+ * Fetches the default news data from the server.
781
+ * @returns {Promise<ODataResponse>} A promise that resolves to the fetched news data
782
+ * @throws {Error} If the network request fails or returns a non-OK status
783
+ * @private
784
+ */
785
+ private async fetchDefaultNews(): Promise<ODataResponse> {
786
+ try {
787
+ const response = await fetch(DEFAULT_NEWS_URL);
788
+
789
+ if (!response.ok) {
790
+ throw new Error(`HTTP error! status: ${response.status}`);
791
+ }
792
+
793
+ this._defaultNews = (await response.json()) as ODataResponse;
794
+ return this._defaultNews;
795
+ } catch (error) {
796
+ this._defaultNewsPromise = null;
797
+ Log.error(error as string);
798
+ throw error;
799
+ }
800
+ }
801
+
802
+ /**
803
+ * Retrieves a custom news feed based on the provided feed ID.
804
+ * If no feed ID is provided, it returns the default news feed.
805
+ *
806
+ * @param {string} sFeedId - The ID of the custom news feed to retrieve. If not provided, the default news feed is returned.
807
+ * @param {boolean} showAllPreparationRequired - A flag indicating whether to show all preparation required.
808
+ * @returns {Promise<ICustomNewsFeed[]>} A promise that resolves to an array of custom news feed items.
809
+ * @private
810
+ */
811
+ public async getCustomNewsFeed(sFeedId: string, showAllPreparationRequired: boolean): Promise<ICustomNewsFeed[]> {
812
+ if (!sFeedId) {
813
+ await this.getDefaultNewsResponse();
814
+ let aDefaultgroups = this.getDefaultNewsFeedDetails(this._defaultNews);
815
+ return aDefaultgroups;
816
+ } else {
817
+ return this.getCustomFeedData(sFeedId, showAllPreparationRequired);
575
818
  }
576
- return this.customNewsFeedCache.get(sUrl) as Promise<number>;
577
819
  }
578
820
 
579
821
  /**
@@ -582,8 +824,9 @@ export default class NewsPanel extends BaseNewsPanel {
582
824
  * @param {string} sFeedId - The ID of the custom news feed.
583
825
  * @param {boolean} showAllPreparationRequired - Indicates whether to show all preparation required.
584
826
  * @returns {Promise} A Promise that resolves to an array of custom news feed items.
827
+ * @private
585
828
  */
586
- public async getCustomNewsFeed(sFeedId: string, showAllPreparationRequired: boolean): Promise<ICustomNewsFeed[]> {
829
+ private async getCustomFeedData(sFeedId: string, showAllPreparationRequired: boolean): Promise<ICustomNewsFeed[]> {
587
830
  try {
588
831
  const newsDetailUrl = this.getNewsFeedDetailsUrl({ changeId: sFeedId, showAllPreparationRequired });
589
832
  if (!this.customNewsFeedCache.has(newsDetailUrl)) {
@@ -605,7 +848,7 @@ export default class NewsPanel extends BaseNewsPanel {
605
848
  }
606
849
  });
607
850
  }
608
- return aFeeds;
851
+ return aFeeds; // group details
609
852
  } catch (err) {
610
853
  Log.error(err as string);
611
854
  throw new Error(err as string);
@@ -620,8 +863,10 @@ export default class NewsPanel extends BaseNewsPanel {
620
863
  */
621
864
  public getNewsFeedDetailsUrl(oNews: INewsItem) {
622
865
  let sUrl = NEWS_FEED_READ_API + "?$filter=ChangeId eq " + "'" + oNews.changeId + "'";
623
- sUrl = oNews.title ? sUrl + " and LineOfBusiness eq " + "'" + encodeURI(oNews.title) + "'" : sUrl;
624
- sUrl = oNews.showAllPreparationRequired ? sUrl + " and PreparationRequired eq true" : sUrl;
866
+ const customFileName = this.getProperty("customFileName") as string;
867
+ if (!this.isCSVFileFormat(customFileName) && oNews.showAllPreparationRequired) {
868
+ sUrl = sUrl + " and PreparationRequired eq true";
869
+ }
625
870
  return sUrl + "&$top=999";
626
871
  }
627
872
 
@@ -632,9 +877,12 @@ export default class NewsPanel extends BaseNewsPanel {
632
877
  * @param {string} sNewsUrl - The URL of the news feed.
633
878
  * @returns {Array} The filtered array of news feed items authorized for the user.
634
879
  */
635
- public async getAuthNewsFeed(sNewsUrl: string) {
880
+ public async getAuthNewsFeed(sNewsUrl: string, newsTitle?: string) {
636
881
  try {
637
- const [aAvailableApps, aNewsFeed] = await Promise.all([this.getAllAvailableApps(), this.getNewsFeedDetails(sNewsUrl)]);
882
+ const [aAvailableApps, aNewsFeed] = await Promise.all([
883
+ this.getAllAvailableApps(),
884
+ this.getNewsFeedDetails(sNewsUrl, newsTitle)
885
+ ]);
638
886
  if (aAvailableApps.length === 0) {
639
887
  return aNewsFeed;
640
888
  }
@@ -713,17 +961,20 @@ export default class NewsPanel extends BaseNewsPanel {
713
961
  * @param {string} sUrl - The URL of the news feed details.
714
962
  * @returns {Array} The array of news feed items with translated and formatted field labels.
715
963
  */
716
- private async getNewsFeedDetails(sUrl: string): Promise<ICustomNewsFeed[]> {
717
- if (!this.customNewsFeedCache.has(sUrl)) {
718
- this.customNewsFeedCache.set(sUrl, HttpHelper.GetJSON(sUrl) as Promise<{ value: ICustomNewsFeed[] }>);
964
+ private async getNewsFeedDetails(sUrl: string, newsTitle?: string): Promise<ICustomNewsFeed[]> {
965
+ if (this.customNewsFeedCache.has(sUrl)) {
966
+ const newsFeedDetails = await this.customNewsFeedCache.get(sUrl);
967
+ return this.filterNewsOnTitle(newsFeedDetails as ICustomNewsFeed[], newsTitle);
719
968
  }
969
+
720
970
  const fnFormattedLabel = (sLabel: string) => sLabel.replace(/([a-z0-9])([A-Z])/g, "$1 $2");
721
971
  const [newsResponse, translationResponse] = await Promise.all([
722
- this.customNewsFeedCache.get(sUrl),
972
+ HttpHelper.GetJSON(sUrl) as Promise<{ value: ICustomNewsFeed[] }>,
723
973
  this.getTranslatedText(this.getCustomFeedKey())
724
974
  ]);
725
- const aNews: ICustomNewsFeed[] = JSON.parse(JSON.stringify((newsResponse as INewsResponse).value || [])) as ICustomNewsFeed[];
975
+ let aNews: ICustomNewsFeed[] = JSON.parse(JSON.stringify((newsResponse as INewsResponse).value || [])) as ICustomNewsFeed[];
726
976
  const aTranslation = JSON.parse(JSON.stringify((translationResponse as INewsResponse).value || [])) as ITranslatedText[];
977
+ aNews = this.filterNewsOnTitle(aNews, newsTitle);
727
978
  return aNews.map((oNews: ICustomNewsFeed) => {
728
979
  const aFields = Object.keys(oNews);
729
980
  const aExpandFields: INewsLink[] = [];
@@ -734,7 +985,7 @@ export default class NewsPanel extends BaseNewsPanel {
734
985
  const oTranslatedFieldName = (oTranslatedField?.TranslatedName as string) || fnFormattedLabel(oField);
735
986
  oNews[oField] = { label: oTranslatedFieldName, value: oNews[oField] as string } as INewsLink;
736
987
  if (!CUSTOM_NEWS_FEED.EXCLUDE_FIELDS.includes(oField)) {
737
- aExpandFields.push(oNews[oField]);
988
+ aExpandFields.push(oNews[oField] as INewsLink);
738
989
  }
739
990
  });
740
991
  oNews.Link = {
@@ -748,6 +999,23 @@ export default class NewsPanel extends BaseNewsPanel {
748
999
  });
749
1000
  }
750
1001
 
1002
+ /**
1003
+ * Filters the news feed data based on the LOB title for the news detail dialog
1004
+ *
1005
+ * @private
1006
+ * @param {ICustomNewsFeed[]} aNews complete news feed data
1007
+ * @param {?string} [newsTitle] title of the line of business to be filtered on
1008
+ * @returns {ICustomNewsFeed[]} filtered news feed for provided LOB title
1009
+ */
1010
+ private filterNewsOnTitle(aNews: ICustomNewsFeed[], newsTitle?: string): ICustomNewsFeed[] {
1011
+ if (newsTitle) {
1012
+ return aNews.filter((newsDetail: ICustomNewsFeed) => {
1013
+ return (newsDetail.LineOfBusiness as INewsLink).value === newsTitle;
1014
+ });
1015
+ }
1016
+ return aNews;
1017
+ }
1018
+
751
1019
  /**
752
1020
  * Retrieves translated text for news feed fields based on the specified feed ID.
753
1021
  * @param {string} sFeedId - The ID of the custom news feed
@@ -772,8 +1040,8 @@ export default class NewsPanel extends BaseNewsPanel {
772
1040
  * Loads custom news feed into the news panel after parsing JSON feed data to XML format.
773
1041
  * @param {Array} feeds - The array of custom news feed items.
774
1042
  */
775
- private loadCustomNewsFeed(feeds: ICustomNewsFeed[]) {
776
- const oXMLResponse = this.parseJsonToXml(JSON.parse(JSON.stringify(feeds)) as JSON[]);
1043
+ private async loadCustomNewsFeed(feeds: ICustomNewsFeed[], feedType: string) {
1044
+ const oXMLResponse = this.parseJsonToXml(JSON.parse(JSON.stringify(feeds)) as JSON[], feedType);
777
1045
  const oParent = this.getParent() as NewsAndPagesContainer;
778
1046
  if (!this.oNewsModel) {
779
1047
  this.oNewsModel = new XMLModel(oXMLResponse);
@@ -783,9 +1051,11 @@ export default class NewsPanel extends BaseNewsPanel {
783
1051
  }
784
1052
  this.oNewsTile.setModel(this.oNewsModel);
785
1053
  } else {
1054
+ this.oNewsTile.unbindAggregation("tiles", false); // Unbind the bound aggregation
1055
+ this.oNewsTile.destroyAggregation("tiles"); // Removes old tiles
786
1056
  this.oNewsModel.setData(oXMLResponse);
787
1057
  }
788
- void this.loadNewsFeed(oXMLResponse, feeds.length);
1058
+ await this.loadNewsFeed(oXMLResponse, feeds.length);
789
1059
  }
790
1060
 
791
1061
  /**
@@ -793,7 +1063,7 @@ export default class NewsPanel extends BaseNewsPanel {
793
1063
  * @param {JSON[]} json - The JSON data to be parsed into XML.
794
1064
  * @returns {XMLDocument} The XML document representing the parsed JSON data.
795
1065
  */
796
- private parseJsonToXml(json: JSON[]): XMLDocument {
1066
+ private parseJsonToXml(json: JSON[], feedType: string): XMLDocument {
797
1067
  const _transformJsonForXml = (aData: JSON[]) => aData.map((data: JSON) => ({ item: data }));
798
1068
  const _jsonToXml = (json: JSON) => {
799
1069
  let xml = "";
@@ -812,7 +1082,7 @@ export default class NewsPanel extends BaseNewsPanel {
812
1082
  };
813
1083
  const transformedJson: JSON = JSON.parse(JSON.stringify(_transformJsonForXml(json))) as JSON;
814
1084
  let xml = "<?xml version='1.0' encoding='UTF-8'?>";
815
- const rootToken = "customFeed";
1085
+ const rootToken = feedType;
816
1086
  xml += `<${rootToken}>`;
817
1087
  xml += _jsonToXml(transformedJson);
818
1088
  xml += `</${rootToken}>`;
@@ -825,8 +1095,9 @@ export default class NewsPanel extends BaseNewsPanel {
825
1095
  * Randomly selects an image from the available images for the feed item.
826
1096
  * @param {string} sFileName - The file name of the custom news feed item.
827
1097
  * @returns {string} The URL of the image for the feed item.
1098
+ * @private
828
1099
  */
829
- public getCustomFeedImage(sFileName: string) {
1100
+ private getCustomFeedImage(sFileName: string) {
830
1101
  const sFileBasePath = sap.ui.require.toUrl(CUSTOM_NEWS_FEED.IMAGE_URL);
831
1102
  let sFilePath = sFileBasePath + CUSTOM_IMAGES.default[0];
832
1103
  const files = CUSTOM_IMAGES[sFileName] || [];
@@ -840,6 +1111,105 @@ export default class NewsPanel extends BaseNewsPanel {
840
1111
  return sFilePath;
841
1112
  }
842
1113
 
1114
+ /**
1115
+ * Retrieves the default feed image for a given news feed.
1116
+ *
1117
+ * @param {ICustomNewsFeed} oFeed - The custom news feed object.
1118
+ * @returns {string} The base64 encoded image string with the appropriate MIME type, or an empty string if no valid image is found.
1119
+ * @private
1120
+ */
1121
+ private getDefaultFeedImage(oFeed: ICustomNewsFeed): string {
1122
+ const imgId = oFeed?.bg_image_id;
1123
+ const groupImg = oFeed?._group_to_image;
1124
+
1125
+ if (!groupImg || groupImg.image_id !== imgId) {
1126
+ return "";
1127
+ }
1128
+
1129
+ let mimeType = groupImg.mime_type;
1130
+ const groupBgImg = groupImg.bg_image;
1131
+
1132
+ if (!groupBgImg) {
1133
+ return "";
1134
+ }
1135
+ if (mimeType === "application/octet-stream") {
1136
+ mimeType = "image/jpeg";
1137
+ }
1138
+ if (!this.isValidBase64(groupBgImg)) {
1139
+ const base64Data = this.base64UrlToBase64(groupBgImg);
1140
+ return `data:${mimeType};base64,${base64Data}`;
1141
+ }
1142
+ return `data:${mimeType};base64,${groupBgImg}`;
1143
+ }
1144
+
1145
+ /**
1146
+ * Converts a base64 URL string to a standard base64 string.
1147
+ *
1148
+ * @param {string} base64Url - The base64 URL string to convert.
1149
+ * @returns {string} The converted base64 string.
1150
+ * @private
1151
+ */
1152
+ private base64UrlToBase64(base64Url: string) {
1153
+ let base64 = base64Url?.replace(/_/g, "/").replace(/-/g, "+");
1154
+
1155
+ // Add padding if missing (Base64 should be a multiple of 4)
1156
+ while (base64.length % 4 !== 0) {
1157
+ base64 += "=";
1158
+ }
1159
+ return base64;
1160
+ }
1161
+
1162
+ /**
1163
+ * Checks if a string is a valid base64 encoded string.
1164
+ * @param input The string to validate
1165
+ * @returns boolean indicating if the string is valid base64
1166
+ * @private
1167
+ */
1168
+ private isValidBase64(input: string): boolean {
1169
+ // Check if the string exists and isn't empty
1170
+ if (!input || input.length === 0) {
1171
+ return false;
1172
+ }
1173
+
1174
+ // Canonical base64 strings use these characters
1175
+ // A-Z, a-z, 0-9, +, /, and = for padding
1176
+ const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
1177
+
1178
+ // Check if the string matches the base64 character set
1179
+ if (!base64Regex.test(input)) {
1180
+ return false;
1181
+ }
1182
+
1183
+ // Check if the length is valid
1184
+ // Base64 strings have a length that is a multiple of 4
1185
+ if (input.length % 4 !== 0) {
1186
+ return false;
1187
+ }
1188
+
1189
+ // Check padding rules
1190
+ if (input.includes("=")) {
1191
+ // If there is padding, it must be at the end
1192
+ const paddingIndex = input.indexOf("=");
1193
+ const lastPaddingIndex = input.lastIndexOf("=");
1194
+ // Padding should only occur at the end
1195
+ if (paddingIndex !== input.length - (input.length - paddingIndex)) {
1196
+ return false;
1197
+ }
1198
+
1199
+ // Can only have 1 or 2 padding characters
1200
+ if (input.length - paddingIndex > 2) {
1201
+ return false;
1202
+ }
1203
+
1204
+ // Make sure all padding is at the end
1205
+ if (paddingIndex !== lastPaddingIndex && lastPaddingIndex !== paddingIndex + 1) {
1206
+ return false;
1207
+ }
1208
+ }
1209
+
1210
+ return true;
1211
+ }
1212
+
843
1213
  private _getUserPersonalization() {
844
1214
  const persContainerId = PersonalisationUtils.getPersContainerId(this);
845
1215
  const ownerComponent = PersonalisationUtils.getOwnerComponent(this) as Component;