@oneuptime/common 9.4.7 → 9.4.8

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 (304) hide show
  1. package/Models/DatabaseModels/Alert.ts +76 -0
  2. package/Models/DatabaseModels/AlertEpisode.ts +1201 -0
  3. package/Models/DatabaseModels/AlertEpisodeFeed.ts +529 -0
  4. package/Models/DatabaseModels/AlertEpisodeInternalNote.ts +455 -0
  5. package/Models/DatabaseModels/AlertEpisodeMember.ts +586 -0
  6. package/Models/DatabaseModels/AlertEpisodeOwnerTeam.ts +421 -0
  7. package/Models/DatabaseModels/AlertEpisodeOwnerUser.ts +419 -0
  8. package/Models/DatabaseModels/AlertEpisodeStateTimeline.ts +523 -0
  9. package/Models/DatabaseModels/AlertFeed.ts +1 -0
  10. package/Models/DatabaseModels/AlertGroupingRule.ts +1432 -0
  11. package/Models/DatabaseModels/Index.ts +18 -0
  12. package/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.ts +70 -0
  13. package/Models/DatabaseModels/StatusPageDomain.ts +2 -0
  14. package/Models/DatabaseModels/WorkspaceNotificationLog.ts +57 -0
  15. package/Server/API/SlackAPI.ts +21 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1768938069147-MigrationName.ts +751 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1769125561322-MigrationName.ts +41 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1769170578688-MigrationName.ts +29 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1769172358833-MigrationName.ts +177 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1769176450526-MigrationName.ts +71 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1769190495840-MigrationName.ts +35 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1769199303656-MigrationName.ts +29 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1769202898645-MigrationName.ts +29 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1769428619414-MigrationName.ts +35 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1769428821686-MigrationName.ts +47 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +20 -0
  27. package/Server/Services/AlertEpisodeFeedService.ts +94 -0
  28. package/Server/Services/AlertEpisodeInternalNoteService.ts +71 -0
  29. package/Server/Services/AlertEpisodeMemberService.ts +267 -0
  30. package/Server/Services/AlertEpisodeOwnerTeamService.ts +10 -0
  31. package/Server/Services/AlertEpisodeOwnerUserService.ts +10 -0
  32. package/Server/Services/AlertEpisodeService.ts +988 -0
  33. package/Server/Services/AlertEpisodeStateTimelineService.ts +557 -0
  34. package/Server/Services/AlertGroupingEngineService.ts +1120 -0
  35. package/Server/Services/AlertGroupingRuleService.ts +14 -0
  36. package/Server/Services/AlertService.ts +12 -0
  37. package/Server/Services/CallService.ts +2 -0
  38. package/Server/Services/Index.ts +21 -0
  39. package/Server/Services/MailService.ts +5 -0
  40. package/Server/Services/OnCallDutyPolicyService.ts +5 -0
  41. package/Server/Services/SmsService.ts +2 -0
  42. package/Server/Services/UserNotificationSettingService.ts +23 -0
  43. package/Server/Services/WhatsAppService.ts +5 -0
  44. package/Server/Services/WorkspaceNotificationRuleService.ts +26 -0
  45. package/Server/Utils/AnalyticsDatabase/Statement.ts +6 -2
  46. package/Server/Utils/WhatsAppTemplateUtil.ts +13 -0
  47. package/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.ts +18 -0
  48. package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +689 -0
  49. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +16 -0
  50. package/Server/Utils/Workspace/Slack/Actions/ActionTypes.ts +11 -0
  51. package/Server/Utils/Workspace/Slack/Actions/AlertEpisode.ts +915 -0
  52. package/Server/Utils/Workspace/Slack/Messages/AlertEpisode.ts +120 -0
  53. package/Server/Utils/Workspace/WorkspaceMessages/AlertEpisode.ts +74 -0
  54. package/Tests/Server/Services/AlertEpisodeMemberService.test.ts +200 -0
  55. package/Tests/Server/Services/AlertEpisodeService.test.ts +240 -0
  56. package/Tests/Server/Services/AlertGroupingEngineService.test.ts +542 -0
  57. package/Tests/Server/Services/AlertGroupingRuleService.test.ts +383 -0
  58. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +1 -1
  59. package/Tests/UI/Components/Input.test.tsx +1 -1
  60. package/Tests/UI/Components/TextArea.test.tsx +2 -2
  61. package/Types/BaseDatabase/SortOrder.ts +9 -0
  62. package/Types/Email/EmailTemplateType.ts +5 -0
  63. package/Types/NotificationRule/NotificationRuleType.ts +1 -0
  64. package/Types/NotificationSetting/NotificationSettingEventType.ts +7 -0
  65. package/Types/Permission.ts +309 -0
  66. package/Types/UserNotification/UserNotificationEventType.ts +1 -0
  67. package/Types/WhatsApp/WhatsAppTemplates.ts +20 -0
  68. package/Types/Workspace/NotificationRules/EventType.ts +1 -0
  69. package/Types/Workspace/NotificationRules/NotificationRuleCondition.ts +32 -3
  70. package/UI/Components/Accordion/Accordion.tsx +20 -2
  71. package/UI/Components/Alerts/Alert.tsx +1 -0
  72. package/UI/Components/Button/Button.tsx +29 -0
  73. package/UI/Components/CardSelect/CardSelect.tsx +5 -1
  74. package/UI/Components/Checkbox/Checkbox.tsx +7 -3
  75. package/UI/Components/ColorCircle/ColorCircle.tsx +2 -0
  76. package/UI/Components/ColorViewer/ColorViewer.tsx +19 -3
  77. package/UI/Components/CopyableButton/CopyableButton.tsx +22 -5
  78. package/UI/Components/Detail/Detail.tsx +1 -1
  79. package/UI/Components/Dropdown/Dropdown.tsx +14 -1
  80. package/UI/Components/Forms/Fields/FormField.tsx +28 -0
  81. package/UI/Components/FullPageModal/FullPageModal.tsx +35 -4
  82. package/UI/Components/Input/Input.tsx +14 -2
  83. package/UI/Components/Link/Link.tsx +1 -0
  84. package/UI/Components/Loader/Loader.tsx +8 -2
  85. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +76 -1
  86. package/UI/Components/Modal/Modal.tsx +47 -3
  87. package/UI/Components/ModelTable/BaseModelTable.tsx +42 -1
  88. package/UI/Components/MoreMenu/MoreMenu.tsx +84 -2
  89. package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +30 -8
  90. package/UI/Components/Pagination/Pagination.tsx +113 -8
  91. package/UI/Components/ProgressBar/ProgressBar.tsx +12 -2
  92. package/UI/Components/Radio/Radio.tsx +21 -3
  93. package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +54 -27
  94. package/UI/Components/StatusBubble/StatusBubble.tsx +7 -2
  95. package/UI/Components/Table/TableHeader.tsx +20 -3
  96. package/UI/Components/Tabs/Tab.tsx +16 -1
  97. package/UI/Components/Tabs/Tabs.tsx +12 -1
  98. package/UI/Components/TextArea/TextArea.tsx +12 -2
  99. package/UI/Components/Toggle/Toggle.tsx +14 -3
  100. package/UI/Components/Tooltip/Tooltip.tsx +11 -1
  101. package/UI/Components/TopAlert/TopAlert.tsx +2 -0
  102. package/build/dist/Models/DatabaseModels/Alert.js +77 -0
  103. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  104. package/build/dist/Models/DatabaseModels/AlertEpisode.js +1225 -0
  105. package/build/dist/Models/DatabaseModels/AlertEpisode.js.map +1 -0
  106. package/build/dist/Models/DatabaseModels/AlertEpisodeFeed.js +553 -0
  107. package/build/dist/Models/DatabaseModels/AlertEpisodeFeed.js.map +1 -0
  108. package/build/dist/Models/DatabaseModels/AlertEpisodeInternalNote.js +467 -0
  109. package/build/dist/Models/DatabaseModels/AlertEpisodeInternalNote.js.map +1 -0
  110. package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +607 -0
  111. package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -0
  112. package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerTeam.js +437 -0
  113. package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerTeam.js.map +1 -0
  114. package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerUser.js +436 -0
  115. package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerUser.js.map +1 -0
  116. package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js +546 -0
  117. package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js.map +1 -0
  118. package/build/dist/Models/DatabaseModels/AlertFeed.js +1 -0
  119. package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
  120. package/build/dist/Models/DatabaseModels/AlertGroupingRule.js +1437 -0
  121. package/build/dist/Models/DatabaseModels/AlertGroupingRule.js.map +1 -0
  122. package/build/dist/Models/DatabaseModels/Index.js +16 -0
  123. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  124. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js +69 -0
  125. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js.map +1 -1
  126. package/build/dist/Models/DatabaseModels/StatusPageDomain.js +2 -0
  127. package/build/dist/Models/DatabaseModels/StatusPageDomain.js.map +1 -1
  128. package/build/dist/Models/DatabaseModels/WorkspaceNotificationLog.js +58 -0
  129. package/build/dist/Models/DatabaseModels/WorkspaceNotificationLog.js.map +1 -1
  130. package/build/dist/Server/API/SlackAPI.js +18 -0
  131. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  132. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768938069147-MigrationName.js +266 -0
  133. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768938069147-MigrationName.js.map +1 -0
  134. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769125561322-MigrationName.js +20 -0
  135. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769125561322-MigrationName.js.map +1 -0
  136. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769170578688-MigrationName.js +16 -0
  137. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769170578688-MigrationName.js.map +1 -0
  138. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769172358833-MigrationName.js +68 -0
  139. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769172358833-MigrationName.js.map +1 -0
  140. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769176450526-MigrationName.js +30 -0
  141. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769176450526-MigrationName.js.map +1 -0
  142. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769190495840-MigrationName.js +18 -0
  143. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769190495840-MigrationName.js.map +1 -0
  144. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769199303656-MigrationName.js +16 -0
  145. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769199303656-MigrationName.js.map +1 -0
  146. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769202898645-MigrationName.js +16 -0
  147. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769202898645-MigrationName.js.map +1 -0
  148. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769428619414-MigrationName.js +18 -0
  149. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769428619414-MigrationName.js.map +1 -0
  150. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769428821686-MigrationName.js +22 -0
  151. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1769428821686-MigrationName.js.map +1 -0
  152. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +20 -0
  153. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  154. package/build/dist/Server/Services/AlertEpisodeFeedService.js +83 -0
  155. package/build/dist/Server/Services/AlertEpisodeFeedService.js.map +1 -0
  156. package/build/dist/Server/Services/AlertEpisodeInternalNoteService.js +70 -0
  157. package/build/dist/Server/Services/AlertEpisodeInternalNoteService.js.map +1 -0
  158. package/build/dist/Server/Services/AlertEpisodeMemberService.js +256 -0
  159. package/build/dist/Server/Services/AlertEpisodeMemberService.js.map +1 -0
  160. package/build/dist/Server/Services/AlertEpisodeOwnerTeamService.js +9 -0
  161. package/build/dist/Server/Services/AlertEpisodeOwnerTeamService.js.map +1 -0
  162. package/build/dist/Server/Services/AlertEpisodeOwnerUserService.js +9 -0
  163. package/build/dist/Server/Services/AlertEpisodeOwnerUserService.js.map +1 -0
  164. package/build/dist/Server/Services/AlertEpisodeService.js +885 -0
  165. package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -0
  166. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js +494 -0
  167. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js.map +1 -0
  168. package/build/dist/Server/Services/AlertGroupingEngineService.js +893 -0
  169. package/build/dist/Server/Services/AlertGroupingEngineService.js.map +1 -0
  170. package/build/dist/Server/Services/AlertGroupingRuleService.js +13 -0
  171. package/build/dist/Server/Services/AlertGroupingRuleService.js.map +1 -0
  172. package/build/dist/Server/Services/AlertService.js +11 -0
  173. package/build/dist/Server/Services/AlertService.js.map +1 -1
  174. package/build/dist/Server/Services/CallService.js +11 -10
  175. package/build/dist/Server/Services/CallService.js.map +1 -1
  176. package/build/dist/Server/Services/Index.js +18 -0
  177. package/build/dist/Server/Services/Index.js.map +1 -1
  178. package/build/dist/Server/Services/MailService.js +3 -0
  179. package/build/dist/Server/Services/MailService.js.map +1 -1
  180. package/build/dist/Server/Services/OnCallDutyPolicyService.js +3 -0
  181. package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
  182. package/build/dist/Server/Services/SmsService.js +11 -10
  183. package/build/dist/Server/Services/SmsService.js.map +1 -1
  184. package/build/dist/Server/Services/UserNotificationSettingService.js +9 -0
  185. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  186. package/build/dist/Server/Services/WhatsAppService.js +3 -0
  187. package/build/dist/Server/Services/WhatsAppService.js.map +1 -1
  188. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +25 -0
  189. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  190. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +4 -2
  191. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
  192. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js +8 -0
  193. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js.map +1 -1
  194. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.js +17 -0
  195. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ActionTypes.js.map +1 -1
  196. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +545 -0
  197. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -0
  198. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +13 -0
  199. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  200. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js +10 -0
  201. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js.map +1 -1
  202. package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js +651 -0
  203. package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js.map +1 -0
  204. package/build/dist/Server/Utils/Workspace/Slack/Messages/AlertEpisode.js +100 -0
  205. package/build/dist/Server/Utils/Workspace/Slack/Messages/AlertEpisode.js.map +1 -0
  206. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/AlertEpisode.js +70 -0
  207. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/AlertEpisode.js.map +1 -0
  208. package/build/dist/Tests/Server/Services/AlertEpisodeMemberService.test.js +165 -0
  209. package/build/dist/Tests/Server/Services/AlertEpisodeMemberService.test.js.map +1 -0
  210. package/build/dist/Tests/Server/Services/AlertEpisodeService.test.js +193 -0
  211. package/build/dist/Tests/Server/Services/AlertEpisodeService.test.js.map +1 -0
  212. package/build/dist/Tests/Server/Services/AlertGroupingEngineService.test.js +412 -0
  213. package/build/dist/Tests/Server/Services/AlertGroupingEngineService.test.js.map +1 -0
  214. package/build/dist/Tests/Server/Services/AlertGroupingRuleService.test.js +308 -0
  215. package/build/dist/Tests/Server/Services/AlertGroupingRuleService.test.js.map +1 -0
  216. package/build/dist/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.js +1 -1
  217. package/build/dist/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.js.map +1 -1
  218. package/build/dist/Tests/UI/Components/Input.test.js +1 -1
  219. package/build/dist/Tests/UI/Components/Input.test.js.map +1 -1
  220. package/build/dist/Tests/UI/Components/TextArea.test.js +2 -2
  221. package/build/dist/Tests/UI/Components/TextArea.test.js.map +1 -1
  222. package/build/dist/Types/BaseDatabase/SortOrder.js +5 -0
  223. package/build/dist/Types/BaseDatabase/SortOrder.js.map +1 -1
  224. package/build/dist/Types/Email/EmailTemplateType.js +4 -0
  225. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  226. package/build/dist/Types/NotificationRule/NotificationRuleType.js +1 -0
  227. package/build/dist/Types/NotificationRule/NotificationRuleType.js.map +1 -1
  228. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +5 -0
  229. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  230. package/build/dist/Types/Permission.js +264 -0
  231. package/build/dist/Types/Permission.js.map +1 -1
  232. package/build/dist/Types/UserNotification/UserNotificationEventType.js +1 -0
  233. package/build/dist/Types/UserNotification/UserNotificationEventType.js.map +1 -1
  234. package/build/dist/Types/WhatsApp/WhatsAppTemplates.js +12 -0
  235. package/build/dist/Types/WhatsApp/WhatsAppTemplates.js.map +1 -1
  236. package/build/dist/Types/Workspace/NotificationRules/EventType.js +1 -0
  237. package/build/dist/Types/Workspace/NotificationRules/EventType.js.map +1 -1
  238. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js +28 -3
  239. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js.map +1 -1
  240. package/build/dist/UI/Components/Accordion/Accordion.js +10 -3
  241. package/build/dist/UI/Components/Accordion/Accordion.js.map +1 -1
  242. package/build/dist/UI/Components/Alerts/Alert.js +1 -1
  243. package/build/dist/UI/Components/Alerts/Alert.js.map +1 -1
  244. package/build/dist/UI/Components/Button/Button.js +8 -2
  245. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  246. package/build/dist/UI/Components/CardSelect/CardSelect.js +1 -1
  247. package/build/dist/UI/Components/CardSelect/CardSelect.js.map +1 -1
  248. package/build/dist/UI/Components/Checkbox/Checkbox.js +2 -2
  249. package/build/dist/UI/Components/Checkbox/Checkbox.js.map +1 -1
  250. package/build/dist/UI/Components/ColorCircle/ColorCircle.js +1 -1
  251. package/build/dist/UI/Components/ColorCircle/ColorCircle.js.map +1 -1
  252. package/build/dist/UI/Components/ColorViewer/ColorViewer.js +12 -3
  253. package/build/dist/UI/Components/ColorViewer/ColorViewer.js.map +1 -1
  254. package/build/dist/UI/Components/CopyableButton/CopyableButton.js +12 -5
  255. package/build/dist/UI/Components/CopyableButton/CopyableButton.js.map +1 -1
  256. package/build/dist/UI/Components/Detail/Detail.js +1 -1
  257. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  258. package/build/dist/UI/Components/Dropdown/Dropdown.js +5 -3
  259. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  260. package/build/dist/UI/Components/Forms/Fields/FormField.js +19 -1
  261. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  262. package/build/dist/UI/Components/FullPageModal/FullPageModal.js +24 -5
  263. package/build/dist/UI/Components/FullPageModal/FullPageModal.js.map +1 -1
  264. package/build/dist/UI/Components/Input/Input.js +3 -3
  265. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  266. package/build/dist/UI/Components/Link/Link.js +1 -1
  267. package/build/dist/UI/Components/Link/Link.js.map +1 -1
  268. package/build/dist/UI/Components/Loader/Loader.js +6 -4
  269. package/build/dist/UI/Components/Loader/Loader.js.map +1 -1
  270. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +56 -3
  271. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  272. package/build/dist/UI/Components/Modal/Modal.js +28 -3
  273. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  274. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +23 -1
  275. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  276. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +67 -6
  277. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  278. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +14 -3
  279. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
  280. package/build/dist/UI/Components/Pagination/Pagination.js +69 -13
  281. package/build/dist/UI/Components/Pagination/Pagination.js.map +1 -1
  282. package/build/dist/UI/Components/ProgressBar/ProgressBar.js +2 -2
  283. package/build/dist/UI/Components/ProgressBar/ProgressBar.js.map +1 -1
  284. package/build/dist/UI/Components/Radio/Radio.js +8 -5
  285. package/build/dist/UI/Components/Radio/Radio.js.map +1 -1
  286. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -4
  287. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
  288. package/build/dist/UI/Components/StatusBubble/StatusBubble.js +2 -2
  289. package/build/dist/UI/Components/StatusBubble/StatusBubble.js.map +1 -1
  290. package/build/dist/UI/Components/Table/TableHeader.js +12 -4
  291. package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
  292. package/build/dist/UI/Components/Tabs/Tab.js +8 -1
  293. package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
  294. package/build/dist/UI/Components/Tabs/Tabs.js +4 -3
  295. package/build/dist/UI/Components/Tabs/Tabs.js.map +1 -1
  296. package/build/dist/UI/Components/TextArea/TextArea.js +3 -3
  297. package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
  298. package/build/dist/UI/Components/Toggle/Toggle.js +7 -4
  299. package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
  300. package/build/dist/UI/Components/Tooltip/Tooltip.js +4 -1
  301. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  302. package/build/dist/UI/Components/TopAlert/TopAlert.js +1 -1
  303. package/build/dist/UI/Components/TopAlert/TopAlert.js.map +1 -1
  304. package/package.json +2 -1
@@ -13,12 +13,29 @@ export interface ComponentProps {
13
13
  const ColorInput: FunctionComponent<ComponentProps> = (
14
14
  props: ComponentProps,
15
15
  ): ReactElement => {
16
+ const hasOnClick: boolean = Boolean(props.onClick);
17
+ const colorLabel: string =
18
+ props.value?.toString() || props.placeholder || "No Color Selected";
19
+
20
+ const handleKeyDown: (event: React.KeyboardEvent) => void = (
21
+ event: React.KeyboardEvent,
22
+ ): void => {
23
+ if (hasOnClick && (event.key === "Enter" || event.key === " ")) {
24
+ event.preventDefault();
25
+ props.onClick?.();
26
+ }
27
+ };
28
+
16
29
  return (
17
30
  <div
18
31
  className={`flex ${props.className}`}
19
32
  onClick={() => {
20
33
  props.onClick?.();
21
34
  }}
35
+ onKeyDown={handleKeyDown}
36
+ role={hasOnClick ? "button" : undefined}
37
+ tabIndex={hasOnClick ? 0 : undefined}
38
+ aria-label={hasOnClick ? `Color picker: ${colorLabel}` : undefined}
22
39
  data-testid={props.dataTestId}
23
40
  >
24
41
  {props.value && (
@@ -34,11 +51,10 @@ const ColorInput: FunctionComponent<ComponentProps> = (
34
51
  marginRight: "7px",
35
52
  borderStyle: "solid",
36
53
  }}
54
+ aria-hidden="true"
37
55
  ></div>
38
56
  )}
39
- <div>
40
- {props.value?.toString() || props.placeholder || "No Color Selected"}
41
- </div>
57
+ <div>{colorLabel}</div>
42
58
  </div>
43
59
  );
44
60
  };
@@ -19,16 +19,33 @@ const CopyableButton: FunctionComponent<ComponentProps> = (
19
19
  }, 2000);
20
20
  };
21
21
 
22
+ const handleCopy: () => Promise<void> = async (): Promise<void> => {
23
+ refreshCopyToClipboardState();
24
+ await navigator.clipboard?.writeText(props.textToBeCopied);
25
+ };
26
+
27
+ const handleKeyDown: (event: React.KeyboardEvent) => Promise<void> = async (
28
+ event: React.KeyboardEvent,
29
+ ): Promise<void> => {
30
+ if (event.key === "Enter" || event.key === " ") {
31
+ event.preventDefault();
32
+ await handleCopy();
33
+ }
34
+ };
35
+
22
36
  return (
23
37
  <div
24
38
  className={`${
25
39
  copiedToClipboard ? "" : "cursor-pointer mt-0.5"
26
40
  } flex ml-1 text-gray-500`}
27
- onClick={async () => {
28
- refreshCopyToClipboardState();
29
- await navigator.clipboard?.writeText(props.textToBeCopied);
30
- }}
31
- role="copy-to-clipboard"
41
+ onClick={handleCopy}
42
+ onKeyDown={handleKeyDown}
43
+ role="button"
44
+ tabIndex={0}
45
+ aria-label={
46
+ copiedToClipboard ? "Copied to clipboard" : "Copy to clipboard"
47
+ }
48
+ aria-live="polite"
32
49
  >
33
50
  {" "}
34
51
  {copiedToClipboard ? (
@@ -395,7 +395,7 @@ const Detail: DetailFunction = <T extends GenericObject>(
395
395
  style={{
396
396
  height: "100px",
397
397
  }}
398
- alt=""
398
+ alt={field.title ? `${field.title} image` : "Uploaded image"}
399
399
  />
400
400
  </div>
401
401
  </div>
@@ -2,6 +2,7 @@ import ObjectID from "../../../Types/ObjectID";
2
2
  import React, {
3
3
  FunctionComponent,
4
4
  ReactElement,
5
+ useId,
5
6
  useLayoutEffect,
6
7
  useRef,
7
8
  useState,
@@ -51,11 +52,15 @@ export interface ComponentProps {
51
52
  error?: string | undefined;
52
53
  id?: string | undefined;
53
54
  dataTestId?: string | undefined;
55
+ ariaLabel?: string | undefined;
54
56
  }
55
57
 
56
58
  const Dropdown: FunctionComponent<ComponentProps> = (
57
59
  props: ComponentProps,
58
60
  ): ReactElement => {
61
+ const uniqueId: string = useId();
62
+ const errorId: string = `dropdown-error-${uniqueId}`;
63
+
59
64
  type GetDropdownOptionFromValueFunctionProps =
60
65
  | undefined
61
66
  | DropdownValue
@@ -497,6 +502,9 @@ const Dropdown: FunctionComponent<ComponentProps> = (
497
502
  onFocus={() => {
498
503
  props.onFocus?.();
499
504
  }}
505
+ aria-label={props.ariaLabel}
506
+ aria-invalid={props.error ? true : undefined}
507
+ aria-describedby={props.error ? errorId : undefined}
500
508
  classNames={{
501
509
  control: (
502
510
  state: ControlProps<DropdownOption, boolean, GroupBase<any>>,
@@ -699,7 +707,12 @@ const Dropdown: FunctionComponent<ComponentProps> = (
699
707
  }}
700
708
  />
701
709
  {props.error && (
702
- <p data-testid="error-message" className="mt-1 text-sm text-red-400">
710
+ <p
711
+ id={errorId}
712
+ data-testid="error-message"
713
+ className="mt-1 text-sm text-red-400"
714
+ role="alert"
715
+ >
703
716
  {props.error}
704
717
  </p>
705
718
  )}
@@ -105,6 +105,29 @@ const FormField: <T extends GenericObject>(
105
105
  }
106
106
  };
107
107
 
108
+ type GetAutoCompleteFunction = (
109
+ fieldType: FormFieldSchemaType,
110
+ ) => string | undefined;
111
+
112
+ const getAutoComplete: GetAutoCompleteFunction = (
113
+ fieldType: FormFieldSchemaType,
114
+ ): string | undefined => {
115
+ switch (fieldType) {
116
+ case FormFieldSchemaType.Email:
117
+ return "email";
118
+ case FormFieldSchemaType.Password:
119
+ return "current-password";
120
+ case FormFieldSchemaType.Phone:
121
+ return "tel";
122
+ case FormFieldSchemaType.Name:
123
+ return "name";
124
+ case FormFieldSchemaType.URL:
125
+ return "url";
126
+ default:
127
+ return undefined;
128
+ }
129
+ };
130
+
108
131
  const getFormField: GetReactElementFunction = (): ReactElement => {
109
132
  const [
110
133
  showMultiSelectCheckboxCategoryModal,
@@ -737,6 +760,11 @@ const FormField: <T extends GenericObject>(
737
760
  error={props.touched && props.error ? props.error : undefined}
738
761
  dataTestId={props.field.dataTestId}
739
762
  type={fieldType as InputType}
763
+ autoComplete={
764
+ props.field.fieldType
765
+ ? getAutoComplete(props.field.fieldType)
766
+ : undefined
767
+ }
740
768
  onChange={(value: string) => {
741
769
  onChange(value);
742
770
  props.setFieldValue(props.fieldName, value);
@@ -10,13 +10,44 @@ export interface ComponentProps {
10
10
  const FullPageModal: FunctionComponent<ComponentProps> = (
11
11
  props: ComponentProps,
12
12
  ): ReactElement => {
13
+ const handleClose: () => void = (): void => {
14
+ props.onClose?.();
15
+ };
16
+
17
+ const handleKeyDown: (event: React.KeyboardEvent) => void = (
18
+ event: React.KeyboardEvent,
19
+ ): void => {
20
+ if (event.key === "Enter" || event.key === " ") {
21
+ event.preventDefault();
22
+ handleClose();
23
+ }
24
+ };
25
+
26
+ // Handle Escape key at the modal level
27
+ React.useEffect(() => {
28
+ const handleEscapeKey: (event: KeyboardEvent) => void = (
29
+ event: KeyboardEvent,
30
+ ): void => {
31
+ if (event.key === "Escape") {
32
+ handleClose();
33
+ }
34
+ };
35
+
36
+ document.addEventListener("keydown", handleEscapeKey);
37
+ return () => {
38
+ document.removeEventListener("keydown", handleEscapeKey);
39
+ };
40
+ }, []);
41
+
13
42
  return (
14
- <div className="full-page-modal">
43
+ <div className="full-page-modal" role="dialog" aria-modal="true">
15
44
  <div
16
45
  className="margin-50 align-right"
17
- onClick={() => {
18
- props.onClose?.();
19
- }}
46
+ onClick={handleClose}
47
+ onKeyDown={handleKeyDown}
48
+ role="button"
49
+ tabIndex={0}
50
+ aria-label="Close modal"
20
51
  >
21
52
  <Icon
22
53
  icon={IconProp.Close}
@@ -40,6 +40,7 @@ export interface ComponentProps {
40
40
  autoFocus?: boolean | undefined;
41
41
  disableSpellCheck?: boolean | undefined;
42
42
  showSecondsForDateTime?: boolean | undefined;
43
+ autoComplete?: string | undefined;
43
44
  }
44
45
 
45
46
  const Input: FunctionComponent<ComponentProps> = (
@@ -156,6 +157,9 @@ const Input: FunctionComponent<ComponentProps> = (
156
157
  onClick={props.onClick}
157
158
  data-testid={props.dataTestId}
158
159
  spellCheck={!props.disableSpellCheck}
160
+ autoComplete={props.autoComplete}
161
+ aria-invalid={props.error ? "true" : undefined}
162
+ aria-describedby={props.error ? "input-error-message" : undefined}
159
163
  onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
160
164
  const value: string | Date = e.target.value;
161
165
 
@@ -205,14 +209,22 @@ const Input: FunctionComponent<ComponentProps> = (
205
209
  />
206
210
 
207
211
  {props.error && (
208
- <div className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
212
+ <div
213
+ className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3"
214
+ aria-hidden="true"
215
+ >
209
216
  <Icon icon={IconProp.ErrorSolid} className="h-5 w-5 text-red-500" />
210
217
  </div>
211
218
  )}
212
219
  </div>
213
220
 
214
221
  {props.error && (
215
- <p data-testid="error-message" className="mt-1 text-sm text-red-400">
222
+ <p
223
+ id="input-error-message"
224
+ data-testid="error-message"
225
+ className="mt-1 text-sm text-red-400"
226
+ role="alert"
227
+ >
216
228
  {props.error}
217
229
  </p>
218
230
  )}
@@ -53,6 +53,7 @@ const Link: FunctionComponent<ComponentProps> = (
53
53
  onMouseLeave={props.onMouseLeave}
54
54
  style={props.style}
55
55
  title={props.title}
56
+ aria-label={props.title}
56
57
  onAuxClick={(event: React.MouseEvent<HTMLAnchorElement>) => {
57
58
  // middle click
58
59
  if (event.button === 1) {
@@ -25,11 +25,14 @@ const Loader: FunctionComponent<ComponentProps> = ({
25
25
  if (loaderType === LoaderType.Bar) {
26
26
  return (
27
27
  <div
28
- role="presentation"
28
+ role="status"
29
+ aria-label="Loading"
30
+ aria-live="polite"
29
31
  className={`flex justify-center mt-1 ${className}`.trim()}
30
32
  data-testid="bar-loader"
31
33
  >
32
34
  <BarLoader height={4} width={size} color={color.toString()} />
35
+ <span className="sr-only">Loading...</span>
33
36
  </div>
34
37
  );
35
38
  }
@@ -37,11 +40,14 @@ const Loader: FunctionComponent<ComponentProps> = ({
37
40
  if (loaderType === LoaderType.Beats) {
38
41
  return (
39
42
  <div
40
- role="presentation"
43
+ role="status"
44
+ aria-label="Loading"
45
+ aria-live="polite"
41
46
  className={`justify-center mt-1 ${className}`.trim()}
42
47
  data-testid="beat-loader"
43
48
  >
44
49
  <BeatLoader size={size} color={color.toString()} />
50
+ <span className="sr-only">Loading...</span>
45
51
  </div>
46
52
  );
47
53
  }
@@ -1,10 +1,70 @@
1
- import React, { FunctionComponent, ReactElement } from "react";
1
+ import React, {
2
+ FunctionComponent,
3
+ ReactElement,
4
+ useEffect,
5
+ useRef,
6
+ } from "react";
2
7
  // https://github.com/remarkjs/react-markdown
3
8
  import ReactMarkdown from "react-markdown";
4
9
  // https://github.com/remarkjs/remark-gfm
5
10
  import remarkGfm from "remark-gfm";
6
11
  import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
7
12
  import { a11yDark } from "react-syntax-highlighter/dist/esm/styles/prism";
13
+ import mermaid from "mermaid";
14
+
15
+ // Initialize mermaid
16
+ mermaid.initialize({
17
+ startOnLoad: false,
18
+ theme: "default",
19
+ securityLevel: "loose",
20
+ fontFamily: "inherit",
21
+ themeVariables: {
22
+ background: "#ffffff",
23
+ primaryColor: "#e0f2fe",
24
+ primaryTextColor: "#1e293b",
25
+ primaryBorderColor: "#0ea5e9",
26
+ lineColor: "#64748b",
27
+ secondaryColor: "#f1f5f9",
28
+ tertiaryColor: "#ffffff",
29
+ },
30
+ });
31
+
32
+ // Mermaid diagram component
33
+ const MermaidDiagram: FunctionComponent<{ chart: string }> = ({
34
+ chart,
35
+ }: {
36
+ chart: string;
37
+ }) => {
38
+ const containerRef: React.RefObject<HTMLDivElement | null> =
39
+ useRef<HTMLDivElement>(null);
40
+
41
+ useEffect(() => {
42
+ const renderDiagram: () => Promise<void> = async (): Promise<void> => {
43
+ if (containerRef.current) {
44
+ containerRef.current.innerHTML = "";
45
+ try {
46
+ const id: string = `mermaid-${Math.random().toString(36).substr(2, 9)}`;
47
+ const { svg } = await mermaid.render(id, chart);
48
+ if (containerRef.current) {
49
+ containerRef.current.innerHTML = svg;
50
+ }
51
+ } catch (error) {
52
+ if (containerRef.current) {
53
+ containerRef.current.innerHTML = `<pre class="text-red-500">Error rendering diagram: ${error}</pre>`;
54
+ }
55
+ }
56
+ }
57
+ };
58
+ renderDiagram();
59
+ }, [chart]);
60
+
61
+ return (
62
+ <div
63
+ ref={containerRef}
64
+ className="my-4 flex justify-center bg-white p-4 rounded-lg"
65
+ />
66
+ );
67
+ };
8
68
 
9
69
  export interface ComponentProps {
10
70
  text: string;
@@ -84,6 +144,16 @@ const MarkdownViewer: FunctionComponent<ComponentProps> = (
84
144
  },
85
145
 
86
146
  pre: ({ children, ...rest }: any) => {
147
+ // Check if this is a mermaid diagram - don't render pre wrapper for mermaid
148
+ const isMermaid: boolean =
149
+ React.isValidElement(children) &&
150
+ (children as any).props?.className?.includes("language-mermaid");
151
+
152
+ if (isMermaid) {
153
+ // For mermaid, just return the children (MermaidDiagram component)
154
+ return <>{children}</>;
155
+ }
156
+
87
157
  // Avoid double borders when SyntaxHighlighter is already styling the block.
88
158
  const isSyntaxHighlighter: boolean =
89
159
  React.isValidElement(children) &&
@@ -184,6 +254,11 @@ const MarkdownViewer: FunctionComponent<ComponentProps> = (
184
254
  "",
185
255
  );
186
256
 
257
+ // Handle mermaid diagrams
258
+ if (match && match[1] === "mermaid") {
259
+ return <MermaidDiagram chart={content} />;
260
+ }
261
+
187
262
  const codeClassName: string =
188
263
  content.includes("\n") ||
189
264
  (match &&
@@ -6,7 +6,12 @@ import ModalBody from "./ModalBody";
6
6
  import ModalFooter from "./ModalFooter";
7
7
  import { VeryLightGray } from "../../../Types/BrandColors";
8
8
  import IconProp from "../../../Types/Icon/IconProp";
9
- import React, { FunctionComponent, ReactElement } from "react";
9
+ import React, {
10
+ FunctionComponent,
11
+ ReactElement,
12
+ useEffect,
13
+ useRef,
14
+ } from "react";
10
15
 
11
16
  export enum ModalWidth {
12
17
  Normal,
@@ -38,6 +43,42 @@ export interface ComponentProps {
38
43
  const Modal: FunctionComponent<ComponentProps> = (
39
44
  props: ComponentProps,
40
45
  ): ReactElement => {
46
+ const modalRef: React.RefObject<HTMLDivElement> =
47
+ useRef<HTMLDivElement>(null);
48
+
49
+ // Handle Escape key to close modal
50
+ useEffect(() => {
51
+ const handleEscapeKey: (event: KeyboardEvent) => void = (
52
+ event: KeyboardEvent,
53
+ ): void => {
54
+ if (event.key === "Escape" && props.onClose) {
55
+ props.onClose();
56
+ }
57
+ };
58
+
59
+ document.addEventListener("keydown", handleEscapeKey);
60
+ return () => {
61
+ document.removeEventListener("keydown", handleEscapeKey);
62
+ };
63
+ }, [props.onClose]);
64
+
65
+ // Focus trap and initial focus
66
+ useEffect(() => {
67
+ const modal: HTMLDivElement | null = modalRef.current;
68
+ if (modal) {
69
+ // Focus the first focusable element in the modal, excluding the close button
70
+ const focusableElements: NodeListOf<Element> = modal.querySelectorAll(
71
+ 'button:not([data-testid="close-button"]), [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
72
+ );
73
+ const firstFocusable: HTMLElement | undefined = focusableElements[0] as
74
+ | HTMLElement
75
+ | undefined;
76
+ if (firstFocusable) {
77
+ firstFocusable.focus();
78
+ }
79
+ }
80
+ }, []);
81
+
41
82
  let iconBgColor: string = "bg-indigo-100";
42
83
  let iconColor: string = "text-indigo-600";
43
84
 
@@ -57,8 +98,10 @@ const Modal: FunctionComponent<ComponentProps> = (
57
98
 
58
99
  return (
59
100
  <div
101
+ ref={modalRef}
60
102
  className="relative z-20"
61
103
  aria-labelledby="modal-title"
104
+ aria-describedby={props.description ? "modal-description" : undefined}
62
105
  role="dialog"
63
106
  aria-modal="true"
64
107
  >
@@ -122,12 +165,13 @@ const Modal: FunctionComponent<ComponentProps> = (
122
165
  {props.title}
123
166
  </h3>
124
167
  {props.description && (
125
- <h3
168
+ <p
169
+ id="modal-description"
126
170
  data-testid="modal-description"
127
171
  className="text-sm leading-6 text-gray-500 mt-2"
128
172
  >
129
173
  {props.description}
130
- </h3>
174
+ </p>
131
175
  )}
132
176
  </div>
133
177
  {props.rightElement && (
@@ -36,7 +36,8 @@ import FormValues from "../Forms/Types/FormValues";
36
36
  import List from "../List/List";
37
37
  import { ListDetailProps } from "../List/ListRow";
38
38
  import ConfirmModal from "../Modal/ConfirmModal";
39
- import { ModalWidth } from "../Modal/Modal";
39
+ import Modal, { ModalWidth } from "../Modal/Modal";
40
+ import MarkdownViewer from "../Markdown.tsx/MarkdownViewer";
40
41
  import Filter from "../ModelFilter/Filter";
41
42
  import { DropdownOption, DropdownOptionLabel } from "../Dropdown/Dropdown";
42
43
  import OrderedStatesList from "../OrderedStatesList/OrderedStatesList";
@@ -153,6 +154,13 @@ export interface BaseTableProps<
153
154
  | undefined
154
155
  | ((data: Array<TBaseModel>, totalCount: number) => void);
155
156
  cardProps?: CardComponentProps | undefined;
157
+ helpContent?:
158
+ | {
159
+ title: string;
160
+ description?: string | undefined;
161
+ markdown: string;
162
+ }
163
+ | undefined;
156
164
  documentationLink?: Route | URL | undefined;
157
165
  videoLink?: Route | URL | undefined;
158
166
  showCreateForm?: undefined | boolean;
@@ -279,6 +287,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
279
287
  );
280
288
 
281
289
  const [showViewIdModal, setShowViewIdModal] = useState<boolean>(false);
290
+ const [showHelpModal, setShowHelpModal] = useState<boolean>(false);
282
291
  const [viewId, setViewId] = useState<string | null>(null);
283
292
  const [tableColumns, setColumns] = useState<Array<TableColumn<TBaseModel>>>(
284
293
  [],
@@ -1046,6 +1055,19 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
1046
1055
  });
1047
1056
  }
1048
1057
 
1058
+ // Add help content button if provided
1059
+ if (props.helpContent) {
1060
+ headerbuttons.push({
1061
+ title: "",
1062
+ icon: IconProp.Help,
1063
+ buttonStyle: ButtonStyleType.ICON,
1064
+ className: "py-0 pr-0 pl-1 mt-1",
1065
+ onClick: () => {
1066
+ setShowHelpModal(true);
1067
+ },
1068
+ });
1069
+ }
1070
+
1049
1071
  // Add video link button if provided
1050
1072
  if (props.videoLink) {
1051
1073
  headerbuttons.push({
@@ -2105,6 +2127,25 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
2105
2127
  closeButtonType={ButtonStyleType.OUTLINE}
2106
2128
  />
2107
2129
  )}
2130
+
2131
+ {showHelpModal && props.helpContent && (
2132
+ <Modal
2133
+ title={props.helpContent.title}
2134
+ description={props.helpContent.description}
2135
+ onClose={() => {
2136
+ setShowHelpModal(false);
2137
+ }}
2138
+ modalWidth={ModalWidth.Large}
2139
+ submitButtonText="Close"
2140
+ onSubmit={() => {
2141
+ setShowHelpModal(false);
2142
+ }}
2143
+ >
2144
+ <div className="p-2">
2145
+ <MarkdownViewer text={props.helpContent.markdown} />
2146
+ </div>
2147
+ </Modal>
2148
+ )}
2108
2149
  </>
2109
2150
  );
2110
2151
  };