@oneuptime/common 11.7.1 → 11.7.3

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 (285) hide show
  1. package/Models/AnalyticsModels/KubernetesCostAllocation.ts +103 -0
  2. package/Models/DatabaseModels/DashboardDomain.ts +1 -0
  3. package/Models/DatabaseModels/Incident.ts +2 -0
  4. package/Models/DatabaseModels/IncidentEpisode.ts +1 -0
  5. package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +1 -0
  6. package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
  7. package/Models/DatabaseModels/IncidentPublicNote.ts +1 -0
  8. package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
  9. package/Models/DatabaseModels/Monitor.ts +1 -0
  10. package/Models/DatabaseModels/MonitorStatusTimeline.ts +1 -0
  11. package/Models/DatabaseModels/NetworkSite.ts +1 -0
  12. package/Models/DatabaseModels/NetworkSiteStatusTimeline.ts +1 -0
  13. package/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.ts +1 -0
  14. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +2 -0
  15. package/Models/DatabaseModels/Probe.ts +13 -13
  16. package/Models/DatabaseModels/ScheduledMaintenance.ts +1 -0
  17. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +1 -0
  18. package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
  19. package/Models/DatabaseModels/ScheduledMaintenanceTemplate.ts +1 -0
  20. package/Models/DatabaseModels/StatusPage.ts +1 -0
  21. package/Models/DatabaseModels/StatusPageAnnouncement.ts +1 -0
  22. package/Models/DatabaseModels/StatusPageDomain.ts +1 -0
  23. package/Models/DatabaseModels/TableView.ts +40 -0
  24. package/Models/DatabaseModels/WorkspaceNotificationSummary.ts +1 -0
  25. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +11 -0
  26. package/Server/API/BaseAPI.ts +17 -1
  27. package/Server/API/CommonAPI.ts +32 -0
  28. package/Server/API/MicrosoftTeamsAPI.ts +99 -2
  29. package/Server/API/ProbeAPI.ts +2 -0
  30. package/Server/API/SlackAPI.ts +62 -0
  31. package/Server/API/StatusPageAPI.ts +157 -192
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1785140242697-AddHotQueryIndexes.ts +89 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1785148065137-AddHotQueryIndexesSecondPass.ts +61 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1785240000000-RepairCrossProjectMonitorStatusReferences.ts +280 -0
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.ts +13 -0
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  37. package/Server/Services/DatabaseService.ts +11 -3
  38. package/Server/Services/MonitorGroupService.ts +145 -0
  39. package/Server/Services/MonitorService.ts +231 -30
  40. package/Server/Services/ProbeService.ts +319 -16
  41. package/Server/Services/StatusPageService.ts +72 -42
  42. package/Server/Services/WorkspaceNotificationRuleService.ts +232 -2
  43. package/Server/Utils/Database/PostgresErrorTranslator.ts +131 -0
  44. package/Server/Utils/Monitor/MonitorResource.ts +88 -35
  45. package/Server/Utils/Monitor/MonitorStatusTimeline.ts +21 -1
  46. package/Server/Utils/Monitor/MonitorStepsProjectValidator.ts +158 -0
  47. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +706 -6
  48. package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +16 -0
  49. package/Tests/Models/DatabaseModels/ProbeColumnAccessControl.test.ts +103 -0
  50. package/Tests/Server/API/BaseAPIUpdateNoOp.test.ts +135 -0
  51. package/Tests/Server/API/CommonAPIAuthGuard.test.ts +317 -0
  52. package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +228 -0
  53. package/Tests/Server/API/ProbeAPI.test.ts +6 -0
  54. package/Tests/Server/API/ZZVerifyChatsAuth.test.ts +167 -0
  55. package/Tests/Server/Services/AddHotQueryIndexesMigration.test.ts +255 -0
  56. package/Tests/Server/Services/AddHotQueryIndexesSecondPassMigration.test.ts +258 -0
  57. package/Tests/Server/Services/DatabaseServiceSanitizeUpdateData.test.ts +1 -1
  58. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +121 -0
  59. package/Tests/Server/Services/HeartbeatWriteFastPathSafety.test.ts +200 -0
  60. package/Tests/Server/Services/HookFreeWriteSafetySecondPass.test.ts +181 -0
  61. package/Tests/Server/Services/MonitorGroupServiceBatchedStatuses.test.ts +513 -0
  62. package/Tests/Server/Services/MonitorResourceProbeAgreementReuse.test.ts +492 -0
  63. package/Tests/Server/Services/MonitorServiceProbeSelection.test.ts +401 -0
  64. package/Tests/Server/Services/MonitorStatusTimelineFastPath.test.ts +453 -0
  65. package/Tests/Server/Services/ProbeAuthKeyCacheAndHeartbeat.test.ts +679 -0
  66. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +3 -3
  67. package/Tests/Server/Services/StatusPageDomainResolutionCache.test.ts +245 -0
  68. package/Tests/Server/Services/StatusPageOverviewTimelineWindow.test.ts +283 -0
  69. package/Tests/Server/Services/StatusPageServiceMcp.test.ts +17 -1
  70. package/Tests/Server/Services/StatusPageServiceMonitorGroupBatching.test.ts +331 -0
  71. package/Tests/Server/Services/UserOnCallLogClaimNotificationRule.test.ts +12 -12
  72. package/Tests/Server/Services/WorkspaceNotificationRuleChats.test.ts +1390 -0
  73. package/Tests/Server/Utils/AI/Insights/InsightFixRouting.test.ts +4 -4
  74. package/Tests/Server/Utils/AI/Insights/InsightScanner.test.ts +2 -2
  75. package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +1 -3
  76. package/Tests/Server/Utils/AI/Insights/InsightStoreHardening.test.ts +1 -3
  77. package/Tests/Server/Utils/AI/Insights/InsightTriage.test.ts +1 -1
  78. package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +5 -5
  79. package/Tests/Server/Utils/Alert/AlertPrivacyFilter.test.ts +187 -0
  80. package/Tests/Server/Utils/AlertEpisode/AlertEpisodePrivacyFilter.test.ts +170 -0
  81. package/Tests/Server/Utils/Database/PostgresErrorTranslator.test.ts +125 -0
  82. package/Tests/Server/Utils/Incident/IncidentPrivacyFilter.test.ts +264 -0
  83. package/Tests/Server/Utils/IncidentEpisode/IncidentEpisodePrivacyFilter.test.ts +175 -0
  84. package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidator.test.ts +181 -0
  85. package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +1 -1
  86. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +2 -2
  87. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelsList.test.ts +341 -0
  88. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +2175 -0
  89. package/Tests/Server/Utils/Workspace/SlackChannelsList.test.ts +585 -0
  90. package/Tests/Types/Billing/MeteredPlan.test.ts +46 -0
  91. package/Tests/Types/JSONFunctions.test.ts +103 -1
  92. package/Tests/Types/Workspace/NotificationRules/NotificationRuleCondition.test.ts +219 -1
  93. package/Tests/UI/Components/BulkUpdateForm.test.tsx +174 -0
  94. package/Tests/UI/Components/CardModelDetailEdit.test.tsx +315 -0
  95. package/Tests/UI/Components/ModelDetailSelect.test.tsx +229 -0
  96. package/Tests/UI/Components/ModelTable/BaseModelTableBulkSelectAll.test.tsx +1258 -0
  97. package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +679 -0
  98. package/Tests/UI/Components/ModelTable/ColumnCustomizationModal.test.tsx +572 -0
  99. package/Tests/UI/Components/ModelTable/ColumnPreference.test.ts +1678 -0
  100. package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1094 -0
  101. package/Tests/UI/Components/ModelTableExportFromColumns.test.ts +153 -0
  102. package/Tests/UI/Components/MonacoLoader.test.ts +67 -0
  103. package/Tests/UI/Components/MonacoRuntime.test.ts +121 -0
  104. package/Tests/UI/Components/TableBulkCsvExport.test.tsx +212 -3
  105. package/Tests/UI/Utils/Project.test.ts +809 -0
  106. package/Tests/UI/Utils/TableColumnsToCsv.test.ts +360 -0
  107. package/Tests/Utils/Alerts/AlertMetricType.test.ts +143 -0
  108. package/Tests/Utils/Dashboard/VariableUrlState.test.ts +219 -0
  109. package/Tests/Utils/Incident/IncidentMetricType.test.ts +174 -0
  110. package/Tests/Utils/Monitor/MonitorProbeSelectionUtil.test.ts +145 -0
  111. package/Tests/Utils/StatusPage/ResourceUptime.test.ts +263 -0
  112. package/Tests/Utils/UserPreferences.test.ts +563 -0
  113. package/Types/JSONFunctions.ts +7 -2
  114. package/Types/Kubernetes/KubernetesCostIngest.ts +37 -1
  115. package/Types/Workspace/NotificationRules/BaseNotificationRule.ts +4 -0
  116. package/Types/Workspace/NotificationRules/NotificationRuleCondition.ts +25 -10
  117. package/Types/Workspace/WorkspaceMessagePayload.ts +1 -0
  118. package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +63 -8
  119. package/UI/Components/CodeEditor/CodeEditor.tsx +3 -0
  120. package/UI/Components/CodeEditor/MonacoLoader.ts +36 -0
  121. package/UI/Components/Forms/ModelForm.tsx +41 -18
  122. package/UI/Components/MasterPage/MasterPage.tsx +65 -0
  123. package/UI/Components/ModelDetail/CardModelDetail.tsx +23 -1
  124. package/UI/Components/ModelDetail/ModelDetail.tsx +46 -1
  125. package/UI/Components/ModelTable/BaseModelTable.tsx +687 -34
  126. package/UI/Components/ModelTable/Column.ts +29 -0
  127. package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +420 -0
  128. package/UI/Components/ModelTable/ColumnPreference.ts +482 -0
  129. package/UI/Components/ModelTable/CustomFieldColumns.tsx +326 -0
  130. package/UI/Components/ModelTable/ExportFromColumns.ts +57 -0
  131. package/UI/Components/ModelTable/TableView.tsx +24 -2
  132. package/UI/Components/ModelTable/useCustomFieldColumns.ts +150 -0
  133. package/UI/Components/Navbar/NavBar.tsx +66 -1
  134. package/UI/Components/SideMenu/SideMenu.tsx +24 -4
  135. package/UI/Components/Table/Table.tsx +66 -14
  136. package/UI/Components/Table/TableRow.tsx +180 -175
  137. package/UI/Components/Table/Types/Column.ts +20 -0
  138. package/UI/Utils/Project.ts +214 -18
  139. package/UI/Utils/TableColumnsToCsv.ts +86 -6
  140. package/UI/esbuild-config.js +34 -0
  141. package/Utils/Monitor/MonitorProbeSelectionUtil.ts +72 -0
  142. package/Utils/UserPreferences.ts +53 -0
  143. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +86 -0
  144. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -1
  145. package/build/dist/Models/DatabaseModels/DashboardDomain.js +1 -0
  146. package/build/dist/Models/DatabaseModels/DashboardDomain.js.map +1 -1
  147. package/build/dist/Models/DatabaseModels/Incident.js +2 -0
  148. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  149. package/build/dist/Models/DatabaseModels/IncidentEpisode.js +1 -0
  150. package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
  151. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +1 -0
  152. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
  153. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
  154. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
  155. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +1 -0
  156. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  157. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
  158. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  159. package/build/dist/Models/DatabaseModels/Monitor.js +1 -0
  160. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  161. package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js +1 -0
  162. package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js.map +1 -1
  163. package/build/dist/Models/DatabaseModels/NetworkSite.js +1 -0
  164. package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -1
  165. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js +1 -0
  166. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js.map +1 -1
  167. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js +1 -0
  168. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js.map +1 -1
  169. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +2 -0
  170. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  171. package/build/dist/Models/DatabaseModels/Probe.js +13 -13
  172. package/build/dist/Models/DatabaseModels/Probe.js.map +1 -1
  173. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +1 -0
  174. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  175. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +1 -0
  176. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  177. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
  178. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
  179. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js +1 -0
  180. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js.map +1 -1
  181. package/build/dist/Models/DatabaseModels/StatusPage.js +1 -0
  182. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  183. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +1 -0
  184. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  185. package/build/dist/Models/DatabaseModels/StatusPageDomain.js +1 -0
  186. package/build/dist/Models/DatabaseModels/StatusPageDomain.js.map +1 -1
  187. package/build/dist/Models/DatabaseModels/TableView.js +40 -0
  188. package/build/dist/Models/DatabaseModels/TableView.js.map +1 -1
  189. package/build/dist/Models/DatabaseModels/WorkspaceNotificationSummary.js +1 -0
  190. package/build/dist/Models/DatabaseModels/WorkspaceNotificationSummary.js.map +1 -1
  191. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  192. package/build/dist/Server/API/BaseAPI.js +12 -1
  193. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  194. package/build/dist/Server/API/CommonAPI.js +21 -0
  195. package/build/dist/Server/API/CommonAPI.js.map +1 -1
  196. package/build/dist/Server/API/MicrosoftTeamsAPI.js +72 -2
  197. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  198. package/build/dist/Server/API/ProbeAPI.js +2 -0
  199. package/build/dist/Server/API/ProbeAPI.js.map +1 -1
  200. package/build/dist/Server/API/SlackAPI.js +44 -0
  201. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  202. package/build/dist/Server/API/StatusPageAPI.js +98 -152
  203. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  204. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785140242697-AddHotQueryIndexes.js +36 -0
  205. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785140242697-AddHotQueryIndexes.js.map +1 -0
  206. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785148065137-AddHotQueryIndexesSecondPass.js +26 -0
  207. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785148065137-AddHotQueryIndexesSecondPass.js.map +1 -0
  208. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785240000000-RepairCrossProjectMonitorStatusReferences.js +254 -0
  209. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785240000000-RepairCrossProjectMonitorStatusReferences.js.map +1 -0
  210. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js +12 -0
  211. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js.map +1 -0
  212. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  213. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  214. package/build/dist/Server/Services/DatabaseService.js +10 -2
  215. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  216. package/build/dist/Server/Services/MonitorGroupService.js +118 -0
  217. package/build/dist/Server/Services/MonitorGroupService.js.map +1 -1
  218. package/build/dist/Server/Services/MonitorService.js +198 -24
  219. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  220. package/build/dist/Server/Services/ProbeService.js +238 -9
  221. package/build/dist/Server/Services/ProbeService.js.map +1 -1
  222. package/build/dist/Server/Services/StatusPageService.js +46 -39
  223. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  224. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +178 -3
  225. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  226. package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js +80 -0
  227. package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js.map +1 -0
  228. package/build/dist/Server/Utils/Monitor/MonitorResource.js +67 -29
  229. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  230. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js +31 -14
  231. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js.map +1 -1
  232. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js +117 -0
  233. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js.map +1 -0
  234. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +549 -7
  235. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  236. package/build/dist/Types/JSONFunctions.js +8 -3
  237. package/build/dist/Types/JSONFunctions.js.map +1 -1
  238. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -1
  239. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js +17 -7
  240. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js.map +1 -1
  241. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +37 -11
  242. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
  243. package/build/dist/UI/Components/CodeEditor/CodeEditor.js +2 -0
  244. package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
  245. package/build/dist/UI/Components/CodeEditor/MonacoLoader.js +34 -0
  246. package/build/dist/UI/Components/CodeEditor/MonacoLoader.js.map +1 -0
  247. package/build/dist/UI/Components/Forms/ModelForm.js +37 -17
  248. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  249. package/build/dist/UI/Components/MasterPage/MasterPage.js +50 -1
  250. package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
  251. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +22 -1
  252. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  253. package/build/dist/UI/Components/ModelDetail/ModelDetail.js +31 -1
  254. package/build/dist/UI/Components/ModelDetail/ModelDetail.js.map +1 -1
  255. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +472 -27
  256. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  257. package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +189 -0
  258. package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -0
  259. package/build/dist/UI/Components/ModelTable/ColumnPreference.js +258 -0
  260. package/build/dist/UI/Components/ModelTable/ColumnPreference.js.map +1 -0
  261. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +168 -0
  262. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -0
  263. package/build/dist/UI/Components/ModelTable/ExportFromColumns.js +30 -0
  264. package/build/dist/UI/Components/ModelTable/ExportFromColumns.js.map +1 -0
  265. package/build/dist/UI/Components/ModelTable/TableView.js +13 -2
  266. package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
  267. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +84 -0
  268. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -0
  269. package/build/dist/UI/Components/Navbar/NavBar.js +39 -1
  270. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  271. package/build/dist/UI/Components/SideMenu/SideMenu.js +15 -5
  272. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  273. package/build/dist/UI/Components/Table/Table.js +46 -13
  274. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  275. package/build/dist/UI/Components/Table/TableRow.js +11 -6
  276. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  277. package/build/dist/UI/Utils/Project.js +161 -15
  278. package/build/dist/UI/Utils/Project.js.map +1 -1
  279. package/build/dist/UI/Utils/TableColumnsToCsv.js +67 -6
  280. package/build/dist/UI/Utils/TableColumnsToCsv.js.map +1 -1
  281. package/build/dist/Utils/Monitor/MonitorProbeSelectionUtil.js +52 -0
  282. package/build/dist/Utils/Monitor/MonitorProbeSelectionUtil.js.map +1 -0
  283. package/build/dist/Utils/UserPreferences.js +33 -0
  284. package/build/dist/Utils/UserPreferences.js.map +1 -1
  285. package/package.json +4 -3
@@ -6,6 +6,7 @@ import Columns from "../../../UI/Components/Table/Types/Columns";
6
6
  import FieldType from "../../../UI/Components/Types/FieldType";
7
7
  import OneUptimeDate from "../../../Types/Date";
8
8
  import ObjectID from "../../../Types/ObjectID";
9
+ import { createElement, ReactElement } from "react";
9
10
 
10
11
  /*
11
12
  * Concrete row shape used across the tests. A real ModelTable passes model
@@ -20,8 +21,23 @@ interface Row {
20
21
  label?: { name?: string } | null | undefined;
21
22
  severityText?: string | undefined;
22
23
  _id?: string | undefined;
24
+ description?: string | undefined;
25
+ hosts?: Array<{ name: string }> | undefined;
26
+ services?: Array<{ name: string }> | undefined;
27
+ monitors?: Array<{ name: string }> | undefined;
23
28
  }
24
29
 
30
+ /*
31
+ * The exporter never calls getElement - it only cares whether a column has
32
+ * one, because that is what makes a `_id` column a placeholder rather than an
33
+ * id the user asked to see.
34
+ */
35
+ type RenderCellFunction = () => ReactElement;
36
+
37
+ const renderCell: RenderCellFunction = (): ReactElement => {
38
+ return createElement("span");
39
+ };
40
+
25
41
  describe("TableColumnsToCsv", () => {
26
42
  describe("escapeCsvValue", () => {
27
43
  test("leaves a plain value untouched", () => {
@@ -321,6 +337,192 @@ describe("TableColumnsToCsv", () => {
321
337
  ),
322
338
  ).toEqual([]);
323
339
  });
340
+
341
+ test("excludes a placeholder _id column such as Owners", () => {
342
+ /*
343
+ * The "Owners" column on alerts / incidents / monitors renders entirely
344
+ * through getElement and only declares `field: { _id: true }` so the row
345
+ * gets fetched. Exporting it wrote a raw UUID under the header "Owners".
346
+ */
347
+ const result: Columns<Row> = TableColumnsToCsv.getExportableColumns([
348
+ { title: "Name", type: FieldType.Text, key: "name" },
349
+ {
350
+ title: "Owners",
351
+ type: FieldType.Element,
352
+ key: "_id",
353
+ exportKeys: ["_id"],
354
+ getElement: renderCell,
355
+ },
356
+ ]);
357
+
358
+ expect(
359
+ result.map((c: Column<Row>) => {
360
+ return c.title;
361
+ }),
362
+ ).toEqual(["Name"]);
363
+ });
364
+
365
+ test("keeps an _id column that genuinely shows the id", () => {
366
+ // FieldType.ObjectID is how a column says the id IS the value.
367
+ const result: Columns<Row> = TableColumnsToCsv.getExportableColumns([
368
+ {
369
+ title: "Execution ID",
370
+ type: FieldType.ObjectID,
371
+ key: "_id",
372
+ exportKeys: ["_id"],
373
+ getElement: renderCell,
374
+ },
375
+ ]);
376
+
377
+ expect(result.length).toBe(1);
378
+ });
379
+
380
+ test("keeps an _id column that has no getElement", () => {
381
+ const result: Columns<Row> = TableColumnsToCsv.getExportableColumns([
382
+ { title: "ID", type: FieldType.Text, key: "_id", exportKeys: ["_id"] },
383
+ ]);
384
+
385
+ expect(result.length).toBe(1);
386
+ });
387
+
388
+ test("keeps an _id column that declares other fields alongside it", () => {
389
+ const result: Columns<Row> = TableColumnsToCsv.getExportableColumns([
390
+ {
391
+ title: "Resource",
392
+ type: FieldType.Element,
393
+ key: "_id",
394
+ exportKeys: ["_id", "name"],
395
+ getElement: renderCell,
396
+ },
397
+ ]);
398
+
399
+ expect(result.length).toBe(1);
400
+ });
401
+
402
+ test("excludes a column that opted out with disableCsvExport", () => {
403
+ const result: Columns<Row> = TableColumnsToCsv.getExportableColumns([
404
+ { title: "Name", type: FieldType.Text, key: "name" },
405
+ {
406
+ title: "Status",
407
+ type: FieldType.Text,
408
+ key: "status",
409
+ disableCsvExport: true,
410
+ },
411
+ ]);
412
+
413
+ expect(
414
+ result.map((c: Column<Row>) => {
415
+ return c.title;
416
+ }),
417
+ ).toEqual(["Name"]);
418
+ });
419
+
420
+ test("keeps a keyless column that supplies its own export value", () => {
421
+ const result: Columns<Row> = TableColumnsToCsv.getExportableColumns([
422
+ {
423
+ title: "Owners",
424
+ type: FieldType.Element,
425
+ getExportValue: (): string => {
426
+ return "someone";
427
+ },
428
+ },
429
+ ]);
430
+
431
+ expect(result.length).toBe(1);
432
+ });
433
+
434
+ test("disableCsvExport wins over an explicit export value", () => {
435
+ const result: Columns<Row> = TableColumnsToCsv.getExportableColumns([
436
+ {
437
+ title: "Owners",
438
+ type: FieldType.Element,
439
+ key: "_id",
440
+ disableCsvExport: true,
441
+ getExportValue: (): string => {
442
+ return "someone";
443
+ },
444
+ },
445
+ ]);
446
+
447
+ expect(result).toEqual([]);
448
+ });
449
+ });
450
+
451
+ describe("getExportKeys", () => {
452
+ test("falls back to the single column key", () => {
453
+ expect(
454
+ TableColumnsToCsv.getExportKeys<Row>({
455
+ title: "Name",
456
+ type: FieldType.Text,
457
+ key: "name",
458
+ }),
459
+ ).toEqual(["name"]);
460
+ });
461
+
462
+ test("returns every declared key when exportKeys is set", () => {
463
+ expect(
464
+ TableColumnsToCsv.getExportKeys<Row>({
465
+ title: "Affected Resources",
466
+ type: FieldType.EntityArray,
467
+ key: "hosts",
468
+ exportKeys: ["hosts", "services", "monitors"],
469
+ }),
470
+ ).toEqual(["hosts", "services", "monitors"]);
471
+ });
472
+
473
+ test("returns nothing for a keyless column", () => {
474
+ expect(
475
+ TableColumnsToCsv.getExportKeys<Row>({
476
+ title: "Custom",
477
+ type: FieldType.Element,
478
+ }),
479
+ ).toEqual([]);
480
+ });
481
+ });
482
+
483
+ describe("isPlaceholderIdColumn", () => {
484
+ test("is true for an _id-only column rendered through getElement", () => {
485
+ expect(
486
+ TableColumnsToCsv.isPlaceholderIdColumn<Row>({
487
+ title: "Owners",
488
+ type: FieldType.Element,
489
+ key: "_id",
490
+ getElement: renderCell,
491
+ }),
492
+ ).toBe(true);
493
+ });
494
+
495
+ test("is false without a getElement", () => {
496
+ expect(
497
+ TableColumnsToCsv.isPlaceholderIdColumn<Row>({
498
+ title: "ID",
499
+ type: FieldType.Element,
500
+ key: "_id",
501
+ }),
502
+ ).toBe(false);
503
+ });
504
+
505
+ test("is false for FieldType.ObjectID", () => {
506
+ expect(
507
+ TableColumnsToCsv.isPlaceholderIdColumn<Row>({
508
+ title: "Run ID",
509
+ type: FieldType.ObjectID,
510
+ key: "_id",
511
+ getElement: renderCell,
512
+ }),
513
+ ).toBe(false);
514
+ });
515
+
516
+ test("is false for a column keyed on something other than _id", () => {
517
+ expect(
518
+ TableColumnsToCsv.isPlaceholderIdColumn<Row>({
519
+ title: "Name",
520
+ type: FieldType.Element,
521
+ key: "name",
522
+ getElement: renderCell,
523
+ }),
524
+ ).toBe(false);
525
+ });
324
526
  });
325
527
 
326
528
  describe("getCellValue", () => {
@@ -343,6 +545,100 @@ describe("TableColumnsToCsv", () => {
343
545
  "No",
344
546
  );
345
547
  });
548
+
549
+ test("reads every declared field, not just the first", () => {
550
+ /*
551
+ * The alert "Affected Resources" cell spans several relations at once.
552
+ * Only the first used to reach the file, so a row whose resources were
553
+ * services exported an empty cell.
554
+ */
555
+ const column: Column<Row> = {
556
+ title: "Affected Resources",
557
+ type: FieldType.EntityArray,
558
+ key: "hosts",
559
+ exportKeys: ["hosts", "services", "monitors"],
560
+ };
561
+
562
+ const item: Row = {
563
+ hosts: [{ name: "web-01" }],
564
+ services: [{ name: "checkout" }],
565
+ monitors: [{ name: "api-uptime" }],
566
+ };
567
+
568
+ expect(TableColumnsToCsv.getCellValue(item, column)).toBe(
569
+ "web-01; checkout; api-uptime",
570
+ );
571
+ });
572
+
573
+ test("skips the declared fields that are empty on this row", () => {
574
+ const column: Column<Row> = {
575
+ title: "Affected Resources",
576
+ type: FieldType.EntityArray,
577
+ key: "hosts",
578
+ exportKeys: ["hosts", "services", "monitors"],
579
+ };
580
+
581
+ expect(
582
+ TableColumnsToCsv.getCellValue(
583
+ { services: [{ name: "checkout" }] },
584
+ column,
585
+ ),
586
+ ).toBe("checkout");
587
+ });
588
+
589
+ test("does not list the same value twice across declared fields", () => {
590
+ const column: Column<Row> = {
591
+ title: "Affected Resources",
592
+ type: FieldType.EntityArray,
593
+ key: "hosts",
594
+ exportKeys: ["hosts", "services"],
595
+ };
596
+
597
+ const item: Row = {
598
+ hosts: [{ name: "shared" }],
599
+ services: [{ name: "shared" }],
600
+ };
601
+
602
+ expect(TableColumnsToCsv.getCellValue(item, column)).toBe("shared");
603
+ });
604
+
605
+ test("returns an empty cell when none of the declared fields are set", () => {
606
+ const column: Column<Row> = {
607
+ title: "Affected Resources",
608
+ type: FieldType.EntityArray,
609
+ key: "hosts",
610
+ exportKeys: ["hosts", "services"],
611
+ };
612
+
613
+ expect(TableColumnsToCsv.getCellValue({}, column)).toBe("");
614
+ });
615
+
616
+ test("uses getExportValue in preference to the row's own fields", () => {
617
+ const column: Column<Row> = {
618
+ title: "Owners",
619
+ type: FieldType.Element,
620
+ key: "_id",
621
+ getExportValue: (item: Row): string => {
622
+ return `owner of ${item.name}`;
623
+ },
624
+ };
625
+
626
+ expect(
627
+ TableColumnsToCsv.getCellValue({ _id: "abc", name: "Alpha" }, column),
628
+ ).toBe("owner of Alpha");
629
+ });
630
+
631
+ test("treats a null-ish getExportValue result as an empty cell", () => {
632
+ const column: Column<Row> = {
633
+ title: "Owners",
634
+ type: FieldType.Element,
635
+ getExportValue: (): string => {
636
+ return undefined as unknown as string;
637
+ },
638
+ };
639
+
640
+ expect(TableColumnsToCsv.getCellValue({}, column)).toBe("");
641
+ });
346
642
  });
347
643
 
348
644
  describe("convertToCsv", () => {
@@ -408,6 +704,70 @@ describe("TableColumnsToCsv", () => {
408
704
  });
409
705
  expect(csv).toBe("Name,Active");
410
706
  });
707
+
708
+ test("drops the placeholder id column and spans every relation of a multi-field column", () => {
709
+ /*
710
+ * End to end over the two shapes that used to export the wrong value: an
711
+ * "Owners" column that wrote a UUID, and an "Affected Resources" column
712
+ * that wrote only its first relation.
713
+ */
714
+ const csv: string = TableColumnsToCsv.convertToCsv({
715
+ items: [
716
+ {
717
+ _id: "b6b0f3c2-0000-0000-0000-000000000000",
718
+ name: "Alpha",
719
+ hosts: [{ name: "web-01" }],
720
+ services: [{ name: "checkout" }],
721
+ },
722
+ ],
723
+ columns: [
724
+ { title: "Name", type: FieldType.Text, key: "name" },
725
+ {
726
+ title: "Affected Resources",
727
+ type: FieldType.EntityArray,
728
+ key: "hosts",
729
+ exportKeys: ["hosts", "services"],
730
+ getElement: renderCell,
731
+ },
732
+ {
733
+ title: "Owners",
734
+ type: FieldType.Element,
735
+ key: "_id",
736
+ exportKeys: ["_id"],
737
+ getElement: renderCell,
738
+ },
739
+ ],
740
+ });
741
+
742
+ expect(csv.split("\r\n")).toEqual([
743
+ "Name,Affected Resources",
744
+ "Alpha,web-01; checkout",
745
+ ]);
746
+ });
747
+
748
+ test("an opted-in placeholder column exports its supplied value", () => {
749
+ const csv: string = TableColumnsToCsv.convertToCsv({
750
+ items: [{ _id: "1", name: "Alpha" }],
751
+ columns: [
752
+ { title: "Name", type: FieldType.Text, key: "name" },
753
+ {
754
+ title: "Owners",
755
+ type: FieldType.Element,
756
+ key: "_id",
757
+ exportKeys: ["_id"],
758
+ getElement: renderCell,
759
+ getExportValue: (): string => {
760
+ return "jane@example.com";
761
+ },
762
+ },
763
+ ],
764
+ });
765
+
766
+ expect(csv.split("\r\n")).toEqual([
767
+ "Name,Owners",
768
+ "Alpha,jane@example.com",
769
+ ]);
770
+ });
411
771
  });
412
772
 
413
773
  describe("getExportFilename", () => {
@@ -0,0 +1,143 @@
1
+ import AlertMetricTypeUtil from "../../../Utils/Alerts/AlertMetricType";
2
+ import AlertMetricType from "../../../Types/Alerts/AlertMetricType";
3
+ import AggregationType from "../../../Types/BaseDatabase/AggregationType";
4
+
5
+ describe("AlertMetricTypeUtil", () => {
6
+ describe("getAggregationTypeByAlertMetricType", () => {
7
+ test("AlertCount aggregates as Sum", () => {
8
+ expect(
9
+ AlertMetricTypeUtil.getAggregationTypeByAlertMetricType(
10
+ AlertMetricType.AlertCount,
11
+ ),
12
+ ).toBe(AggregationType.Sum);
13
+ });
14
+
15
+ test.each([
16
+ AlertMetricType.TimeToAcknowledge,
17
+ AlertMetricType.TimeToResolve,
18
+ AlertMetricType.AlertDuration,
19
+ ])("%s aggregates as Avg", (metricType: AlertMetricType) => {
20
+ expect(
21
+ AlertMetricTypeUtil.getAggregationTypeByAlertMetricType(metricType),
22
+ ).toBe(AggregationType.Avg);
23
+ });
24
+
25
+ test("throws for an unknown metric type", () => {
26
+ expect(() => {
27
+ return AlertMetricTypeUtil.getAggregationTypeByAlertMetricType(
28
+ "not-a-real-metric" as AlertMetricType,
29
+ );
30
+ }).toThrow("Invalid AlertMetricType value");
31
+ });
32
+ });
33
+
34
+ describe("getAllAlertMetricTypes", () => {
35
+ test("returns exactly the four supported metric types", () => {
36
+ expect(AlertMetricTypeUtil.getAllAlertMetricTypes()).toEqual([
37
+ AlertMetricType.AlertCount,
38
+ AlertMetricType.TimeToAcknowledge,
39
+ AlertMetricType.TimeToResolve,
40
+ AlertMetricType.AlertDuration,
41
+ ]);
42
+ });
43
+
44
+ test("every returned type resolves to a valid aggregation type", () => {
45
+ for (const metricType of AlertMetricTypeUtil.getAllAlertMetricTypes()) {
46
+ expect(() => {
47
+ return AlertMetricTypeUtil.getAggregationTypeByAlertMetricType(
48
+ metricType,
49
+ );
50
+ }).not.toThrow();
51
+ }
52
+ });
53
+ });
54
+
55
+ describe("getTitleByAlertMetricType", () => {
56
+ test.each([
57
+ [AlertMetricType.AlertCount, "Alert Count"],
58
+ [AlertMetricType.TimeToAcknowledge, "Time to Acknowledge"],
59
+ [AlertMetricType.TimeToResolve, "Time to Resolve"],
60
+ [AlertMetricType.AlertDuration, "Alert Duration"],
61
+ ])("%s -> %s", (metricType: AlertMetricType, expected: string) => {
62
+ expect(AlertMetricTypeUtil.getTitleByAlertMetricType(metricType)).toBe(
63
+ expected,
64
+ );
65
+ });
66
+
67
+ test("returns empty string for an unknown metric type", () => {
68
+ expect(
69
+ AlertMetricTypeUtil.getTitleByAlertMetricType(
70
+ "unknown" as AlertMetricType,
71
+ ),
72
+ ).toBe("");
73
+ });
74
+ });
75
+
76
+ describe("getDescriptionByAlertMetricType", () => {
77
+ test("returns a non-empty sentence for each known type", () => {
78
+ for (const metricType of AlertMetricTypeUtil.getAllAlertMetricTypes()) {
79
+ const description: string =
80
+ AlertMetricTypeUtil.getDescriptionByAlertMetricType(metricType);
81
+ expect(description.length).toBeGreaterThan(0);
82
+ expect(description.endsWith(".")).toBe(true);
83
+ }
84
+ });
85
+
86
+ test("returns empty string for an unknown metric type", () => {
87
+ expect(
88
+ AlertMetricTypeUtil.getDescriptionByAlertMetricType(
89
+ "unknown" as AlertMetricType,
90
+ ),
91
+ ).toBe("");
92
+ });
93
+ });
94
+
95
+ describe("getLegendByAlertMetricType", () => {
96
+ test.each([
97
+ [AlertMetricType.AlertCount, "Alerts"],
98
+ [AlertMetricType.TimeToAcknowledge, "Time to Acknowledge"],
99
+ [AlertMetricType.TimeToResolve, "Time to Resolve"],
100
+ [AlertMetricType.AlertDuration, "Duration"],
101
+ ])("%s -> %s", (metricType: AlertMetricType, expected: string) => {
102
+ expect(AlertMetricTypeUtil.getLegendByAlertMetricType(metricType)).toBe(
103
+ expected,
104
+ );
105
+ });
106
+
107
+ test("returns empty string for an unknown metric type", () => {
108
+ expect(
109
+ AlertMetricTypeUtil.getLegendByAlertMetricType(
110
+ "unknown" as AlertMetricType,
111
+ ),
112
+ ).toBe("");
113
+ });
114
+ });
115
+
116
+ describe("getLegendUnitByAlertMetricType", () => {
117
+ test("AlertCount has no unit", () => {
118
+ expect(
119
+ AlertMetricTypeUtil.getLegendUnitByAlertMetricType(
120
+ AlertMetricType.AlertCount,
121
+ ),
122
+ ).toBe("");
123
+ });
124
+
125
+ test.each([
126
+ AlertMetricType.TimeToAcknowledge,
127
+ AlertMetricType.TimeToResolve,
128
+ AlertMetricType.AlertDuration,
129
+ ])("%s is measured in seconds", (metricType: AlertMetricType) => {
130
+ expect(
131
+ AlertMetricTypeUtil.getLegendUnitByAlertMetricType(metricType),
132
+ ).toBe("s");
133
+ });
134
+
135
+ test("returns empty string for an unknown metric type", () => {
136
+ expect(
137
+ AlertMetricTypeUtil.getLegendUnitByAlertMetricType(
138
+ "unknown" as AlertMetricType,
139
+ ),
140
+ ).toBe("");
141
+ });
142
+ });
143
+ });