@stack-spot/portal-components 0.0.18 → 1.0.0-dev.1768482754546

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 (533) hide show
  1. package/CHANGELOG.md +670 -0
  2. package/dist/components/AnimatedHeight.d.ts +58 -0
  3. package/dist/components/AnimatedHeight.d.ts.map +1 -0
  4. package/dist/components/AnimatedHeight.js +105 -0
  5. package/dist/components/AnimatedHeight.js.map +1 -0
  6. package/dist/components/AsyncContent.d.ts +46 -0
  7. package/dist/components/AsyncContent.d.ts.map +1 -0
  8. package/dist/components/AsyncContent.js +34 -0
  9. package/dist/components/AsyncContent.js.map +1 -0
  10. package/dist/components/BannerWarning.d.ts +11 -2
  11. package/dist/components/BannerWarning.d.ts.map +1 -1
  12. package/dist/components/BannerWarning.js +45 -3
  13. package/dist/components/BannerWarning.js.map +1 -1
  14. package/dist/components/Breadcrumb/index.d.ts +7 -9
  15. package/dist/components/Breadcrumb/index.d.ts.map +1 -1
  16. package/dist/components/Breadcrumb/index.js +7 -6
  17. package/dist/components/Breadcrumb/index.js.map +1 -1
  18. package/dist/components/Breadcrumb/styled.d.ts +1 -2
  19. package/dist/components/Breadcrumb/styled.d.ts.map +1 -1
  20. package/dist/components/Breadcrumb/styled.js +1 -0
  21. package/dist/components/Breadcrumb/styled.js.map +1 -1
  22. package/dist/components/ButtonLoading.d.ts +11 -0
  23. package/dist/components/ButtonLoading.d.ts.map +1 -0
  24. package/dist/components/ButtonLoading.js +5 -0
  25. package/dist/components/ButtonLoading.js.map +1 -0
  26. package/dist/components/ChatBot.d.ts +5 -0
  27. package/dist/components/ChatBot.d.ts.map +1 -1
  28. package/dist/components/ChatBot.js +11 -6
  29. package/dist/components/ChatBot.js.map +1 -1
  30. package/dist/components/ContentValidateFilter.d.ts +6 -0
  31. package/dist/components/ContentValidateFilter.d.ts.map +1 -0
  32. package/dist/components/ContentValidateFilter.js +8 -0
  33. package/dist/components/ContentValidateFilter.js.map +1 -0
  34. package/dist/components/FadingOverflow.d.ts +37 -0
  35. package/dist/components/FadingOverflow.d.ts.map +1 -0
  36. package/dist/components/FadingOverflow.js +228 -0
  37. package/dist/components/FadingOverflow.js.map +1 -0
  38. package/dist/components/FileTreeView/More.d.ts +23 -0
  39. package/dist/components/FileTreeView/More.d.ts.map +1 -0
  40. package/dist/components/FileTreeView/More.js +55 -0
  41. package/dist/components/FileTreeView/More.js.map +1 -0
  42. package/dist/components/FileTreeView/index.d.ts +32 -0
  43. package/dist/components/FileTreeView/index.d.ts.map +1 -0
  44. package/dist/components/FileTreeView/index.js +91 -0
  45. package/dist/components/FileTreeView/index.js.map +1 -0
  46. package/dist/components/InfiniteScroll.d.ts +11 -0
  47. package/dist/components/InfiniteScroll.d.ts.map +1 -0
  48. package/dist/components/InfiniteScroll.js +14 -0
  49. package/dist/components/InfiniteScroll.js.map +1 -0
  50. package/dist/components/InfoMaintenanceBanner.d.ts +8 -0
  51. package/dist/components/InfoMaintenanceBanner.d.ts.map +1 -0
  52. package/dist/components/InfoMaintenanceBanner.js +19 -0
  53. package/dist/components/InfoMaintenanceBanner.js.map +1 -0
  54. package/dist/components/LazyMarkdown/BlockquoteMd.d.ts +11 -0
  55. package/dist/components/LazyMarkdown/BlockquoteMd.d.ts.map +1 -0
  56. package/dist/components/LazyMarkdown/BlockquoteMd.js +77 -0
  57. package/dist/components/LazyMarkdown/BlockquoteMd.js.map +1 -0
  58. package/dist/components/LazyMarkdown/CodeViewer.d.ts +24 -0
  59. package/dist/components/LazyMarkdown/CodeViewer.d.ts.map +1 -0
  60. package/dist/components/LazyMarkdown/CodeViewer.js +122 -0
  61. package/dist/components/LazyMarkdown/CodeViewer.js.map +1 -0
  62. package/dist/components/LazyMarkdown/Markdown.d.ts +19 -0
  63. package/dist/components/LazyMarkdown/Markdown.d.ts.map +1 -0
  64. package/dist/components/LazyMarkdown/Markdown.js +96 -0
  65. package/dist/components/LazyMarkdown/Markdown.js.map +1 -0
  66. package/dist/components/LazyMarkdown/MarkdownButton.d.ts +19 -0
  67. package/dist/components/LazyMarkdown/MarkdownButton.d.ts.map +1 -0
  68. package/dist/components/LazyMarkdown/MarkdownButton.js +9 -0
  69. package/dist/components/LazyMarkdown/MarkdownButton.js.map +1 -0
  70. package/dist/components/LazyMarkdown/Video.d.ts +11 -0
  71. package/dist/components/LazyMarkdown/Video.d.ts.map +1 -0
  72. package/dist/components/LazyMarkdown/Video.js +10 -0
  73. package/dist/components/LazyMarkdown/Video.js.map +1 -0
  74. package/dist/components/LazyMarkdown/index.d.ts +10 -0
  75. package/dist/components/LazyMarkdown/index.d.ts.map +1 -0
  76. package/dist/components/LazyMarkdown/index.js +8 -0
  77. package/dist/components/LazyMarkdown/index.js.map +1 -0
  78. package/dist/components/Placeholder.d.ts +28 -0
  79. package/dist/components/Placeholder.d.ts.map +1 -0
  80. package/dist/components/Placeholder.js +32 -0
  81. package/dist/components/Placeholder.js.map +1 -0
  82. package/dist/components/ScrollView.d.ts +31 -0
  83. package/dist/components/ScrollView.d.ts.map +1 -0
  84. package/dist/components/ScrollView.js +30 -0
  85. package/dist/components/ScrollView.js.map +1 -0
  86. package/dist/components/Select/BadgeItem.d.ts +4 -0
  87. package/dist/components/Select/BadgeItem.d.ts.map +1 -0
  88. package/dist/components/Select/BadgeItem.js +28 -0
  89. package/dist/components/Select/BadgeItem.js.map +1 -0
  90. package/dist/components/Select/ClearInput.d.ts +3 -0
  91. package/dist/components/Select/ClearInput.d.ts.map +1 -0
  92. package/dist/components/Select/ClearInput.js +18 -0
  93. package/dist/components/Select/ClearInput.js.map +1 -0
  94. package/dist/components/Select/CloseItem.d.ts +3 -0
  95. package/dist/components/Select/CloseItem.d.ts.map +1 -0
  96. package/dist/components/Select/CloseItem.js +26 -0
  97. package/dist/components/Select/CloseItem.js.map +1 -0
  98. package/dist/components/Select/CreatableSelect.d.ts +16 -0
  99. package/dist/components/Select/CreatableSelect.d.ts.map +1 -0
  100. package/dist/components/Select/CreatableSelect.js +114 -0
  101. package/dist/components/Select/CreatableSelect.js.map +1 -0
  102. package/dist/components/Select/CustomMenu.d.ts +8 -0
  103. package/dist/components/Select/CustomMenu.d.ts.map +1 -0
  104. package/dist/components/Select/CustomMenu.js +4 -0
  105. package/dist/components/Select/CustomMenu.js.map +1 -0
  106. package/dist/components/Select/LabelItem.d.ts +3 -0
  107. package/dist/components/Select/LabelItem.d.ts.map +1 -0
  108. package/dist/components/Select/LabelItem.js +4 -0
  109. package/dist/components/Select/LabelItem.js.map +1 -0
  110. package/dist/components/Select/MultiValue.d.ts +3 -0
  111. package/dist/components/Select/MultiValue.d.ts.map +1 -0
  112. package/dist/components/Select/MultiValue.js +27 -0
  113. package/dist/components/Select/MultiValue.js.map +1 -0
  114. package/dist/components/Select/SelectInfiniteScroll.d.ts +14 -0
  115. package/dist/components/Select/SelectInfiniteScroll.d.ts.map +1 -0
  116. package/dist/components/Select/SelectInfiniteScroll.js +31 -0
  117. package/dist/components/Select/SelectInfiniteScroll.js.map +1 -0
  118. package/dist/components/Select/SelectSearch.d.ts +11 -0
  119. package/dist/components/Select/SelectSearch.d.ts.map +1 -0
  120. package/dist/components/Select/SelectSearch.js +156 -0
  121. package/dist/components/Select/SelectSearch.js.map +1 -0
  122. package/dist/components/Select/index.d.ts +6 -0
  123. package/dist/components/Select/index.d.ts.map +1 -0
  124. package/dist/components/Select/index.js +6 -0
  125. package/dist/components/Select/index.js.map +1 -0
  126. package/dist/components/Select/types.d.ts +7 -0
  127. package/dist/components/Select/types.d.ts.map +1 -0
  128. package/dist/components/Select/types.js +2 -0
  129. package/dist/components/Select/types.js.map +1 -0
  130. package/dist/components/SelectionList.d.ts +151 -0
  131. package/dist/components/SelectionList.d.ts.map +1 -0
  132. package/dist/components/SelectionList.js +180 -0
  133. package/dist/components/SelectionList.js.map +1 -0
  134. package/dist/components/StatusCircle.d.ts +24 -0
  135. package/dist/components/StatusCircle.d.ts.map +1 -0
  136. package/dist/components/StatusCircle.js +44 -0
  137. package/dist/components/StatusCircle.js.map +1 -0
  138. package/dist/components/Stepper/Navigation.d.ts +35 -0
  139. package/dist/components/Stepper/Navigation.d.ts.map +1 -0
  140. package/dist/components/Stepper/Navigation.js +41 -0
  141. package/dist/components/Stepper/Navigation.js.map +1 -0
  142. package/dist/components/Stepper/Step.d.ts +18 -0
  143. package/dist/components/Stepper/Step.d.ts.map +1 -0
  144. package/dist/components/Stepper/Step.js +13 -0
  145. package/dist/components/Stepper/Step.js.map +1 -0
  146. package/dist/components/Stepper/Stepper.d.ts +45 -0
  147. package/dist/components/Stepper/Stepper.d.ts.map +1 -0
  148. package/dist/components/Stepper/Stepper.js +57 -0
  149. package/dist/components/Stepper/Stepper.js.map +1 -0
  150. package/dist/components/Stepper/headers.d.ts +19 -0
  151. package/dist/components/Stepper/headers.d.ts.map +1 -0
  152. package/dist/components/Stepper/headers.js +40 -0
  153. package/dist/components/Stepper/headers.js.map +1 -0
  154. package/dist/components/Stepper/index.d.ts +4 -0
  155. package/dist/components/Stepper/index.d.ts.map +1 -0
  156. package/dist/components/Stepper/index.js +4 -0
  157. package/dist/components/Stepper/index.js.map +1 -0
  158. package/dist/components/Table/HeaderItem.d.ts +18 -0
  159. package/dist/components/Table/HeaderItem.d.ts.map +1 -0
  160. package/dist/components/Table/HeaderItem.js +14 -0
  161. package/dist/components/Table/HeaderItem.js.map +1 -0
  162. package/dist/components/Table/SettingsVerticalMenu.d.ts +14 -0
  163. package/dist/components/Table/SettingsVerticalMenu.d.ts.map +1 -0
  164. package/dist/components/Table/SettingsVerticalMenu.js +14 -0
  165. package/dist/components/Table/SettingsVerticalMenu.js.map +1 -0
  166. package/dist/components/Table/StyledLinkTable.d.ts +5 -0
  167. package/dist/components/Table/StyledLinkTable.d.ts.map +1 -0
  168. package/dist/components/Table/StyledLinkTable.js +13 -0
  169. package/dist/components/Table/StyledLinkTable.js.map +1 -0
  170. package/dist/components/Table/TableData.d.ts +37 -0
  171. package/dist/components/Table/TableData.d.ts.map +1 -0
  172. package/dist/components/Table/TableData.js +84 -0
  173. package/dist/components/Table/TableData.js.map +1 -0
  174. package/dist/components/Table/index.d.ts +3 -0
  175. package/dist/components/Table/index.d.ts.map +1 -0
  176. package/dist/components/Table/index.js +3 -0
  177. package/dist/components/Table/index.js.map +1 -0
  178. package/dist/components/TimelineSection.d.ts +24 -0
  179. package/dist/components/TimelineSection.d.ts.map +1 -0
  180. package/dist/components/TimelineSection.js +37 -0
  181. package/dist/components/TimelineSection.js.map +1 -0
  182. package/dist/components/error/ErrorFeedback.d.ts +58 -0
  183. package/dist/components/error/ErrorFeedback.d.ts.map +1 -0
  184. package/dist/components/error/ErrorFeedback.js +110 -0
  185. package/dist/components/error/ErrorFeedback.js.map +1 -0
  186. package/dist/components/error/NotFound.d.ts +4 -0
  187. package/dist/components/error/NotFound.d.ts.map +1 -0
  188. package/dist/components/error/NotFound.js +19 -0
  189. package/dist/components/error/NotFound.js.map +1 -0
  190. package/dist/components/error/UnderMaintenance.d.ts +4 -0
  191. package/dist/components/error/UnderMaintenance.d.ts.map +1 -0
  192. package/dist/components/error/UnderMaintenance.js +25 -0
  193. package/dist/components/error/UnderMaintenance.js.map +1 -0
  194. package/dist/components/error/index.d.ts +4 -0
  195. package/dist/components/error/index.d.ts.map +1 -0
  196. package/dist/components/error/index.js +4 -0
  197. package/dist/components/error/index.js.map +1 -0
  198. package/dist/components/form/Form/Form.d.ts +15 -0
  199. package/dist/components/form/Form/Form.d.ts.map +1 -0
  200. package/dist/components/form/Form/Form.js +48 -0
  201. package/dist/components/form/Form/Form.js.map +1 -0
  202. package/dist/components/form/Form/FormGroup.d.ts +37 -0
  203. package/dist/components/form/Form/FormGroup.d.ts.map +1 -0
  204. package/dist/components/form/Form/FormGroup.js +72 -0
  205. package/dist/components/form/Form/FormGroup.js.map +1 -0
  206. package/dist/components/form/Form/index.d.ts +3 -0
  207. package/dist/components/form/Form/index.d.ts.map +1 -0
  208. package/dist/components/form/Form/index.js +3 -0
  209. package/dist/components/form/Form/index.js.map +1 -0
  210. package/dist/components/form/SearchInput.d.ts +9 -0
  211. package/dist/components/form/SearchInput.d.ts.map +1 -0
  212. package/dist/components/form/SearchInput.js +28 -0
  213. package/dist/components/form/SearchInput.js.map +1 -0
  214. package/dist/components/form/Select/CustomSelect.d.ts +81 -0
  215. package/dist/components/form/Select/CustomSelect.d.ts.map +1 -0
  216. package/dist/components/form/Select/CustomSelect.js +178 -0
  217. package/dist/components/form/Select/CustomSelect.js.map +1 -0
  218. package/dist/components/form/Select/DetailedSelect.d.ts +65 -0
  219. package/dist/components/form/Select/DetailedSelect.d.ts.map +1 -0
  220. package/dist/components/form/Select/DetailedSelect.js +80 -0
  221. package/dist/components/form/Select/DetailedSelect.js.map +1 -0
  222. package/dist/components/form/Select/Select.d.ts +47 -0
  223. package/dist/components/form/Select/Select.d.ts.map +1 -0
  224. package/dist/components/form/Select/Select.js +62 -0
  225. package/dist/components/form/Select/Select.js.map +1 -0
  226. package/dist/components/form/Select/index.d.ts +5 -0
  227. package/dist/components/form/Select/index.d.ts.map +1 -0
  228. package/dist/components/form/Select/index.js +5 -0
  229. package/dist/components/form/Select/index.js.map +1 -0
  230. package/dist/components/form/Select/styled.d.ts +5 -0
  231. package/dist/components/form/Select/styled.d.ts.map +1 -0
  232. package/dist/components/form/Select/styled.js +165 -0
  233. package/dist/components/form/Select/styled.js.map +1 -0
  234. package/dist/components/form/Select/types.d.ts +103 -0
  235. package/dist/components/form/Select/types.d.ts.map +1 -0
  236. package/dist/components/form/Select/types.js +2 -0
  237. package/dist/components/form/Select/types.js.map +1 -0
  238. package/dist/components/form/Select/utils.d.ts +3 -0
  239. package/dist/components/form/Select/utils.d.ts.map +1 -0
  240. package/dist/components/form/Select/utils.js +20 -0
  241. package/dist/components/form/Select/utils.js.map +1 -0
  242. package/dist/components/notification/NotificationComponent.d.ts +31 -0
  243. package/dist/components/notification/NotificationComponent.d.ts.map +1 -0
  244. package/dist/components/notification/NotificationComponent.js +176 -0
  245. package/dist/components/notification/NotificationComponent.js.map +1 -0
  246. package/dist/components/notification/NotificationItem.d.ts +51 -0
  247. package/dist/components/notification/NotificationItem.d.ts.map +1 -0
  248. package/dist/components/notification/NotificationItem.js +165 -0
  249. package/dist/components/notification/NotificationItem.js.map +1 -0
  250. package/dist/components/notification/NotificationList.d.ts +47 -0
  251. package/dist/components/notification/NotificationList.d.ts.map +1 -0
  252. package/dist/components/notification/NotificationList.js +82 -0
  253. package/dist/components/notification/NotificationList.js.map +1 -0
  254. package/dist/components/notification/NotificationPlaceholder.d.ts +13 -0
  255. package/dist/components/notification/NotificationPlaceholder.d.ts.map +1 -0
  256. package/dist/components/notification/NotificationPlaceholder.js +34 -0
  257. package/dist/components/notification/NotificationPlaceholder.js.map +1 -0
  258. package/dist/components/notification/types.d.ts +60 -0
  259. package/dist/components/notification/types.d.ts.map +1 -0
  260. package/dist/components/notification/types.js +7 -0
  261. package/dist/components/notification/types.js.map +1 -0
  262. package/dist/containers/NotificationsPage.d.ts +2 -0
  263. package/dist/containers/NotificationsPage.d.ts.map +1 -0
  264. package/dist/containers/NotificationsPage.js +71 -0
  265. package/dist/containers/NotificationsPage.js.map +1 -0
  266. package/dist/context/anchor.d.ts +27 -0
  267. package/dist/context/anchor.d.ts.map +1 -0
  268. package/dist/context/anchor.js +23 -0
  269. package/dist/context/anchor.js.map +1 -0
  270. package/dist/context/loading.d.ts +27 -0
  271. package/dist/context/loading.d.ts.map +1 -0
  272. package/dist/context/loading.js +24 -0
  273. package/dist/context/loading.js.map +1 -0
  274. package/dist/context/notification/LazyNotificationList.d.ts +28 -0
  275. package/dist/context/notification/LazyNotificationList.d.ts.map +1 -0
  276. package/dist/context/notification/LazyNotificationList.js +136 -0
  277. package/dist/context/notification/LazyNotificationList.js.map +1 -0
  278. package/dist/context/notification/NotificationController.d.ts +25 -0
  279. package/dist/context/notification/NotificationController.d.ts.map +1 -0
  280. package/dist/context/notification/NotificationController.js +153 -0
  281. package/dist/context/notification/NotificationController.js.map +1 -0
  282. package/dist/context/notification/context.d.ts +8 -0
  283. package/dist/context/notification/context.d.ts.map +1 -0
  284. package/dist/context/notification/context.js +12 -0
  285. package/dist/context/notification/context.js.map +1 -0
  286. package/dist/context/notification/hooks.d.ts +18 -0
  287. package/dist/context/notification/hooks.d.ts.map +1 -0
  288. package/dist/context/notification/hooks.js +92 -0
  289. package/dist/context/notification/hooks.js.map +1 -0
  290. package/dist/context/notification/types.d.ts +65 -0
  291. package/dist/context/notification/types.d.ts.map +1 -0
  292. package/dist/context/notification/types.js +2 -0
  293. package/dist/context/notification/types.js.map +1 -0
  294. package/dist/hooks/date.d.ts +18 -0
  295. package/dist/hooks/date.d.ts.map +1 -0
  296. package/dist/hooks/date.js +68 -0
  297. package/dist/hooks/date.js.map +1 -0
  298. package/dist/hooks/keyboard.d.ts +64 -0
  299. package/dist/hooks/keyboard.d.ts.map +1 -0
  300. package/dist/hooks/keyboard.js +84 -0
  301. package/dist/hooks/keyboard.js.map +1 -0
  302. package/dist/hooks/manual-render.d.ts +8 -0
  303. package/dist/hooks/manual-render.d.ts.map +1 -0
  304. package/dist/hooks/manual-render.js +10 -0
  305. package/dist/hooks/manual-render.js.map +1 -0
  306. package/dist/hooks/service-now.d.ts +32 -1
  307. package/dist/hooks/service-now.d.ts.map +1 -1
  308. package/dist/hooks/service-now.js +58 -18
  309. package/dist/hooks/service-now.js.map +1 -1
  310. package/dist/hooks/text.d.ts +9 -0
  311. package/dist/hooks/text.d.ts.map +1 -0
  312. package/dist/hooks/text.js +24 -0
  313. package/dist/hooks/text.js.map +1 -0
  314. package/dist/hooks/title.d.ts +13 -0
  315. package/dist/hooks/title.d.ts.map +1 -1
  316. package/dist/hooks/title.js +13 -0
  317. package/dist/hooks/title.js.map +1 -1
  318. package/dist/hooks/use-effect-once.d.ts.map +1 -1
  319. package/dist/hooks/use-effect-once.js.map +1 -1
  320. package/dist/index.d.ts +14 -4
  321. package/dist/index.d.ts.map +1 -1
  322. package/dist/index.js +14 -4
  323. package/dist/index.js.map +1 -1
  324. package/dist/notifications.d.ts +11 -0
  325. package/dist/notifications.d.ts.map +1 -0
  326. package/dist/notifications.js +10 -0
  327. package/dist/notifications.js.map +1 -0
  328. package/dist/svg/AI.d.ts +8 -0
  329. package/dist/svg/AI.d.ts.map +1 -0
  330. package/dist/svg/AI.js +15 -0
  331. package/dist/svg/AI.js.map +1 -0
  332. package/dist/svg/CS.d.ts +8 -0
  333. package/dist/svg/CS.d.ts.map +1 -0
  334. package/dist/svg/CS.js +15 -0
  335. package/dist/svg/CS.js.map +1 -0
  336. package/dist/svg/EDP.d.ts +8 -0
  337. package/dist/svg/EDP.d.ts.map +1 -0
  338. package/dist/svg/EDP.js +15 -0
  339. package/dist/svg/EDP.js.map +1 -0
  340. package/dist/svg/Forbidden.d.ts +5 -0
  341. package/dist/svg/Forbidden.d.ts.map +1 -0
  342. package/dist/svg/Forbidden.js +4 -0
  343. package/dist/svg/Forbidden.js.map +1 -0
  344. package/dist/svg/GenericPlaceholder.d.ts +7 -0
  345. package/dist/svg/GenericPlaceholder.d.ts.map +1 -0
  346. package/dist/svg/GenericPlaceholder.js +4 -0
  347. package/dist/svg/GenericPlaceholder.js.map +1 -0
  348. package/dist/svg/HUB.d.ts +8 -0
  349. package/dist/svg/HUB.d.ts.map +1 -0
  350. package/dist/svg/HUB.js +15 -0
  351. package/dist/svg/HUB.js.map +1 -0
  352. package/dist/svg/Logo.d.ts +5 -0
  353. package/dist/svg/Logo.d.ts.map +1 -0
  354. package/dist/svg/Logo.js +8 -0
  355. package/dist/svg/Logo.js.map +1 -0
  356. package/dist/svg/MiniLogo.d.ts +8 -0
  357. package/dist/svg/MiniLogo.d.ts.map +1 -0
  358. package/dist/svg/MiniLogo.js +6 -0
  359. package/dist/svg/MiniLogo.js.map +1 -0
  360. package/dist/svg/NotFound.d.ts +5 -0
  361. package/dist/svg/NotFound.d.ts.map +1 -0
  362. package/dist/svg/NotFound.js +4 -0
  363. package/dist/svg/NotFound.js.map +1 -0
  364. package/dist/svg/ServerError.d.ts +5 -0
  365. package/dist/svg/ServerError.d.ts.map +1 -0
  366. package/dist/svg/ServerError.js +4 -0
  367. package/dist/svg/ServerError.js.map +1 -0
  368. package/dist/svg/Unauthenticated.d.ts +5 -0
  369. package/dist/svg/Unauthenticated.d.ts.map +1 -0
  370. package/dist/svg/Unauthenticated.js +4 -0
  371. package/dist/svg/Unauthenticated.js.map +1 -0
  372. package/dist/svg/index.d.ts +12 -0
  373. package/dist/svg/index.d.ts.map +1 -0
  374. package/dist/svg/index.js +12 -0
  375. package/dist/svg/index.js.map +1 -0
  376. package/dist/utils/accessibility.d.ts +75 -0
  377. package/dist/utils/accessibility.d.ts.map +1 -0
  378. package/dist/utils/accessibility.js +123 -0
  379. package/dist/utils/accessibility.js.map +1 -0
  380. package/dist/utils/cookie.d.ts +34 -0
  381. package/dist/utils/cookie.d.ts.map +1 -0
  382. package/dist/utils/cookie.js +69 -0
  383. package/dist/utils/cookie.js.map +1 -0
  384. package/dist/utils/promise.d.ts +2 -0
  385. package/dist/utils/promise.d.ts.map +1 -0
  386. package/dist/utils/promise.js +6 -0
  387. package/dist/utils/promise.js.map +1 -0
  388. package/dist/utils/read-file.d.ts +2 -0
  389. package/dist/utils/read-file.d.ts.map +1 -0
  390. package/dist/utils/read-file.js +14 -0
  391. package/dist/utils/read-file.js.map +1 -0
  392. package/package.dev.json +3 -0
  393. package/package.json +53 -14
  394. package/package.stg.json +3 -0
  395. package/readme.md +55 -13
  396. package/src/components/AnimatedHeight.tsx +174 -0
  397. package/src/components/AsyncContent.tsx +78 -0
  398. package/src/components/BannerWarning.tsx +89 -19
  399. package/src/components/Breadcrumb/index.tsx +15 -13
  400. package/src/components/Breadcrumb/styled.ts +2 -1
  401. package/src/components/ButtonLoading.tsx +29 -0
  402. package/src/components/ChatBot.tsx +12 -7
  403. package/src/components/ContentValidateFilter.tsx +15 -0
  404. package/src/components/FadingOverflow.tsx +265 -0
  405. package/src/components/FileTreeView/More.tsx +114 -0
  406. package/src/components/FileTreeView/index.tsx +186 -0
  407. package/src/components/InfiniteScroll.tsx +24 -0
  408. package/src/components/InfoMaintenanceBanner.tsx +25 -0
  409. package/src/components/LazyMarkdown/BlockquoteMd.tsx +107 -0
  410. package/src/components/LazyMarkdown/CodeViewer.tsx +161 -0
  411. package/src/components/LazyMarkdown/Markdown.tsx +122 -0
  412. package/src/components/LazyMarkdown/MarkdownButton.tsx +24 -0
  413. package/src/components/LazyMarkdown/Video.tsx +13 -0
  414. package/src/components/LazyMarkdown/index.tsx +21 -0
  415. package/src/components/Placeholder.tsx +124 -0
  416. package/src/components/ScrollView.tsx +57 -0
  417. package/src/components/Select/BadgeItem.tsx +58 -0
  418. package/src/components/Select/ClearInput.tsx +24 -0
  419. package/src/components/Select/CloseItem.tsx +38 -0
  420. package/src/components/Select/CreatableSelect.tsx +155 -0
  421. package/src/components/Select/CustomMenu.tsx +16 -0
  422. package/src/components/Select/LabelItem.tsx +8 -0
  423. package/src/components/Select/MultiValue.tsx +49 -0
  424. package/src/components/Select/SelectInfiniteScroll.tsx +82 -0
  425. package/src/components/Select/SelectSearch.tsx +195 -0
  426. package/src/components/Select/index.tsx +7 -0
  427. package/src/components/Select/types.ts +8 -0
  428. package/src/components/SelectionList.tsx +427 -0
  429. package/src/components/StatusCircle.tsx +67 -0
  430. package/src/components/Stepper/Navigation.tsx +97 -0
  431. package/src/components/Stepper/Step.tsx +30 -0
  432. package/src/components/Stepper/Stepper.tsx +113 -0
  433. package/src/components/Stepper/headers.tsx +64 -0
  434. package/src/components/Stepper/index.ts +3 -0
  435. package/src/components/Table/HeaderItem.tsx +52 -0
  436. package/src/components/Table/SettingsVerticalMenu.tsx +50 -0
  437. package/src/components/Table/StyledLinkTable.tsx +22 -0
  438. package/src/components/Table/TableData.tsx +251 -0
  439. package/src/components/Table/index.tsx +2 -0
  440. package/src/components/TimelineSection.tsx +66 -0
  441. package/src/components/error/ErrorFeedback.tsx +217 -0
  442. package/src/components/error/NotFound.tsx +24 -0
  443. package/src/components/error/UnderMaintenance.tsx +30 -0
  444. package/src/components/error/index.ts +4 -0
  445. package/src/components/form/Form/Form.tsx +101 -0
  446. package/src/components/form/Form/FormGroup.tsx +221 -0
  447. package/src/components/form/Form/index.ts +2 -0
  448. package/src/components/form/SearchInput.tsx +69 -0
  449. package/src/components/form/Select/CustomSelect.tsx +232 -0
  450. package/src/components/form/Select/DetailedSelect.tsx +85 -0
  451. package/src/components/form/Select/Select.tsx +67 -0
  452. package/src/components/form/Select/index.ts +4 -0
  453. package/src/components/form/Select/styled.ts +165 -0
  454. package/src/components/form/Select/types.ts +112 -0
  455. package/src/components/form/Select/utils.tsx +28 -0
  456. package/src/components/notification/NotificationComponent.tsx +340 -0
  457. package/src/components/notification/NotificationItem.tsx +353 -0
  458. package/src/components/notification/NotificationList.tsx +185 -0
  459. package/src/components/notification/NotificationPlaceholder.tsx +60 -0
  460. package/src/components/notification/types.ts +72 -0
  461. package/src/containers/NotificationsPage.tsx +120 -0
  462. package/src/context/anchor.tsx +37 -0
  463. package/src/context/loading.tsx +36 -0
  464. package/src/context/notification/LazyNotificationList.ts +103 -0
  465. package/src/context/notification/NotificationController.ts +119 -0
  466. package/src/context/notification/context.tsx +23 -0
  467. package/src/context/notification/hooks.ts +98 -0
  468. package/src/context/notification/types.ts +71 -0
  469. package/src/hooks/date.ts +68 -0
  470. package/src/hooks/keyboard.tsx +128 -0
  471. package/src/hooks/manual-render.tsx +10 -0
  472. package/src/hooks/service-now.tsx +64 -19
  473. package/src/hooks/text.tsx +30 -0
  474. package/src/hooks/title.tsx +13 -0
  475. package/src/index.ts +14 -6
  476. package/src/notifications.ts +11 -0
  477. package/src/svg/AI.tsx +41 -0
  478. package/src/svg/CS.tsx +48 -0
  479. package/src/svg/EDP.tsx +31 -0
  480. package/src/svg/Forbidden.tsx +22 -0
  481. package/src/svg/GenericPlaceholder.tsx +16 -0
  482. package/src/svg/HUB.tsx +48 -0
  483. package/src/svg/Logo.tsx +16 -0
  484. package/src/svg/MiniLogo.tsx +12 -0
  485. package/src/svg/NotFound.tsx +16 -0
  486. package/src/svg/ServerError.tsx +33 -0
  487. package/src/svg/Unauthenticated.tsx +16 -0
  488. package/src/svg/index.ts +11 -0
  489. package/src/utils/accessibility.ts +135 -0
  490. package/src/utils/cookie.ts +73 -0
  491. package/src/utils/promise.ts +5 -0
  492. package/src/utils/read-file.ts +16 -0
  493. package/tsconfig.json +1 -0
  494. package/dist/components/Login.d.ts +0 -26
  495. package/dist/components/Login.d.ts.map +0 -1
  496. package/dist/components/Login.js +0 -100
  497. package/dist/components/Login.js.map +0 -1
  498. package/dist/components/MiniLogo.d.ts +0 -6
  499. package/dist/components/MiniLogo.d.ts.map +0 -1
  500. package/dist/components/MiniLogo.js +0 -4
  501. package/dist/components/MiniLogo.js.map +0 -1
  502. package/dist/components/tour/StepContainer.d.ts +0 -13
  503. package/dist/components/tour/StepContainer.d.ts.map +0 -1
  504. package/dist/components/tour/StepContainer.js +0 -48
  505. package/dist/components/tour/StepContainer.js.map +0 -1
  506. package/dist/components/tour/StepNavigation.d.ts +0 -13
  507. package/dist/components/tour/StepNavigation.d.ts.map +0 -1
  508. package/dist/components/tour/StepNavigation.js +0 -20
  509. package/dist/components/tour/StepNavigation.js.map +0 -1
  510. package/dist/components/tour/StepTitle.d.ts +0 -7
  511. package/dist/components/tour/StepTitle.d.ts.map +0 -1
  512. package/dist/components/tour/StepTitle.js +0 -5
  513. package/dist/components/tour/StepTitle.js.map +0 -1
  514. package/dist/components/tour/context.d.ts +0 -17
  515. package/dist/components/tour/context.d.ts.map +0 -1
  516. package/dist/components/tour/context.js +0 -48
  517. package/dist/components/tour/context.js.map +0 -1
  518. package/dist/components/tour/index.d.ts +0 -9
  519. package/dist/components/tour/index.d.ts.map +0 -1
  520. package/dist/components/tour/index.js +0 -4
  521. package/dist/components/tour/index.js.map +0 -1
  522. package/dist/components/tour/utils.d.ts +0 -13
  523. package/dist/components/tour/utils.d.ts.map +0 -1
  524. package/dist/components/tour/utils.js +0 -43
  525. package/dist/components/tour/utils.js.map +0 -1
  526. package/src/components/Login.tsx +0 -157
  527. package/src/components/MiniLogo.tsx +0 -32
  528. package/src/components/tour/StepContainer.tsx +0 -67
  529. package/src/components/tour/StepNavigation.tsx +0 -32
  530. package/src/components/tour/StepTitle.tsx +0 -17
  531. package/src/components/tour/context.tsx +0 -56
  532. package/src/components/tour/index.ts +0 -7
  533. package/src/components/tour/utils.tsx +0 -65
@@ -0,0 +1,353 @@
1
+ import { Box, Button, Flex, IconBox, OneOfColorSchemesWithVariants, Styles, SxProp, Text } from '@citric/core'
2
+ import { Envelope, EnvelopeOpen, ExternalLink } from '@citric/icons'
3
+ import { IconButton, Tooltip } from '@citric/ui'
4
+ import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
5
+ import { differenceInDays, parseISO } from 'date-fns'
6
+ import styled from 'styled-components'
7
+ import { useAnchorTag } from '../../context/anchor'
8
+ import { useGetNotificationTitleAndDescription } from '../../context/notification/hooks'
9
+ import { useDateFormatter } from '../../hooks/date'
10
+ import { LazyMarkdown } from '../LazyMarkdown'
11
+ import { GetTenantNotificationsResponse } from './types'
12
+
13
+ const styles = {
14
+ item: (color: string, isRead: boolean) => ({
15
+ borderLeft: `2px solid ${color}`,
16
+ opacity: isRead ? 0.5 : 1,
17
+ }),
18
+ } satisfies Record<string, (...args: any) => SxProp>
19
+
20
+ const statusToColor: Record<string, OneOfColorSchemesWithVariants> = {
21
+ LOW: 'success.500',
22
+ MEDIUM: 'warning.500',
23
+ HIGH: 'danger.500',
24
+ }
25
+
26
+ interface Props {
27
+ notification: GetTenantNotificationsResponse,
28
+ isSummary: boolean,
29
+ // @deprecated this property currently does nothing. Remove in next major.
30
+ id?: string,
31
+ onClickViewNotification?: () => void,
32
+ }
33
+
34
+ const style: Styles = {
35
+ notificationDescription: {
36
+ display: '-webkit-box',
37
+ WebkitBoxOrient: 'vertical',
38
+ overflow: 'hidden',
39
+ WebkitLineClamp: '2',
40
+ lineHeight: '1.5',
41
+ maxHeight: '3em',
42
+ maxWidth: '340px',
43
+ },
44
+ notificationTooltip: {
45
+ overflowWrap: 'break-word',
46
+ },
47
+ }
48
+
49
+ /**
50
+ * NotificationHeader component that renders the header of a notification.
51
+ *
52
+ * @param props the component's props.
53
+ */
54
+ const NotificationHeader = ({ title, isSummary }: { title: string, isSummary: boolean }) => (
55
+ <Flex justifyContent="space-between" mb={2} sx={{ maxWidth: isSummary ? '330px' : '100%' }} flexWrap="nowrap">
56
+ <Text appearance={isSummary ? 'body2' : 'body1'} weight="medium" nowrapEllipsis mr={5}>
57
+ {title}
58
+ </Text>
59
+ </Flex>
60
+ )
61
+
62
+ /**
63
+ * Get the number of days ago from the given date string.
64
+ *
65
+ * @param {string} dateString - The date string to calculate the days ago.
66
+ * @returns {number} The number of days ago.
67
+ */
68
+ const getDaysAgo = (dateString: string): number => {
69
+ const givenDate = parseISO(dateString)
70
+ const today = new Date()
71
+ return differenceInDays(today, givenDate)
72
+ }
73
+
74
+ /**
75
+ * NotificationContent component that renders the content of a notification.
76
+ *
77
+ * @param props the component's props {@link Props}.
78
+ */
79
+ const NotificationContent = ({ notification, isSummary, onClickViewNotification }: Props) => {
80
+ const { formatRelativeWithTooltip } = useDateFormatter()
81
+ const relativeDate = formatRelativeWithTooltip(notification.trigger_at)
82
+ const Link = useAnchorTag()
83
+
84
+ const t = useTranslate(dictionary)
85
+ const { description } = useGetNotificationTitleAndDescription(notification)
86
+ const daysAgo = getDaysAgo(notification.trigger_at)
87
+
88
+ const components = () => ({
89
+ ul: (props: any) => (
90
+ <Text
91
+ as="ul"
92
+ appearance="body2"
93
+ colorScheme="light.700"
94
+ sx={{ listStyleType: 'disc', marginLeft: '2rem', marginBottom: '1em' }}
95
+ {...props}
96
+ />
97
+ ),
98
+ li: (props: any) => (
99
+ <Text
100
+ as="li"
101
+ appearance="body2"
102
+ colorScheme="light.700"
103
+ sx={{ marginBottom: '0.5em' }}
104
+ {...props}
105
+ />
106
+ ),
107
+ p: (props: any) => (
108
+ <Text
109
+ as="p"
110
+ appearance="body2"
111
+ sx={{ marginBottom: '1em' }}
112
+ {...props}
113
+ />
114
+ ),
115
+ })
116
+
117
+ const navigateToNotificationPosition = (ev: React.MouseEvent<HTMLElement>, anchorText: string) => {
118
+ ev.preventDefault()
119
+
120
+ const checkElement = setInterval(() => {
121
+ const target = document.getElementById(anchorText)
122
+ if (target) {
123
+ target.scrollIntoView({ behavior: 'smooth', block: 'start' })
124
+ clearInterval(checkElement)
125
+ }
126
+ }, 100)
127
+ }
128
+
129
+ return (
130
+ <>
131
+ {!isSummary && <Flex mt={4} mb={3} flexDirection="column">
132
+ <LazyMarkdown components={components()}>{description}</LazyMarkdown>
133
+ </Flex>}
134
+ {isSummary && (
135
+ <Text appearance="body2" mb={3} sx={style.notificationDescription}>
136
+ {handleTextMark(description)}
137
+ </Text>
138
+ )}
139
+ <Flex justifyContent="space-between">
140
+ <Flex>
141
+ <Text appearance="microtext1" colorScheme="light.700">
142
+ {t[notification.context]}
143
+ </Text>
144
+ <Text appearance="microtext1" colorScheme="light.700" mx="2">
145
+
146
+ </Text>
147
+ {!isSummary && relativeDate && (<>
148
+ <Text appearance="microtext1" colorScheme="light.700">
149
+ {relativeDate.relative}
150
+ </Text>
151
+ <Text appearance="microtext1" colorScheme="light.700" mx="2">
152
+
153
+ </Text>
154
+ </>)}
155
+ <Text appearance="microtext1" colorScheme="light.700">
156
+ {daysAgo > 0 ? daysAgo + ' ' + t.daysAgo : t.today}
157
+ </Text>
158
+ </Flex>
159
+ {isSummary && description.length > 120 && (
160
+ <Link
161
+ href="/notifications"
162
+ onClick={(ev: React.MouseEvent<HTMLElement>) => {
163
+ onClickViewNotification?.()
164
+ navigateToNotificationPosition(ev, `notification-item-${notification.id}`)
165
+ }}>
166
+ <Text appearance="microtext1" colorScheme="light.700">{t.readMore}</Text>
167
+ </Link>
168
+ )}
169
+ </Flex>
170
+ </>
171
+ )
172
+ }
173
+
174
+ interface NotificationFooterProps {
175
+ /**
176
+ * The URL to open when the action button is clicked.
177
+ */
178
+ actionURL: string,
179
+ /**
180
+ * Function to call when the user clicks the action button.
181
+ */
182
+ onClickAction: () => void,
183
+ /**
184
+ * Notification title
185
+ */
186
+ title?: string,
187
+ }
188
+
189
+ /**
190
+ * NotificationFooter component that renders the footer of a notification.
191
+ *
192
+ * @param props the component's props {@link NotificationFooterProps}.
193
+ */
194
+ const NotificationFooter = ({ actionURL, onClickAction, title }: NotificationFooterProps) => {
195
+ const t = useTranslate(dictionary)
196
+ const Link = useAnchorTag()
197
+
198
+ return (
199
+ <Flex mt="5">
200
+ <Button
201
+ size="sm"
202
+ colorScheme="inverse"
203
+ appearance="text"
204
+ onClick={onClickAction}
205
+ as={Link}
206
+ href={actionURL}
207
+ aria-label={t.viewNotification.replace('%s', title || t.moreDetails)}
208
+ target="_blank"
209
+ >
210
+ <Text sx={{ mr: 2, textDecoration: 'underline' }}>
211
+ {t.moreDetails}
212
+ </Text>
213
+ <IconBox size="xs">
214
+ <ExternalLink />
215
+ </IconBox>
216
+ </Button>
217
+ </Flex>
218
+ )
219
+ }
220
+
221
+ interface DeprecatedNotificationItemProps extends Props {
222
+ /**
223
+ * @deprecated use `onCommit` and `onClickAction` instead.
224
+ *
225
+ * Function to call when the user marks a notification as read or unread. This can happen either through the mail icon or when the user
226
+ * clicks the action button of a notification. Type will be "icon" on the first case or "callToAction" on the former.
227
+ *
228
+ * Tip: clicking the action button (callToAction) should only change the read status if the message is unread. This is not treated by this
229
+ * component, be sure to handle it on your side.
230
+ *
231
+ * Deprecation warning: since the deprecation, the parameter `read` is always true.
232
+ */
233
+ onClickMarkReadUnread: (read: boolean, type: 'callToAction' | 'icon') => void | Promise<void>,
234
+ }
235
+
236
+ interface NewNotificationItemProps extends Props {
237
+ /**
238
+ * Function to call when the user marks a notification as read (committed).
239
+ */
240
+ onCommit: () => void,
241
+ /**
242
+ * Function to call when the user marks a notification as unread (uncommitted).
243
+ */
244
+ onUncommit: () => void,
245
+ /**
246
+ * Whenever the user clicks the action button of a notification, the notification is marked as read (committed) and the browser is
247
+ * redirected to the page that corresponds to the action.
248
+ *
249
+ * If you need additional behavior, use this parameter, which is a function to call whenever the button is clicked.
250
+ */
251
+ onClickAction?: () => void,
252
+ /**
253
+ * Function to call when the user clicks in read more button.
254
+ */
255
+ onClickViewNotification?: () => void,
256
+ }
257
+
258
+ type NotificationItemProps = DeprecatedNotificationItemProps | NewNotificationItemProps
259
+
260
+ const StyledBox = styled(Box)<{$isSummary?: boolean}>`
261
+ .notification-item {
262
+ padding: ${({ $isSummary }) => $isSummary ? '8px 8px 8px 16px' : '16px'};
263
+ }
264
+ `
265
+
266
+ /**
267
+ * NotificationItem component that renders a notification item.
268
+ *
269
+ * @param props the component's props {@link NotificationItemProps}.
270
+ */
271
+ export const NotificationItem = ({ notification, isSummary, ...props }: NotificationItemProps) => {
272
+ const t = useTranslate(dictionary)
273
+ const { title } = useGetNotificationTitleAndDescription(notification)
274
+ const committed = notification.committed
275
+
276
+ function commit() {
277
+ if ('onCommit' in props) props.onCommit()
278
+ else props.onClickMarkReadUnread(true, 'icon')
279
+ }
280
+
281
+ function uncommit() {
282
+ if ('onUncommit' in props) props.onUncommit()
283
+ else props.onClickMarkReadUnread(false, 'icon')
284
+ }
285
+
286
+ function clickAction() {
287
+ if ('onCommit' in props) {
288
+ if (!committed) props.onCommit()
289
+ props.onClickAction?.()
290
+ }
291
+ else props.onClickMarkReadUnread(true, 'callToAction')
292
+ }
293
+
294
+ return (
295
+ <StyledBox sx={{ position: 'relative' }} id={props.id} $isSummary={isSummary}>
296
+ <Flex bg="light.400" r="xs"
297
+ flexWrap="nowrap"
298
+ className="notification-item"
299
+ flexDirection="column" w="100%" sx={styles.item(statusToColor[notification.criticality], committed)}>
300
+ <NotificationHeader title={title} isSummary={isSummary} />
301
+ <NotificationContent notification={notification} isSummary={isSummary} onClickViewNotification={props.onClickViewNotification} />
302
+ {notification.call_to_action && <NotificationFooter
303
+ actionURL={notification.call_to_action}
304
+ onClickAction={clickAction}
305
+ title={title}
306
+ />}
307
+ </Flex>
308
+ <Box sx={{ position: 'absolute', top: '8px', right: '8px' }}>
309
+ <Tooltip text={committed ? t.committed : t.uncommitted} position="left">
310
+ <IconButton aria-label={committed ? t.committed : t.uncommitted} onClick={() => committed ? uncommit() : commit()}>
311
+ <IconBox size="xs" style={{ opacity: committed ? 0.5 : 1 }}>
312
+ {committed ? <EnvelopeOpen /> : <Envelope />}
313
+ </IconBox>
314
+ </IconButton>
315
+ </Tooltip>
316
+ </Box>
317
+ </StyledBox>
318
+ )
319
+ }
320
+
321
+ function handleTextMark(text: string) {
322
+ // eslint-disable-next-line no-useless-escape
323
+ return text.replace(/[^\p{L}\p{N}\s\p{Emoji_Presentation}:!'()"\/_-]/gu, '')
324
+ }
325
+
326
+ const dictionary = {
327
+ en: {
328
+ ACCOUNT: 'Account',
329
+ WORKSPACE: 'Workspace',
330
+ STUDIO: 'Studio',
331
+ AI: 'AI',
332
+ daysAgo: 'days ago',
333
+ today: 'today',
334
+ committed: 'This notification has been read.',
335
+ uncommitted: 'This notification has not been read yet. Click to mark as read.',
336
+ moreDetails: 'More details',
337
+ viewNotification: 'View notification %s',
338
+ readMore: 'Read more',
339
+ },
340
+ pt: {
341
+ ACCOUNT: 'Conta',
342
+ WORKSPACE: 'Workspace',
343
+ STUDIO: 'Estúdio',
344
+ AI: 'AI',
345
+ daysAgo: 'dias atrás',
346
+ today: 'hoje',
347
+ committed: 'Esta notificação já foi lida.',
348
+ uncommitted: 'Esta notificação ainda não foi lida. Clique para marcar como lida.',
349
+ moreDetails: 'Acessar detalhes',
350
+ viewNotification: 'Visualizar notificação %s',
351
+ readMore: 'Ler mais',
352
+ },
353
+ } satisfies Dictionary
@@ -0,0 +1,185 @@
1
+ import { Box, Flex } from '@citric/core'
2
+ import { listToClass } from '@stack-spot/portal-theme'
3
+ import { Month } from '@stack-spot/portal-translate'
4
+ import { last } from 'lodash'
5
+ import { useMemo } from 'react'
6
+ import { styled } from 'styled-components'
7
+ import { InfiniteScroll } from '../InfiniteScroll'
8
+ import { TimelineSection } from '../TimelineSection'
9
+ import { NotificationItem } from './NotificationItem'
10
+ import { NotificationPlaceholder } from './NotificationPlaceholder'
11
+ import { GetTenantNotificationsResponse, InfiniteScrollConfig } from './types'
12
+
13
+ export interface NotificationListProps {
14
+ /**
15
+ * Function to call when the message is marked as read (committed).
16
+ * @param id the id of the notification where the read status changed.
17
+ */
18
+ onCommit: (id: string) => void,
19
+ /**
20
+ * Function to call when the message is marked as unread (uncommitted).
21
+ * @param id the id of the notification where the read status changed.
22
+ */
23
+ onUncommit: (id: string) => void,
24
+ /**
25
+ * Optional. Function called when the button to perform the notification action is clicked. This function will be run in addition to
26
+ * the notification action.
27
+ * @param id the id of the notification where the button was clicked
28
+ */
29
+ onClickAction?: (id: string) => void,
30
+ /**
31
+ * Optional. Function called when the button read more in notification is clicked.
32
+ */
33
+ onClickViewNotification?: () => void,
34
+ /**
35
+ * If you need this notification list to be have an infinite scroll behavior, set this option.
36
+ */
37
+ infiniteScroll?: InfiniteScrollConfig,
38
+ /**
39
+ * The notifications themselves.
40
+ */
41
+ items: GetTenantNotificationsResponse[],
42
+ /**
43
+ * A compact notification list don't show date headers (as a timeline) or descriptions of notifications.
44
+ */
45
+ compact?: boolean,
46
+ /**
47
+ * Whether or not the content is loading. If this is true, the content becomes transparent and the cursor turns into the progress cursor.
48
+ */
49
+ loading?: boolean,
50
+ /**
51
+ * If true, when the list is empty, the placeholder will say "nothing found" instead of "no notifications".
52
+ */
53
+ showEmptySearch?: boolean,
54
+ style?: React.CSSProperties,
55
+ className?: string,
56
+ }
57
+
58
+ interface NotificationGroup {
59
+ month: Month,
60
+ day: number,
61
+ year: number,
62
+ items: GetTenantNotificationsResponse[],
63
+ }
64
+
65
+ const StyledBox = styled(Box)`
66
+ width: 100%;
67
+ position: relative;
68
+ transition: opacity 0.3s;
69
+
70
+ > div:first-child{
71
+ width: 100%;
72
+ }
73
+
74
+ &.loading {
75
+ opacity: 0.6;
76
+ .loading-mask {
77
+ pointer-events: auto;
78
+ }
79
+ }
80
+
81
+ .loading-mask {
82
+ opacity: 0;
83
+ position: absolute;
84
+ pointer-events: none;
85
+ top: 0;
86
+ right: 0;
87
+ left: 0;
88
+ bottom: 0;
89
+ cursor: progress;
90
+ }
91
+
92
+ .placeholder.compact {
93
+ & > div {
94
+ padding-block: 0;
95
+ gap: 16px;
96
+ & > div {
97
+ text-align: center;
98
+ h4 {
99
+ margin-bottom: 10px;
100
+ }
101
+ p {
102
+ margin: 0;
103
+ }
104
+ }
105
+ }
106
+ }
107
+ `
108
+
109
+ // this assumes the data from the backend is ordered by date (trigger_at)
110
+ function groupNotificationsByDate(notifications: GetTenantNotificationsResponse[]): NotificationGroup[] {
111
+ const groups: NotificationGroup[] = []
112
+ for (const n of notifications) {
113
+ let currentGroup = last(groups)
114
+ const date = new Date(n.trigger_at)
115
+ const year = date.getFullYear()
116
+ const month = date.getMonth() as Month
117
+ const day = date.getDate()
118
+ if (!currentGroup || currentGroup.day !== day || currentGroup.month !== month || currentGroup.year !== year) {
119
+ currentGroup = { year, month, day, items: [] }
120
+ groups.push(currentGroup)
121
+ }
122
+ currentGroup.items.push(n)
123
+ }
124
+ return groups
125
+ }
126
+
127
+ export const NotificationList = (
128
+ { items, compact = false, onCommit, onUncommit, onClickAction, onClickViewNotification,
129
+ infiniteScroll, loading, showEmptySearch, style, className }: NotificationListProps,
130
+ ) => {
131
+ const groups: NotificationGroup[] = useMemo(
132
+ () => compact ? [{ day: 0, month: 0, year: 0, items }] : groupNotificationsByDate(items),
133
+ [compact, items],
134
+ )
135
+
136
+ const renderNotifications = (notifications: GetTenantNotificationsResponse[], key?: string) => (
137
+ <Flex sx={{ gap: '4px' }} flexDirection="column" key={key}>
138
+ {notifications?.map((item) => (
139
+ <NotificationItem
140
+ key={item.id}
141
+ id={key ? '' : `notification-item-${item.id}`}
142
+ notification={item}
143
+ isSummary={compact}
144
+ onClickViewNotification={onClickViewNotification}
145
+ onCommit={() => onCommit(item.id)}
146
+ onUncommit={() => onUncommit(item.id)}
147
+ onClickAction={() => onClickAction?.(item.id)}
148
+ />
149
+ ))}
150
+ </Flex>
151
+ )
152
+
153
+ return infiniteScroll?.scrollableTarget !== null && (
154
+ <StyledBox style={style} className={listToClass([className, loading && 'loading'])}>
155
+ {items.length ? (
156
+ <InfiniteScroll
157
+ dataLength={items.length || 0}
158
+ next={infiniteScroll?.loadMore ?? (() => { })}
159
+ hasMore={infiniteScroll?.hasMore ?? false}
160
+ // @ts-ignore: the library is wrongly typed and abandoned, meaning, it will never be fixed. The source code clearly accepts
161
+ // HTMLElements as scrollable targets:
162
+ // https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/src/index.tsx#L168
163
+ scrollableTarget={infiniteScroll?.scrollableTarget}
164
+ >
165
+ <Flex sx={{ gap: '24px' }} flexDirection="column">
166
+ {groups.map((group) => compact
167
+ ? renderNotifications(group.items, 'compact')
168
+ : (
169
+ <TimelineSection key={`${group.day}-${group.month}-${group.year}`} month={group.month} day={group.day}>
170
+ {renderNotifications(group.items)}
171
+ </TimelineSection>
172
+ ),
173
+ )}
174
+ </Flex>
175
+ </InfiniteScroll>
176
+ ) : <NotificationPlaceholder
177
+ isSearch={showEmptySearch}
178
+ className={listToClass(['placeholder', compact && 'compact'])}
179
+ titleAs="p"
180
+ sx={{ minHeight: '350px' }}
181
+ />}
182
+ <div className="loading-mask"></div>
183
+ </StyledBox>
184
+ )
185
+ }
@@ -0,0 +1,60 @@
1
+ import { AsProp } from '@citric/core/dist/forward-ref-as'
2
+ import { SxProperties } from '@citric/core/dist/sx'
3
+ import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
4
+ import { PlaceholderCallToAction } from '../Placeholder'
5
+
6
+ interface Props {
7
+ isSearch?: boolean,
8
+ style?: React.CSSProperties,
9
+ className?: string,
10
+ sx?: SxProperties,
11
+ sxCard?: SxProperties,
12
+ titleAs?: AsProp,
13
+ }
14
+
15
+ export const NotificationPlaceholder = ({ isSearch, sx, sxCard, className, style, titleAs }: Props) => {
16
+ const t = useTranslate(dictionary)
17
+
18
+ return <PlaceholderCallToAction
19
+ title={
20
+ isSearch
21
+ ? (<>{t.placeholderSearchTitle}<br />{t.placeholderSearchSubTitle}</>)
22
+ : (<>{t.placeholderTitle}<br />{t.placeholderSubTitle}</>)
23
+ }
24
+ description={
25
+ isSearch
26
+ ? (<>{t.placeholderSearchDescription}<br />{t.placeholderSearchSubDescription}</>)
27
+ : (<>{t.placeholderDescription}<br />{t.placeholderSubDescription}</>)
28
+ }
29
+ fullWidth
30
+ sx={sx}
31
+ sxCard={sxCard}
32
+ className={className}
33
+ style={style}
34
+ titleAs={titleAs}
35
+ placeholderImageConfig={{ width: '200', height: '200' }}
36
+ />
37
+ }
38
+
39
+ const dictionary = {
40
+ en: {
41
+ placeholderTitle: 'You don’t have',
42
+ placeholderSubTitle: 'any notifications yet.',
43
+ placeholderDescription: 'Relevant updates will show up here',
44
+ placeholderSubDescription: 'as soon as they’re available.',
45
+ placeholderSearchTitle: 'No notifications',
46
+ placeholderSearchSubTitle: 'match your filters.',
47
+ placeholderSearchDescription: 'Try changing the filters',
48
+ placeholderSearchSubDescription: 'to see more results.',
49
+ },
50
+ pt: {
51
+ placeholderTitle: 'Você ainda não tem',
52
+ placeholderSubTitle: 'notificações.',
53
+ placeholderDescription: 'Quando houver alguma atualização relevante,',
54
+ placeholderSubDescription: 'ela será exibida aqui.',
55
+ placeholderSearchTitle: 'Nenhuma notificação',
56
+ placeholderSearchSubTitle: 'corresponde aos filtros',
57
+ placeholderSearchDescription: 'Experimente mudar os filtros',
58
+ placeholderSearchSubDescription: 'para encontrar mais notificações.',
59
+ },
60
+ } satisfies Dictionary
@@ -0,0 +1,72 @@
1
+ export type NotificationType = 'LOW' | 'MEDIUM' | 'HIGH'
2
+
3
+ export type NotificationContext = 'ACCOUNT' | 'STUDIO' | 'WORKSPACE' | 'AI'
4
+
5
+ //The following three notification types comes from the api swagger
6
+
7
+ export type NotificationContentResponse = {
8
+ title: string,
9
+ description: string,
10
+ };
11
+
12
+ export type GetTenantNotificationsResponse = {
13
+ id: string,
14
+ content: {
15
+ [key: string]: NotificationContentResponse,
16
+ },
17
+ broadcast_level: 'ACCOUNT' | 'INDIVIDUAL' | 'PLATFORM' | 'RESOURCE',
18
+ context: 'ACCOUNT' | 'STUDIO' | 'WORKSPACE' | 'AI',
19
+ target?: string,
20
+ criticality: 'LOW' | 'MEDIUM' | 'HIGH',
21
+ call_to_action: string,
22
+ persistent: boolean,
23
+ committed: boolean,
24
+ last_until?: string,
25
+ trigger_at: string,
26
+ created_at?: string,
27
+ isBanner?: boolean,
28
+ }
29
+
30
+ export type ResponseModelGetTenantNotificationsResponse = {
31
+ items: GetTenantNotificationsResponse[],
32
+ total: number,
33
+ }
34
+
35
+ export type NotificationTypeFilters = NotificationType | UnreadType
36
+
37
+ export interface NotificationFilters {
38
+ filterBy?: 'criticality' | 'context',
39
+ filterValue?: string,
40
+ sort?: string,
41
+ direction?: string,
42
+ page?: any,
43
+ size?: string,
44
+ }
45
+
46
+ export interface NotificationCommitted {
47
+ id: string,
48
+ committed: boolean,
49
+ }
50
+
51
+ // fixme: please, do not ignore lint rules. They exist for a reason. Next major: transform this enum into a disjoint string type.
52
+ // eslint-disable-next-line no-restricted-syntax
53
+ export enum UnreadType {
54
+ Unread = 'unread',
55
+ }
56
+
57
+ export interface InfiniteScrollConfig {
58
+ /**
59
+ * Function to load more items into the list. Called when the scroll is almost reaching its end.
60
+ */
61
+ loadMore: () => void,
62
+ /**
63
+ * Set this to false to prevent the scroll from loading more items when it reaches the end.
64
+ */
65
+ hasMore: boolean,
66
+ /**
67
+ * Defines which scroll will be used as the target of the infinite scroll.
68
+ *
69
+ * If null, nothing renders, it waits until it has a value.
70
+ */
71
+ scrollableTarget?: string | HTMLElement | null,
72
+ }