@oneuptime/common 14.0.8 → 14.0.9

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 (639) hide show
  1. package/Models/DatabaseModels/Index.ts +2 -0
  2. package/Models/DatabaseModels/KubernetesAiAgent.ts +364 -0
  3. package/Models/DatabaseModels/KubernetesCluster.ts +3 -3
  4. package/Models/DatabaseModels/Project.ts +55 -5
  5. package/Models/DatabaseModels/ProxmoxResource.ts +49 -1
  6. package/Models/DatabaseModels/RunnerJob.ts +75 -0
  7. package/Models/DatabaseModels/TeamComplianceSetting.ts +143 -2
  8. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +17 -0
  9. package/Server/API/AIChatAPI.ts +6 -3
  10. package/Server/API/AIInvestigationAPI.ts +17 -10
  11. package/Server/API/AutoRemediationAPI.ts +207 -25
  12. package/Server/API/KubernetesClusterAiAccessAPI.ts +623 -21
  13. package/Server/API/MicrosoftTeamsAPI.ts +93 -14
  14. package/Server/API/ProxmoxResourceAPI.ts +244 -14
  15. package/Server/Infrastructure/GlobalCache.ts +32 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.ts +99 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.ts +137 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.ts +42 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  20. package/Server/Middleware/TelemetryIngest.ts +41 -18
  21. package/Server/Services/AIService.ts +70 -1
  22. package/Server/Services/AlertService.ts +352 -11
  23. package/Server/Services/AlertSeverityService.ts +65 -15
  24. package/Server/Services/AutoRemediationRuleService.ts +1 -1
  25. package/Server/Services/IncidentService.ts +280 -104
  26. package/Server/Services/IncidentSeverityService.ts +66 -15
  27. package/Server/Services/KubernetesAiAgentJobService.ts +185 -0
  28. package/Server/Services/KubernetesAiAgentService.ts +1634 -0
  29. package/Server/Services/KubernetesClusterAiAccessService.ts +1118 -451
  30. package/Server/Services/KubernetesClusterService.ts +129 -21
  31. package/Server/Services/ProjectService.ts +32 -0
  32. package/Server/Services/ProxmoxResourceService.ts +322 -5
  33. package/Server/Services/RunnerJobService.ts +241 -104
  34. package/Server/Services/RunnerService.ts +1 -1
  35. package/Server/Services/ScheduledMaintenanceService.ts +737 -1
  36. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +414 -56
  37. package/Server/Services/TeamComplianceSettingService.ts +1125 -9
  38. package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +67 -9
  39. package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +39 -10
  40. package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +14 -3
  41. package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +37 -15
  42. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +67 -24
  43. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +48 -5
  44. package/Server/Utils/AI/SRE/IncidentPostmortemRunner.ts +40 -8
  45. package/Server/Utils/AI/SRE/InvestigationEligibility.ts +13 -2
  46. package/Server/Utils/AI/SRE/InvestigationGrader.ts +1 -1
  47. package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +6 -1
  48. package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +133 -7
  49. package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +58 -4
  50. package/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.ts +447 -0
  51. package/Server/Utils/Telemetry/ProxmoxNativePush.ts +903 -0
  52. package/Server/Utils/Telemetry/TelemetryEntity.ts +87 -27
  53. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +684 -47
  54. package/Tests/App/AdminDashboard/RowActionPlacementOverrides.test.tsx +278 -0
  55. package/Tests/App/Dashboard/AIChatChartWidgetZoom.test.tsx +738 -0
  56. package/Tests/App/Dashboard/AIFeaturesSettingsPointers.test.tsx +147 -0
  57. package/Tests/App/Dashboard/AIInsightsKubernetesClusterPage.test.tsx +1523 -0
  58. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +463 -3
  59. package/Tests/App/Dashboard/AffectedResourcesPickerDropdownPlacement.test.tsx +958 -0
  60. package/Tests/App/Dashboard/AffectedResourcesPickerFocusLeave.test.tsx +595 -0
  61. package/Tests/App/Dashboard/AskAiAvailability.test.ts +20 -3
  62. package/Tests/App/Dashboard/AskAiDisabled.test.tsx +8 -3
  63. package/Tests/App/Dashboard/CephRateChartReload.test.tsx +1456 -0
  64. package/Tests/App/Dashboard/CephTimeRangeZoom.test.tsx +1229 -0
  65. package/Tests/App/Dashboard/ChartCardTimeRangeZoom.test.tsx +151 -0
  66. package/Tests/App/Dashboard/ChartCardZoomAffordances.test.tsx +257 -0
  67. package/Tests/App/Dashboard/ChartRefetchFrame.test.tsx +141 -0
  68. package/Tests/App/Dashboard/ChartZoomHarness.tsx +249 -0
  69. package/Tests/App/Dashboard/ChartZoomStandIn.tsx +131 -0
  70. package/Tests/App/Dashboard/CloudServerlessSlowLoads.test.tsx +628 -0
  71. package/Tests/App/Dashboard/CloudServerlessTimeRangeZoom.test.tsx +607 -0
  72. package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +91 -19
  73. package/Tests/App/Dashboard/CompanionMetricsTabZoom.test.tsx +632 -0
  74. package/Tests/App/Dashboard/ContainerChartZoomStandIn.tsx +195 -0
  75. package/Tests/App/Dashboard/ContainerHostOverviewSlowLoads.test.tsx +542 -0
  76. package/Tests/App/Dashboard/ContainerHostOverviewTimeRangeZoom.test.tsx +848 -0
  77. package/Tests/App/Dashboard/ContainerMetricsTimeRangeZoom.test.tsx +561 -0
  78. package/Tests/App/Dashboard/DashboardBoardWideZoomShell.test.tsx +1147 -0
  79. package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +3 -2
  80. package/Tests/App/Dashboard/DashboardHistogramWidgetDragCursor.test.tsx +399 -0
  81. package/Tests/App/Dashboard/DashboardHistogramWidgetZoom.test.tsx +985 -0
  82. package/Tests/App/Dashboard/DashboardHistogramWidgetZoomHint.test.tsx +803 -0
  83. package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +1 -0
  84. package/Tests/App/Dashboard/DashboardSettingsPreviewZoom.test.tsx +679 -0
  85. package/Tests/App/Dashboard/DashboardSloAndDataSourceChartZoom.test.tsx +881 -0
  86. package/Tests/App/Dashboard/DashboardTraceStatusWidgets.test.tsx +878 -0
  87. package/Tests/App/Dashboard/DatabaseMetricChartModalTimeRangeZoom.test.tsx +442 -0
  88. package/Tests/App/Dashboard/DatabaseOverviewTimeRangeZoom.test.tsx +831 -0
  89. package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +43 -0
  90. package/Tests/App/Dashboard/DockerSwarmInsightsTimeRangeZoom.test.tsx +524 -0
  91. package/Tests/App/Dashboard/DockerSwarmRateChartRefresh.test.tsx +259 -0
  92. package/Tests/App/Dashboard/EdgeDetailPanelHistory.test.tsx +763 -0
  93. package/Tests/App/Dashboard/EdgeDetailPanelTimeRangeZoom.test.tsx +547 -0
  94. package/Tests/App/Dashboard/EdgeHistoryBucketsCases.tsx +565 -0
  95. package/Tests/App/Dashboard/EdgeHistoryBucketsKathmandu.test.tsx +73 -0
  96. package/Tests/App/Dashboard/EdgeHistoryBucketsKolkata.test.tsx +74 -0
  97. package/Tests/App/Dashboard/EdgeHistoryBucketsNewYork.test.tsx +72 -0
  98. package/Tests/App/Dashboard/EdgeHistoryBucketsUtc.test.tsx +72 -0
  99. package/Tests/App/Dashboard/EmbeddedMetricCardRefresh.test.tsx +310 -0
  100. package/Tests/App/Dashboard/EmbeddedMetricCardTimeRangeZoom.test.tsx +536 -0
  101. package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +3 -1
  102. package/Tests/App/Dashboard/EscalationRuleRowActions.test.tsx +660 -0
  103. package/Tests/App/Dashboard/EventNotes.test.tsx +2 -2
  104. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +587 -13
  105. package/Tests/App/Dashboard/EventOverviewSnapshotExplorerZoom.test.tsx +1139 -0
  106. package/Tests/App/Dashboard/EventOverviewSnapshotZoomAcrossTabs.test.tsx +1057 -0
  107. package/Tests/App/Dashboard/EventOverviewTelemetrySnapshotZoom.test.tsx +757 -0
  108. package/Tests/App/Dashboard/ExceptionOccurrenceTrendZoom.test.tsx +675 -0
  109. package/Tests/App/Dashboard/ExceptionOccurrencesZoomSurvivesViewSwitch.test.tsx +405 -0
  110. package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +67 -3
  111. package/Tests/App/Dashboard/ExceptionTablesSpanStatus.test.tsx +515 -0
  112. package/Tests/App/Dashboard/ExplorerOwnZoomRegression.test.tsx +739 -0
  113. package/Tests/App/Dashboard/FlowBandwidthAxisCases.tsx +461 -0
  114. package/Tests/App/Dashboard/FlowBandwidthAxisKathmandu.test.tsx +25 -0
  115. package/Tests/App/Dashboard/FlowBandwidthAxisKolkata.test.tsx +25 -0
  116. package/Tests/App/Dashboard/FlowBandwidthAxisNewYork.test.tsx +25 -0
  117. package/Tests/App/Dashboard/FlowBandwidthAxisUtc.test.tsx +24 -0
  118. package/Tests/App/Dashboard/FlowTopTalkersZoomRefetch.test.tsx +722 -0
  119. package/Tests/App/Dashboard/FlowViewportGuard.test.tsx +2526 -0
  120. package/Tests/App/Dashboard/HostPagesSlowLoads.test.tsx +872 -0
  121. package/Tests/App/Dashboard/HostPagesTimeRangeZoom.test.tsx +1208 -0
  122. package/Tests/App/Dashboard/IncidentRootCauseTimeRangeZoom.test.tsx +358 -0
  123. package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +100 -9
  124. package/Tests/App/Dashboard/InfrastructureMetricsTabTimeRangeZoom.test.tsx +485 -0
  125. package/Tests/App/Dashboard/InvestigationDrawerCompanionZoom.test.tsx +655 -0
  126. package/Tests/App/Dashboard/InvestigationDrawerZoom.test.tsx +830 -0
  127. package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +338 -2
  128. package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +454 -16
  129. package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +799 -819
  130. package/Tests/App/Dashboard/KubernetesClusterAiAgentOverviewCard.test.tsx +367 -0
  131. package/Tests/App/Dashboard/KubernetesClusterAiAgentStatus.test.ts +1202 -0
  132. package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +106 -0
  133. package/Tests/App/Dashboard/KubernetesClusterAiNavigation.test.tsx +354 -0
  134. package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +1884 -2054
  135. package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +478 -179
  136. package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +50 -0
  137. package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +2 -1
  138. package/Tests/App/Dashboard/KubernetesClusterOverviewZoom.test.tsx +1217 -0
  139. package/Tests/App/Dashboard/KubernetesClusterPagesZoom.test.tsx +731 -0
  140. package/Tests/App/Dashboard/KubernetesCostsLoadRecovery.test.tsx +869 -0
  141. package/Tests/App/Dashboard/KubernetesCostsZoom.test.tsx +1214 -0
  142. package/Tests/App/Dashboard/KubernetesCostsZoomExactHours.test.tsx +692 -0
  143. package/Tests/App/Dashboard/KubernetesNetworkThroughputReload.test.tsx +902 -0
  144. package/Tests/App/Dashboard/KubernetesNetworkZoomBucketEdges.test.tsx +571 -0
  145. package/Tests/App/Dashboard/KubernetesOverviewZoomBucketEdges.test.tsx +697 -0
  146. package/Tests/App/Dashboard/KubernetesResourceMetricsTabZoom.test.tsx +633 -0
  147. package/Tests/App/Dashboard/LogsExplorerTimeRangeZoom.test.tsx +470 -0
  148. package/Tests/App/Dashboard/LogsInsightsTimeRangeZoom.test.tsx +948 -0
  149. package/Tests/App/Dashboard/LogsViewerPinnedWindowZoom.test.tsx +486 -0
  150. package/Tests/App/Dashboard/MetricChartsBucketInspectorDoubleClick.test.tsx +1001 -0
  151. package/Tests/App/Dashboard/MetricExplorerInvestigationAutoRefresh.test.tsx +514 -0
  152. package/Tests/App/Dashboard/MetricExplorerSavedViewZoomRoundTrip.test.tsx +581 -0
  153. package/Tests/App/Dashboard/MetricExplorerTimeRangeZoom.test.tsx +1162 -0
  154. package/Tests/App/Dashboard/MetricMonitorPreviewZoomLabel.test.ts +72 -0
  155. package/Tests/App/Dashboard/MetricRowSparklineTimeRangeZoom.test.tsx +204 -0
  156. package/Tests/App/Dashboard/MetricViewFirstResultLands.test.tsx +408 -0
  157. package/Tests/App/Dashboard/MetricViewOwnZoomResetPlacement.test.tsx +952 -0
  158. package/Tests/App/Dashboard/MetricViewTimeRange.test.ts +139 -0
  159. package/Tests/App/Dashboard/MetricViewTimeRangeZoom.test.tsx +556 -0
  160. package/Tests/App/Dashboard/MonitorMetricsChartWrappersZoom.test.tsx +552 -0
  161. package/Tests/App/Dashboard/MonitorMetricsTabsTimeRangeZoom.test.tsx +740 -0
  162. package/Tests/App/Dashboard/MonitorOverviewChartsTimeRangeZoom.test.tsx +735 -0
  163. package/Tests/App/Dashboard/MonitorStepPreviewsTimeRangeZoom.test.tsx +835 -0
  164. package/Tests/App/Dashboard/NetworkDeviceTimeRangeZoom.test.tsx +1115 -0
  165. package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +186 -17
  166. package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +155 -46
  167. package/Tests/App/Dashboard/PasskeySettings.test.tsx +87 -2
  168. package/Tests/App/Dashboard/ProjectAISettingsPages.test.tsx +884 -0
  169. package/Tests/App/Dashboard/ProxmoxNodeRemove.test.tsx +621 -0
  170. package/Tests/App/Dashboard/ProxmoxOverviewSlowLoads.test.tsx +584 -0
  171. package/Tests/App/Dashboard/ProxmoxPagesTimeRangeZoom.test.tsx +823 -0
  172. package/Tests/App/Dashboard/ProxmoxRateChartReload.test.tsx +1253 -0
  173. package/Tests/App/Dashboard/PublicDashboardBoardWideZoom.test.tsx +605 -0
  174. package/Tests/App/Dashboard/RealRowsLineChart.tsx +250 -0
  175. package/Tests/App/Dashboard/RechartsHostsPlotCursor.test.tsx +513 -0
  176. package/Tests/App/Dashboard/RowActionPlacementOverrides.test.tsx +865 -0
  177. package/Tests/App/Dashboard/RumOverviewTimeRangeZoom.test.tsx +877 -0
  178. package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +20 -4
  179. package/Tests/App/Dashboard/RunnerSupersededByAiAgentNote.test.tsx +296 -0
  180. package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +146 -36
  181. package/Tests/App/Dashboard/ServiceDatabaseSlowLoads.test.tsx +1166 -0
  182. package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +1243 -104
  183. package/Tests/App/Dashboard/ServiceOverviewTimeRangeZoom.test.tsx +792 -0
  184. package/Tests/App/Dashboard/SloBudgetBurnDownZoom.test.tsx +771 -0
  185. package/Tests/App/Dashboard/SloBudgetBurnDownZoomAffordances.test.tsx +380 -0
  186. package/Tests/App/Dashboard/SloEventMetricsBarChartZoom.test.tsx +369 -0
  187. package/Tests/App/Dashboard/SloHistoryChartsTimeRangeZoom.test.tsx +694 -0
  188. package/Tests/App/Dashboard/SloHistoryChartsZoomAffordances.test.tsx +497 -0
  189. package/Tests/App/Dashboard/SloMetricsTimeRangeZoom.test.tsx +541 -0
  190. package/Tests/App/Dashboard/SlowLoadHarness.ts +123 -0
  191. package/Tests/App/Dashboard/SnapshotExplorerPrimaryZoom.test.tsx +1194 -0
  192. package/Tests/App/Dashboard/SnapshotViewerPinnedWindow.test.tsx +620 -0
  193. package/Tests/App/Dashboard/TelemetrySnapshotPanelTimeRangeZoom.test.tsx +765 -0
  194. package/Tests/App/Dashboard/TelemetrySnapshotZoom.test.tsx +516 -0
  195. package/Tests/App/Dashboard/TelemetrySnapshotZoomAcrossTabs.test.tsx +827 -0
  196. package/Tests/App/Dashboard/TimeRangeZoomPageHarness.tsx +463 -0
  197. package/Tests/App/Dashboard/TraceChartEditorStatusSplit.test.tsx +543 -0
  198. package/Tests/App/Dashboard/TraceStatusPresentation.test.tsx +967 -0
  199. package/Tests/App/Dashboard/TraceTimelineMinimapZoom.test.tsx +315 -0
  200. package/Tests/App/Dashboard/TracesAnalyticsStatusSplit.test.tsx +778 -0
  201. package/Tests/App/Dashboard/TracesAnalyticsViewZoom.test.tsx +349 -0
  202. package/Tests/App/Dashboard/TracesExplorerTimeRangeZoom.test.tsx +551 -0
  203. package/Tests/App/Dashboard/TracesStatusChartAndFacet.test.tsx +687 -0
  204. package/Tests/App/Dashboard/TracesViewerStaleResponses.test.tsx +458 -0
  205. package/Tests/App/Dashboard/UptimeStripsExcludedFromZoom.test.tsx +406 -0
  206. package/Tests/App/Dashboard/VMwareOverviewSlowLoads.test.tsx +535 -0
  207. package/Tests/App/Dashboard/VMwarePagesTimeRangeZoom.test.tsx +606 -0
  208. package/Tests/App/Dashboard/ValueWidgetSparklineStaleHover.test.tsx +1292 -0
  209. package/Tests/App/Dashboard/ValueWidgetSparklineZoom.test.tsx +765 -0
  210. package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +98 -0
  211. package/Tests/Models/DatabaseModels/KubernetesAiAgentModel.test.ts +295 -0
  212. package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +347 -0
  213. package/Tests/Server/API/AIChatRouteAuthorization.test.ts +58 -0
  214. package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +1 -1
  215. package/Tests/Server/API/AIInvestigationAPI.test.ts +123 -45
  216. package/Tests/Server/API/AutoRemediationApproveClusterRound.test.ts +1329 -0
  217. package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +25 -2
  218. package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -0
  219. package/Tests/Server/API/KubernetesClusterAiAccessAPIAgent.test.ts +903 -0
  220. package/Tests/Server/API/MicrosoftTeamsChatsRefreshRoute.test.ts +667 -0
  221. package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +294 -6
  222. package/Tests/Server/API/ProxmoxResourceAPIRemoveNode.test.ts +1932 -0
  223. package/Tests/Server/Infrastructure/GlobalCache.test.ts +195 -0
  224. package/Tests/Server/Infrastructure/Postgres/AddKubernetesAiAgentAndAiDefaultsMigration.test.ts +623 -0
  225. package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +87 -10
  226. package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleScopeMigration.test.ts +622 -0
  227. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +61 -4
  228. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +98 -2
  229. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +105 -2
  230. package/Tests/Server/Services/AIServiceBalanceBlocker.test.ts +282 -0
  231. package/Tests/Server/Services/AlertMonitorClearWritesNull.test.ts +409 -0
  232. package/Tests/Server/Services/AlertMonitorEditFeed.test.ts +474 -0
  233. package/Tests/Server/Services/AlertMonitorEditGuard.test.ts +610 -0
  234. package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +2 -0
  235. package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +2 -1
  236. package/Tests/Server/Services/IncidentAffectedMonitorsEdit.test.ts +1360 -0
  237. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +3 -1
  238. package/Tests/Server/Services/IncidentSeverityDeletePausesComplianceRules.test.ts +488 -0
  239. package/Tests/Server/Services/KubernetesAiAgentJobService.test.ts +329 -0
  240. package/Tests/Server/Services/KubernetesAiAgentServiceHelpers.test.ts +618 -0
  241. package/Tests/Server/Services/KubernetesAiAgentServiceLifecycle.test.ts +1444 -0
  242. package/Tests/Server/Services/KubernetesAiAgentServiceRegister.test.ts +1666 -0
  243. package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +140 -111
  244. package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +267 -105
  245. package/Tests/Server/Services/KubernetesClusterAiAccessLegacySuperseded.test.ts +440 -0
  246. package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +567 -411
  247. package/Tests/Server/Services/KubernetesClusterAiAccessTarget.test.ts +1168 -0
  248. package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +410 -12
  249. package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +55 -0
  250. package/Tests/Server/Services/ProjectServiceNewProjectAiDefaults.test.ts +288 -0
  251. package/Tests/Server/Services/ProxmoxResourcePostgres.test.ts +5633 -0
  252. package/Tests/Server/Services/ProxmoxResourceService.test.ts +6458 -5
  253. package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +48 -15
  254. package/Tests/Server/Services/RunnerJobEnqueueKubectlAiAgent.test.ts +620 -0
  255. package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +170 -3
  256. package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +72 -0
  257. package/Tests/Server/Services/RunnerServiceAgentName.test.ts +6 -4
  258. package/Tests/Server/Services/ScheduledMaintenanceAttachmentEdit.test.ts +2113 -0
  259. package/Tests/Server/Services/ScheduledMaintenanceMonitorRelease.test.ts +972 -0
  260. package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +2237 -0
  261. package/Tests/Server/Services/TeamComplianceSettingService.test.ts +3988 -138
  262. package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +107 -1
  263. package/Tests/Server/Utils/AI/IncidentPostmortemRunner.test.ts +351 -0
  264. package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +2 -0
  265. package/Tests/Server/Utils/AI/InvestigationEligibility.test.ts +310 -0
  266. package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +70 -0
  267. package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +58 -0
  268. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +2 -0
  269. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +2 -0
  270. package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +2 -0
  271. package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +125 -1
  272. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +252 -3
  273. package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +2 -0
  274. package/Tests/Server/Utils/AI/RemediationExecutionRunnerProjectGates.test.ts +240 -0
  275. package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +2 -0
  276. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +2 -0
  277. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +2 -0
  278. package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +2 -0
  279. package/Tests/Server/Utils/Telemetry/HostAssetAttributesFromOtlp.test.ts +68 -0
  280. package/Tests/Server/Utils/Telemetry/InventoryMirrorPostgres.test.ts +370 -0
  281. package/Tests/Server/Utils/Telemetry/NetworkDeviceInventoryAttributes.test.ts +522 -0
  282. package/Tests/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.test.ts +155 -0
  283. package/Tests/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.test.ts +8631 -0
  284. package/Tests/Server/Utils/Telemetry/ProxmoxNativePush.test.ts +2852 -0
  285. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +367 -1
  286. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +45 -3
  287. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +25 -0
  288. package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNames.test.ts +3119 -0
  289. package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNamesPostgres.test.ts +1721 -0
  290. package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +581 -113
  291. package/Tests/Types/Kubernetes/KubernetesAiAgentAccessContract.test.ts +510 -0
  292. package/Tests/Types/Team/ComplianceRule.test.ts +1029 -0
  293. package/Tests/Types/Team/TeamComplianceStatus.test.ts +176 -0
  294. package/Tests/UI/Components/ActionButton/RowActions.test.tsx +641 -0
  295. package/Tests/UI/Components/ActionButton/RowActionsAccessibility.test.tsx +414 -0
  296. package/Tests/UI/Components/ActionButton/SplitActionButtons.test.ts +565 -0
  297. package/Tests/UI/Components/Charts/BarChartDragToSelect.test.tsx +386 -0
  298. package/Tests/UI/Components/Charts/ChartDoubleClickResetWithoutDblclick.test.tsx +1025 -0
  299. package/Tests/UI/Components/Charts/ChartGroupPageZoomHint.test.tsx +196 -0
  300. package/Tests/UI/Components/Charts/ChartPlaceholdersTakeDoubleClick.test.tsx +1861 -0
  301. package/Tests/UI/Components/Charts/ChartPlotClicksWhileResetArmed.test.tsx +382 -0
  302. package/Tests/UI/Components/Charts/ChartRangeSelection.test.tsx +704 -0
  303. package/Tests/UI/Components/Charts/ChartRangeSelectionDoubleClickReset.test.tsx +1481 -0
  304. package/Tests/UI/Components/Charts/ChartRangeSelectionRealRecharts.test.tsx +918 -0
  305. package/Tests/UI/Components/Charts/ChartRowBucketStart.test.ts +350 -0
  306. package/Tests/UI/Components/Charts/DoubleClickReset.test.tsx +996 -0
  307. package/Tests/UI/Components/Charts/HistogramDoubleClickResetRealRecharts.test.tsx +965 -0
  308. package/Tests/UI/Components/Charts/HistogramDriftThenRefetch.test.tsx +277 -0
  309. package/Tests/UI/Components/Charts/HistogramRangeSelectionDataChange.test.tsx +1757 -0
  310. package/Tests/UI/Components/Charts/HistogramRangeSelectionRealRecharts.test.tsx +560 -0
  311. package/Tests/UI/Components/Charts/TimeRangeZoom/ChartPageTimeRangeZoom.test.tsx +513 -0
  312. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.test.tsx +845 -0
  313. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.test.tsx +119 -0
  314. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHintTailwind.test.tsx +274 -0
  315. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.test.ts +433 -0
  316. package/Tests/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.test.tsx +863 -0
  317. package/Tests/UI/Components/Charts/TimeRangeZoom/ZoomDocsPromises.test.tsx +1147 -0
  318. package/Tests/UI/Components/DisabledButtonTooltip.test.tsx +14 -3
  319. package/Tests/UI/Components/EntityDropdownEscape.test.tsx +454 -0
  320. package/Tests/UI/Components/EntityDropdownFocusLeave.test.tsx +420 -0
  321. package/Tests/UI/Components/Forms/FormFieldDropdownDisabled.test.tsx +233 -0
  322. package/Tests/UI/Components/Input.test.tsx +80 -1
  323. package/Tests/UI/Components/LogsAnalyticsViewZoom.test.tsx +947 -0
  324. package/Tests/UI/Components/LogsHistogramDragTooltip.test.tsx +17 -5
  325. package/Tests/UI/Components/LogsViewerAnalyticsZoom.test.tsx +501 -0
  326. package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +1 -1
  327. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +6 -4
  328. package/Tests/UI/Components/ModelTable/BaseModelTablePermissionGating.test.tsx +60 -8
  329. package/Tests/UI/Components/ModelTable/BaseModelTableRowActions.test.tsx +476 -0
  330. package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +7 -5
  331. package/Tests/UI/Components/MoreMenuPortal.test.tsx +623 -0
  332. package/Tests/UI/Components/StatusPage/ResourceGridActions.test.tsx +538 -0
  333. package/Tests/UI/Components/StatusPage/ResourceGridSelection.test.tsx +14 -4
  334. package/Tests/UI/Components/TableCellWrapping.test.tsx +3 -3
  335. package/Tests/UI/Components/TableRowActions.test.tsx +472 -0
  336. package/Tests/UI/Components/TelemetryHistogramDragTooltip.test.tsx +1 -1
  337. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +1 -1
  338. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerZoomScope.test.tsx +470 -0
  339. package/Tests/UI/Components/TelemetryViewer/UseViewerTimeRangeZoom.test.tsx +571 -0
  340. package/Tests/UI/Components/TelemetryViewer/ViewerDoubleClickResetUnderDataChange.test.tsx +928 -0
  341. package/Tests/UI/Components/TelemetryViewer/ViewerFollowsEnclosingZoom.test.tsx +1569 -0
  342. package/Tests/UI/Components/Toggle.test.tsx +66 -0
  343. package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardRefreshNames.test.tsx +1023 -0
  344. package/Tests/UI/Rum/ChunkLoader.test.ts +201 -0
  345. package/Tests/UI/Rum/FidelityNotices.test.ts +54 -0
  346. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +72 -0
  347. package/Tests/UI/Rum/ReplayFrameCapture.test.ts +1009 -9
  348. package/Tests/UI/Rum/ReplayRecordedAssets.test.ts +1069 -0
  349. package/Tests/UI/Rum/ReplayStage.test.tsx +913 -2
  350. package/Tests/UI/Rum/SessionReplayTable.test.tsx +443 -8
  351. package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +439 -9
  352. package/Tests/UI/Rum/UserFlowTablesRowActions.test.tsx +501 -0
  353. package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +47 -19
  354. package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +2 -0
  355. package/Tests/Utils/AiRemediation/KubernetesAiAgentPolicyCopyParity.test.ts +396 -0
  356. package/Tests/Utils/Dashboard/DashboardTimeRangeZoom.test.ts +104 -1
  357. package/Types/AI/AIRunType.ts +9 -4
  358. package/Types/AI/InvestigationNotStartedReason.ts +6 -0
  359. package/Types/AutoRemediation/AiRemediationCommandPlan.ts +14 -16
  360. package/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.ts +28 -0
  361. package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +4 -2
  362. package/Types/Kubernetes/KubernetesClusterAiAccess.ts +263 -32
  363. package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +20 -16
  364. package/Types/Kubernetes/KubernetesClusterAiInsights.ts +81 -0
  365. package/Types/Monitor/ProxmoxAlertTemplates.ts +4 -4
  366. package/Types/Team/ComplianceNotificationChannel.ts +22 -0
  367. package/Types/Team/ComplianceRule.ts +434 -0
  368. package/Types/Team/ComplianceRuleType.ts +21 -0
  369. package/Types/Team/TeamComplianceStatus.ts +81 -0
  370. package/Types/Telemetry/TelemetryIngestSurface.ts +28 -0
  371. package/UI/Components/ActionButton/ActionButtonSchema.ts +21 -0
  372. package/UI/Components/ActionButton/RowActions.tsx +238 -0
  373. package/UI/Components/ActionButton/SplitActionButtons.ts +173 -0
  374. package/UI/Components/Charts/Area/AreaChart.tsx +32 -2
  375. package/UI/Components/Charts/Bar/BarChart.tsx +40 -3
  376. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +37 -11
  377. package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +80 -243
  378. package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +122 -31
  379. package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +95 -244
  380. package/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.ts +214 -0
  381. package/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.ts +32 -0
  382. package/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.ts +599 -0
  383. package/UI/Components/Charts/Line/LineChart.tsx +32 -2
  384. package/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.tsx +70 -0
  385. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.tsx +226 -0
  386. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.tsx +73 -0
  387. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.ts +163 -0
  388. package/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.ts +215 -0
  389. package/UI/Components/Charts/Utils/DataPoint.ts +20 -8
  390. package/UI/Components/Charts/Utils/XAxis.ts +75 -0
  391. package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +493 -59
  392. package/UI/Components/EntityDropdown/EntityDropdown.tsx +107 -11
  393. package/UI/Components/Forms/Fields/FormField.tsx +10 -0
  394. package/UI/Components/Input/Input.tsx +90 -57
  395. package/UI/Components/List/ListRow.tsx +8 -74
  396. package/UI/Components/LogsViewer/LogsViewer.tsx +40 -11
  397. package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +22 -6
  398. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +209 -6
  399. package/UI/Components/LogsViewer/components/LogsHistogram.tsx +127 -84
  400. package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +3 -0
  401. package/UI/Components/ModelTable/BaseModelTable.tsx +12 -1
  402. package/UI/Components/MoreMenu/MoreMenu.tsx +365 -30
  403. package/UI/Components/MoreMenu/MoreMenuItem.tsx +70 -17
  404. package/UI/Components/OrderedStatesList/Item.tsx +7 -72
  405. package/UI/Components/StatusPage/ResourceGrid.tsx +126 -77
  406. package/UI/Components/Table/TableBody.tsx +8 -2
  407. package/UI/Components/Table/TableRow.tsx +20 -140
  408. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +41 -10
  409. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +47 -9
  410. package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +25 -6
  411. package/UI/Components/TelemetryViewer/types.ts +2 -0
  412. package/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.ts +448 -0
  413. package/UI/Components/Toggle/Toggle.tsx +26 -0
  414. package/UI/Components/Tooltip/Tooltip.tsx +8 -1
  415. package/UI/Styles/Theme.css +14 -2
  416. package/Utils/AiRemediation/CommandPolicy.ts +1 -1
  417. package/Utils/AiRemediation/KubectlPolicy.ts +1 -1
  418. package/Utils/Dashboard/DashboardTimeRangeZoom.ts +46 -2
  419. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  420. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  421. package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js +385 -0
  422. package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js.map +1 -0
  423. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +3 -3
  424. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  425. package/build/dist/Models/DatabaseModels/Project.js +56 -5
  426. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  427. package/build/dist/Models/DatabaseModels/ProxmoxResource.js +51 -1
  428. package/build/dist/Models/DatabaseModels/ProxmoxResource.js.map +1 -1
  429. package/build/dist/Models/DatabaseModels/RunnerJob.js +74 -0
  430. package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
  431. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +134 -3
  432. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
  433. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  434. package/build/dist/Server/API/AIChatAPI.js +6 -1
  435. package/build/dist/Server/API/AIChatAPI.js.map +1 -1
  436. package/build/dist/Server/API/AIInvestigationAPI.js +17 -10
  437. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  438. package/build/dist/Server/API/AutoRemediationAPI.js +144 -24
  439. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  440. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +436 -22
  441. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -1
  442. package/build/dist/Server/API/MicrosoftTeamsAPI.js +69 -13
  443. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  444. package/build/dist/Server/API/ProxmoxResourceAPI.js +187 -14
  445. package/build/dist/Server/API/ProxmoxResourceAPI.js.map +1 -1
  446. package/build/dist/Server/Infrastructure/GlobalCache.js +27 -0
  447. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  448. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js +50 -0
  449. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js.map +1 -0
  450. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js +84 -0
  451. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js.map +1 -0
  452. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js +31 -0
  453. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js.map +1 -0
  454. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  455. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  456. package/build/dist/Server/Middleware/TelemetryIngest.js +34 -19
  457. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  458. package/build/dist/Server/Services/AIService.js +59 -1
  459. package/build/dist/Server/Services/AIService.js.map +1 -1
  460. package/build/dist/Server/Services/AlertService.js +248 -13
  461. package/build/dist/Server/Services/AlertService.js.map +1 -1
  462. package/build/dist/Server/Services/AlertSeverityService.js +51 -15
  463. package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
  464. package/build/dist/Server/Services/AutoRemediationRuleService.js +1 -1
  465. package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
  466. package/build/dist/Server/Services/IncidentService.js +199 -72
  467. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  468. package/build/dist/Server/Services/IncidentSeverityService.js +51 -15
  469. package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
  470. package/build/dist/Server/Services/KubernetesAiAgentJobService.js +158 -0
  471. package/build/dist/Server/Services/KubernetesAiAgentJobService.js.map +1 -0
  472. package/build/dist/Server/Services/KubernetesAiAgentService.js +1145 -0
  473. package/build/dist/Server/Services/KubernetesAiAgentService.js.map +1 -0
  474. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +842 -371
  475. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -1
  476. package/build/dist/Server/Services/KubernetesClusterService.js +86 -17
  477. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  478. package/build/dist/Server/Services/ProjectService.js +22 -0
  479. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  480. package/build/dist/Server/Services/ProxmoxResourceService.js +258 -3
  481. package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
  482. package/build/dist/Server/Services/RunnerJobService.js +178 -92
  483. package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
  484. package/build/dist/Server/Services/RunnerService.js +1 -1
  485. package/build/dist/Server/Services/RunnerService.js.map +1 -1
  486. package/build/dist/Server/Services/ScheduledMaintenanceService.js +535 -3
  487. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  488. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +316 -46
  489. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  490. package/build/dist/Server/Services/TeamComplianceSettingService.js +833 -7
  491. package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
  492. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +52 -9
  493. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -1
  494. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +13 -9
  495. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
  496. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +7 -3
  497. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
  498. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +29 -15
  499. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
  500. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +56 -20
  501. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  502. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +39 -5
  503. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  504. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js +30 -3
  505. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -1
  506. package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js +13 -2
  507. package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js.map +1 -1
  508. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +1 -1
  509. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +4 -2
  510. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
  511. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +111 -6
  512. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
  513. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +40 -4
  514. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -1
  515. package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js +296 -0
  516. package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js.map +1 -0
  517. package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js +699 -0
  518. package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js.map +1 -0
  519. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +77 -19
  520. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  521. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +505 -42
  522. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  523. package/build/dist/Types/AI/AIRunType.js +9 -4
  524. package/build/dist/Types/AI/AIRunType.js.map +1 -1
  525. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +10 -16
  526. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
  527. package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js +28 -0
  528. package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js.map +1 -0
  529. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +72 -16
  530. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
  531. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +20 -16
  532. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -1
  533. package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js +17 -0
  534. package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js.map +1 -0
  535. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +4 -4
  536. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
  537. package/build/dist/Types/Team/ComplianceNotificationChannel.js +23 -0
  538. package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -0
  539. package/build/dist/Types/Team/ComplianceRule.js +304 -0
  540. package/build/dist/Types/Team/ComplianceRule.js.map +1 -0
  541. package/build/dist/Types/Team/ComplianceRuleType.js +21 -0
  542. package/build/dist/Types/Team/ComplianceRuleType.js.map +1 -1
  543. package/build/dist/Types/Team/TeamComplianceStatus.js +2 -0
  544. package/build/dist/Types/Team/TeamComplianceStatus.js.map +1 -0
  545. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +25 -0
  546. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
  547. package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js +20 -1
  548. package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js.map +1 -1
  549. package/build/dist/UI/Components/ActionButton/RowActions.js +113 -0
  550. package/build/dist/UI/Components/ActionButton/RowActions.js.map +1 -0
  551. package/build/dist/UI/Components/ActionButton/SplitActionButtons.js +71 -0
  552. package/build/dist/UI/Components/ActionButton/SplitActionButtons.js.map +1 -0
  553. package/build/dist/UI/Components/Charts/Area/AreaChart.js +16 -1
  554. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  555. package/build/dist/UI/Components/Charts/Bar/BarChart.js +16 -1
  556. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  557. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +27 -5
  558. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  559. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +61 -194
  560. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
  561. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +84 -26
  562. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
  563. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +75 -196
  564. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
  565. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js +133 -0
  566. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js.map +1 -1
  567. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js +26 -0
  568. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js.map +1 -0
  569. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js +371 -0
  570. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js.map +1 -0
  571. package/build/dist/UI/Components/Charts/Line/LineChart.js +16 -1
  572. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  573. package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js +35 -0
  574. package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js.map +1 -0
  575. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js +107 -0
  576. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js.map +1 -0
  577. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js +41 -0
  578. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js.map +1 -0
  579. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js +117 -0
  580. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js.map +1 -0
  581. package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js +121 -0
  582. package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js.map +1 -0
  583. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -7
  584. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  585. package/build/dist/UI/Components/Charts/Utils/XAxis.js +70 -0
  586. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  587. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +305 -38
  588. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -1
  589. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +89 -14
  590. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
  591. package/build/dist/UI/Components/Forms/Fields/FormField.js +11 -2
  592. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  593. package/build/dist/UI/Components/Input/Input.js +69 -54
  594. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  595. package/build/dist/UI/Components/List/ListRow.js +4 -39
  596. package/build/dist/UI/Components/List/ListRow.js.map +1 -1
  597. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +31 -8
  598. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  599. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +10 -1
  600. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
  601. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +139 -21
  602. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  603. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +30 -8
  604. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
  605. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +1 -1
  606. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
  607. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +10 -0
  608. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  609. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +253 -14
  610. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  611. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +43 -13
  612. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  613. package/build/dist/UI/Components/OrderedStatesList/Item.js +2 -38
  614. package/build/dist/UI/Components/OrderedStatesList/Item.js.map +1 -1
  615. package/build/dist/UI/Components/StatusPage/ResourceGrid.js +53 -15
  616. package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -1
  617. package/build/dist/UI/Components/Table/TableBody.js +6 -2
  618. package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
  619. package/build/dist/UI/Components/Table/TableRow.js +12 -75
  620. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  621. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +32 -7
  622. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  623. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +27 -9
  624. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  625. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +11 -1
  626. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
  627. package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js +272 -0
  628. package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js.map +1 -0
  629. package/build/dist/UI/Components/Toggle/Toggle.js +14 -1
  630. package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
  631. package/build/dist/UI/Components/Tooltip/Tooltip.js +1 -1
  632. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  633. package/build/dist/Utils/AiRemediation/CommandPolicy.js +1 -1
  634. package/build/dist/Utils/AiRemediation/CommandPolicy.js.map +1 -1
  635. package/build/dist/Utils/AiRemediation/KubectlPolicy.js +1 -1
  636. package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -1
  637. package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js +27 -1
  638. package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js.map +1 -1
  639. package/package.json +1 -1
@@ -0,0 +1,865 @@
1
+ import "@testing-library/jest-dom";
2
+ import { afterEach, describe, expect, jest, test } from "@jest/globals";
3
+ import {
4
+ cleanup,
5
+ fireEvent,
6
+ render,
7
+ screen,
8
+ waitFor,
9
+ within,
10
+ } from "@testing-library/react";
11
+ import React, { ReactElement } from "react";
12
+ import { MemoryRouter } from "react-router-dom";
13
+ import getJestMockFunction, { MockFunction } from "../../MockType";
14
+
15
+ /*
16
+ * THE TABLES THAT HAD TO SAY WHICH ACTION IS THE ROW'S BUTTON.
17
+ *
18
+ * Every row now shows one action as a button and folds the rest into a ⋯ menu
19
+ * (SplitActionButtons). The split reads the choice off each action's style, and
20
+ * on most tables that is the right choice. On these it is not, so the page
21
+ * marks the action itself:
22
+ *
23
+ * - the notification method tables (Email, SMS, Call, WhatsApp, Telegram and
24
+ * incoming call numbers) mark Verify Primary. Left to the style, the
25
+ * NORMAL-styled Resend Code / Rotate Code would take the button and an
26
+ * unverified row - which is waiting on exactly one thing, the code - would
27
+ * hide Verify in the menu;
28
+ * - a project's custom probes mark Show ID and Key MoreMenu. It is NORMAL
29
+ * styled, so whenever View is not on offer it would take the button;
30
+ * - discovery scans mark Review Results Primary. Edit sits ahead of it and is
31
+ * just as NORMAL, so without the mark a scan with hosts waiting to be
32
+ * imported would offer Edit.
33
+ *
34
+ * So these render the real tables through the real ModelTable, with only the
35
+ * network stubbed, and assert on what a person would see on the row. Each
36
+ * describe block has at least one test that fails when the page's placement
37
+ * line is deleted. The admin dashboard's probes and AI agents are covered in
38
+ * App/AdminDashboard/RowActionPlacementOverrides.test.tsx.
39
+ */
40
+
41
+ const getMock: MockFunction = getJestMockFunction();
42
+ const postMock: MockFunction = getJestMockFunction();
43
+ const getListMock: MockFunction = getJestMockFunction();
44
+ const getItemMock: MockFunction = getJestMockFunction();
45
+ const getCommonHeadersMock: MockFunction = getJestMockFunction();
46
+
47
+ /*
48
+ * The arrow wrappers are load bearing: jest.mock is hoisted above the compiled
49
+ * requires, so the consts above are still in their temporal dead zone when the
50
+ * factory body runs. Dereferencing them lazily, at call time, is what works.
51
+ */
52
+ jest.mock("../../../UI/Utils/API/API", () => {
53
+ return {
54
+ __esModule: true,
55
+ default: {
56
+ get: (...args: Array<any>) => {
57
+ return getMock(...args);
58
+ },
59
+ post: (...args: Array<any>) => {
60
+ return postMock(...args);
61
+ },
62
+ getFriendlyMessage: (error: unknown) => {
63
+ return error instanceof Error ? error.message : "Something went wrong";
64
+ },
65
+ },
66
+ };
67
+ });
68
+
69
+ jest.mock("../../../UI/Utils/ModelAPI/ModelAPI", () => {
70
+ return {
71
+ __esModule: true,
72
+ default: {
73
+ getCommonHeaders: (...args: Array<any>) => {
74
+ return getCommonHeadersMock(...args);
75
+ },
76
+ getList: (...args: Array<any>) => {
77
+ return getListMock(...args);
78
+ },
79
+ getItem: (...args: Array<any>) => {
80
+ return getItemMock(...args);
81
+ },
82
+ },
83
+ };
84
+ });
85
+
86
+ jest.mock("react-i18next", () => {
87
+ return {
88
+ useTranslation: () => {
89
+ return {
90
+ t: (key: string, options?: { defaultValue?: string }): string => {
91
+ return options?.defaultValue ?? key;
92
+ },
93
+ };
94
+ },
95
+ };
96
+ });
97
+
98
+ import EmailMethods from "../../../../App/FeatureSet/Dashboard/src/Components/NotificationMethods/Email";
99
+ import SMSMethods from "../../../../App/FeatureSet/Dashboard/src/Components/NotificationMethods/SMS";
100
+ import CallMethods from "../../../../App/FeatureSet/Dashboard/src/Components/NotificationMethods/Call";
101
+ import WhatsAppMethods from "../../../../App/FeatureSet/Dashboard/src/Components/NotificationMethods/WhatsApp";
102
+ import TelegramMethods from "../../../../App/FeatureSet/Dashboard/src/Components/NotificationMethods/Telegram";
103
+ import IncomingCallNumberMethods from "../../../../App/FeatureSet/Dashboard/src/Components/NotificationMethods/IncomingCallNumber";
104
+ import MonitorProbesPage from "../../../../App/FeatureSet/Dashboard/src/Pages/Monitor/Settings/MonitorProbes";
105
+ import DiscoveryPage from "../../../../App/FeatureSet/Dashboard/src/Pages/NetworkDevice/Discovery";
106
+ import BaseModel, {
107
+ DatabaseBaseModelType,
108
+ } from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
109
+ import NetworkDeviceDiscoveryScan, {
110
+ DiscoveredNetworkDevice,
111
+ } from "../../../Models/DatabaseModels/NetworkDeviceDiscoveryScan";
112
+ import Probe from "../../../Models/DatabaseModels/Probe";
113
+ import Project from "../../../Models/DatabaseModels/Project";
114
+ import UserCall from "../../../Models/DatabaseModels/UserCall";
115
+ import UserEmail from "../../../Models/DatabaseModels/UserEmail";
116
+ import UserIncomingCallNumber from "../../../Models/DatabaseModels/UserIncomingCallNumber";
117
+ import UserSMS from "../../../Models/DatabaseModels/UserSMS";
118
+ import UserTelegram from "../../../Models/DatabaseModels/UserTelegram";
119
+ import UserWhatsApp from "../../../Models/DatabaseModels/UserWhatsApp";
120
+ import HTTPResponse from "../../../Types/API/HTTPResponse";
121
+ import Route from "../../../Types/API/Route";
122
+ import Email from "../../../Types/Email";
123
+ import { JSONObject } from "../../../Types/JSON";
124
+ import ObjectID from "../../../Types/ObjectID";
125
+ import Permission from "../../../Types/Permission";
126
+ import Phone from "../../../Types/Phone";
127
+ import {
128
+ DISCOVERY_SCAN_STARTED_MESSAGE,
129
+ DiscoveryScanStatus,
130
+ } from "../../../Utils/NetworkDiscovery/DiscoveryScanStatus";
131
+
132
+ const USER_ID: string = "aaaaaaaa-1111-4111-8111-111111111111";
133
+ const PROJECT_ID: string = "dddddddd-4444-4444-8444-444444444444";
134
+
135
+ afterEach(() => {
136
+ cleanup();
137
+ getMock.mockReset();
138
+ postMock.mockReset();
139
+ getListMock.mockReset();
140
+ getItemMock.mockReset();
141
+ getCommonHeadersMock.mockReset();
142
+ localStorage.clear();
143
+ sessionStorage.clear();
144
+ });
145
+
146
+ /*
147
+ * The session these pages read themselves out of. The components take the user
148
+ * and the project from the real utils rather than from props, so the storage
149
+ * those utils read is set instead of stubbing them.
150
+ */
151
+ type SessionOptions = {
152
+ isMasterAdmin: boolean;
153
+ projectPermissions: Array<Permission>;
154
+ };
155
+
156
+ const startSession: (options: SessionOptions) => void = (
157
+ options: SessionOptions,
158
+ ): void => {
159
+ localStorage.setItem("user_id", USER_ID);
160
+ localStorage.setItem("is_master_admin", String(options.isMasterAdmin));
161
+ sessionStorage.setItem("current_project_id", PROJECT_ID);
162
+
163
+ if (options.projectPermissions.length > 0) {
164
+ localStorage.setItem(
165
+ "project_permissions",
166
+ JSON.stringify({
167
+ projectId: PROJECT_ID,
168
+ permissions: options.projectPermissions.map(
169
+ (permission: Permission) => {
170
+ return { permission: permission };
171
+ },
172
+ ),
173
+ }),
174
+ );
175
+ }
176
+ };
177
+
178
+ /*
179
+ * A project owner, as the sibling notification-method suites sign in. The
180
+ * permission snapshot matters as well as the master-admin flag: the table drops
181
+ * any extra column the snapshot cannot read (a probe's key, a scan's hosts)
182
+ * from what it asks the server for.
183
+ */
184
+ const signInAsOwner: () => void = (): void => {
185
+ startSession({
186
+ isMasterAdmin: true,
187
+ projectPermissions: [Permission.ProjectOwner],
188
+ });
189
+ };
190
+
191
+ /*
192
+ * What a person sees on a row: the one button and the ⋯ trigger, by the name a
193
+ * screen reader would announce.
194
+ */
195
+ const rowButtonLabels: (rowActions: HTMLElement) => Array<string> = (
196
+ rowActions: HTMLElement,
197
+ ): Array<string> => {
198
+ return within(rowActions)
199
+ .getAllByRole("button")
200
+ .map((button: HTMLElement) => {
201
+ const label: string =
202
+ button.getAttribute("aria-label") || (button.textContent || "").trim();
203
+
204
+ /*
205
+ * Each ⋯ is named for its row ("More actions for Monitor: Checkout
206
+ * API"); what these tests compare is which controls a row has.
207
+ */
208
+ return label.startsWith("More actions for ") ? "More actions" : label;
209
+ });
210
+ };
211
+
212
+ const openMenuIn: (rowActions: HTMLElement) => HTMLElement = (
213
+ rowActions: HTMLElement,
214
+ ): HTMLElement => {
215
+ fireEvent.click(within(rowActions).getByTestId("row-actions-more-button"));
216
+ return screen.getByRole("menu");
217
+ };
218
+
219
+ const menuLabels: (menu: HTMLElement) => Array<string> = (
220
+ menu: HTMLElement,
221
+ ): Array<string> => {
222
+ return within(menu)
223
+ .getAllByRole("menuitem")
224
+ .map((item: HTMLElement) => {
225
+ return (item.textContent || "").trim();
226
+ });
227
+ };
228
+
229
+ type ListResultJSON = {
230
+ data: Array<BaseModel>;
231
+ count: number;
232
+ skip: number;
233
+ limit: number;
234
+ };
235
+
236
+ const listOf: (rows: Array<BaseModel>) => Promise<ListResultJSON> = (
237
+ rows: Array<BaseModel>,
238
+ ): Promise<ListResultJSON> => {
239
+ return Promise.resolve({
240
+ data: rows,
241
+ count: rows.length,
242
+ skip: 0,
243
+ limit: 50,
244
+ });
245
+ };
246
+
247
+ /*
248
+ * ---------------------------------------------------------------------------
249
+ * NOTIFICATION METHODS: Verify is what an unverified row is waiting for.
250
+ * ---------------------------------------------------------------------------
251
+ */
252
+
253
+ const UNVERIFIED_ID: string = "11111111-7777-4777-8777-777777777777";
254
+ const VERIFIED_ID: string = "22222222-8888-4888-8888-888888888888";
255
+
256
+ interface MethodTable {
257
+ name: string;
258
+ Component: () => ReactElement;
259
+ modelType: DatabaseBaseModelType;
260
+ // The identifying columns of one row; isVerified is added per row.
261
+ columns: JSONObject;
262
+ // The NORMAL-styled code action that would take the button without the mark.
263
+ codeActionTitle: string;
264
+ verifyDialogTitle: string;
265
+ codeActionDialogTitle: string;
266
+ }
267
+
268
+ const METHOD_TABLES: Array<MethodTable> = [
269
+ {
270
+ name: "Email",
271
+ Component: EmailMethods,
272
+ modelType: UserEmail,
273
+ columns: { email: new Email("jane@example.com") as never },
274
+ codeActionTitle: "Resend Code",
275
+ verifyDialogTitle: "Verify Email",
276
+ codeActionDialogTitle: "Resend Code",
277
+ },
278
+ {
279
+ name: "SMS",
280
+ Component: SMSMethods,
281
+ modelType: UserSMS,
282
+ columns: { phone: new Phone("+15551230100") as never },
283
+ codeActionTitle: "Resend Code",
284
+ verifyDialogTitle: "Verify Phone Number",
285
+ codeActionDialogTitle: "Resend Code",
286
+ },
287
+ {
288
+ name: "Call",
289
+ Component: CallMethods,
290
+ modelType: UserCall,
291
+ columns: { phone: new Phone("+15551230199") as never },
292
+ codeActionTitle: "Resend Code",
293
+ verifyDialogTitle: "Verify Phone Number",
294
+ codeActionDialogTitle: "Resend Code",
295
+ },
296
+ {
297
+ name: "WhatsApp",
298
+ Component: WhatsAppMethods,
299
+ modelType: UserWhatsApp,
300
+ columns: { phone: new Phone("+15551230123") as never },
301
+ codeActionTitle: "Resend Code",
302
+ verifyDialogTitle: "Verify WhatsApp Number",
303
+ codeActionDialogTitle: "Resend Code",
304
+ },
305
+ {
306
+ name: "Telegram",
307
+ Component: TelegramMethods,
308
+ modelType: UserTelegram,
309
+ columns: { telegramUserHandle: "@alexchen" },
310
+ codeActionTitle: "Rotate Code",
311
+ verifyDialogTitle: "Verify Telegram Account",
312
+ codeActionDialogTitle: "Rotate Verification Code",
313
+ },
314
+ {
315
+ name: "Incoming call number",
316
+ Component: IncomingCallNumberMethods,
317
+ modelType: UserIncomingCallNumber,
318
+ columns: { phone: new Phone("+15551230177") as never },
319
+ codeActionTitle: "Resend Code",
320
+ verifyDialogTitle: "Verify Phone Number",
321
+ codeActionDialogTitle: "Resend Code",
322
+ },
323
+ ];
324
+
325
+ const buildMethodRow: (
326
+ table: MethodTable,
327
+ id: string,
328
+ isVerified: boolean,
329
+ ) => BaseModel = (
330
+ table: MethodTable,
331
+ id: string,
332
+ isVerified: boolean,
333
+ ): BaseModel => {
334
+ const model: BaseModel = new table.modelType();
335
+ model.id = new ObjectID(id);
336
+
337
+ const columns: JSONObject = { ...table.columns, isVerified: isVerified };
338
+
339
+ for (const columnName of Object.keys(columns)) {
340
+ (model as unknown as Record<string, unknown>)[columnName] =
341
+ columns[columnName];
342
+ }
343
+
344
+ return model;
345
+ };
346
+
347
+ /*
348
+ * One unverified method above one verified one, so the same render shows the
349
+ * row the mark is for and the row it must leave alone.
350
+ */
351
+ const mockMethodRows: (table: MethodTable) => void = (
352
+ table: MethodTable,
353
+ ): void => {
354
+ getCommonHeadersMock.mockReturnValue({});
355
+
356
+ getListMock.mockImplementation((params: any): Promise<ListResultJSON> => {
357
+ if (params.modelType === table.modelType) {
358
+ return listOf([
359
+ buildMethodRow(table, UNVERIFIED_ID, false),
360
+ buildMethodRow(table, VERIFIED_ID, true),
361
+ ]);
362
+ }
363
+
364
+ return listOf([]);
365
+ });
366
+
367
+ /*
368
+ * Only Telegram's Verify calls out before its dialog opens (for the bot's
369
+ * deep link); the others post only when the dialog is submitted.
370
+ */
371
+ postMock.mockResolvedValue(
372
+ new HTTPResponse<JSONObject>(
373
+ 200,
374
+ {
375
+ verificationCode: "123456",
376
+ telegramBotUsername: "oneuptime_bot",
377
+ isVerified: false,
378
+ deepLinkUrl: "https://t.me/oneuptime_bot?start=123456",
379
+ startCommand: "/start 123456",
380
+ },
381
+ {},
382
+ ) as never,
383
+ );
384
+ };
385
+
386
+ type MethodRows = {
387
+ unverified: HTMLElement;
388
+ verified: HTMLElement;
389
+ };
390
+
391
+ const renderMethodTable: (table: MethodTable) => Promise<MethodRows> = async (
392
+ table: MethodTable,
393
+ ): Promise<MethodRows> => {
394
+ signInAsOwner();
395
+ mockMethodRows(table);
396
+
397
+ render(<table.Component />);
398
+
399
+ await waitFor(() => {
400
+ expect(screen.getAllByTestId("row-actions")).toHaveLength(2);
401
+ });
402
+
403
+ const [unverified, verified] = screen.getAllByTestId("row-actions");
404
+
405
+ return { unverified: unverified!, verified: verified! };
406
+ };
407
+
408
+ describe.each(METHOD_TABLES)(
409
+ "$name notification methods: Verify is the unverified row's button",
410
+ (table: MethodTable) => {
411
+ test("an unverified row shows Verify, with the code action and Delete in the menu", async () => {
412
+ const { unverified } = await renderMethodTable(table);
413
+
414
+ expect(rowButtonLabels(unverified)).toEqual(["Verify", "More actions"]);
415
+ expect(within(unverified).queryByText(table.codeActionTitle)).toBeNull();
416
+
417
+ // Delete sinks below the code action, as destructive actions always do.
418
+ expect(menuLabels(openMenuIn(unverified))).toEqual([
419
+ table.codeActionTitle,
420
+ "Delete",
421
+ ]);
422
+ });
423
+
424
+ test("Verify is never offered from the menu as well", async () => {
425
+ const { unverified } = await renderMethodTable(table);
426
+
427
+ expect(
428
+ within(openMenuIn(unverified)).queryByRole("menuitem", {
429
+ name: "Verify",
430
+ }),
431
+ ).toBeNull();
432
+ expect(screen.getAllByRole("button", { name: "Verify" })).toHaveLength(1);
433
+ });
434
+
435
+ /*
436
+ * The mark is for rows that are waiting on a code. A verified row has
437
+ * nothing to verify, so it must not grow a Verify button from it - Delete
438
+ * is all it has, and a lone action stays on the row rather than behind a
439
+ * menu of one.
440
+ */
441
+ test("a verified row offers neither Verify nor the code action", async () => {
442
+ const { verified } = await renderMethodTable(table);
443
+
444
+ expect(rowButtonLabels(verified)).toEqual(["Delete"]);
445
+ expect(
446
+ within(verified).queryByTestId("row-actions-more-button"),
447
+ ).toBeNull();
448
+ });
449
+
450
+ test("the row's Verify button opens the verify dialog", async () => {
451
+ const { unverified } = await renderMethodTable(table);
452
+
453
+ fireEvent.click(
454
+ within(unverified).getByRole("button", { name: "Verify" }),
455
+ );
456
+
457
+ await waitFor(() => {
458
+ expect(screen.getByTestId("modal-title")).toHaveTextContent(
459
+ table.verifyDialogTitle,
460
+ );
461
+ });
462
+ });
463
+
464
+ test("the code action still works from the menu", async () => {
465
+ const { unverified } = await renderMethodTable(table);
466
+
467
+ fireEvent.click(
468
+ within(openMenuIn(unverified)).getByRole("menuitem", {
469
+ name: table.codeActionTitle,
470
+ }),
471
+ );
472
+
473
+ await waitFor(() => {
474
+ expect(screen.getByTestId("modal-title")).toHaveTextContent(
475
+ table.codeActionDialogTitle,
476
+ );
477
+ });
478
+ });
479
+ },
480
+ );
481
+
482
+ /*
483
+ * ---------------------------------------------------------------------------
484
+ * A PROJECT'S CUSTOM PROBES: Show ID and Key is a utility, never the button.
485
+ * ---------------------------------------------------------------------------
486
+ */
487
+
488
+ const PROBE_ID: string = "33333333-9999-4999-8999-999999999999";
489
+ const PROBE_KEY: string = "probe-secret-key-0001";
490
+
491
+ /*
492
+ * The page carries two probe tables. The global one (read from its own
493
+ * endpoint) has no row actions, so it is left empty and every row on screen is
494
+ * the custom probe.
495
+ */
496
+ const mockProbeRows: () => void = (): void => {
497
+ getCommonHeadersMock.mockReturnValue({});
498
+
499
+ getListMock.mockImplementation((params: any): Promise<ListResultJSON> => {
500
+ if (
501
+ params.modelType === Probe &&
502
+ !params.requestOptions?.overrideRequestUrl
503
+ ) {
504
+ const probe: Probe = new Probe();
505
+ probe._id = PROBE_ID;
506
+ probe.name = "Office LAN";
507
+ probe.key = PROBE_KEY;
508
+
509
+ return listOf([probe]);
510
+ }
511
+
512
+ return listOf([]);
513
+ });
514
+
515
+ // The Global Probe Settings card under the tables reads the project.
516
+ getItemMock.mockResolvedValue(null as never);
517
+ };
518
+
519
+ const renderMonitorProbes: () => Promise<HTMLElement> =
520
+ async (): Promise<HTMLElement> => {
521
+ mockProbeRows();
522
+
523
+ render(
524
+ <MemoryRouter>
525
+ <MonitorProbesPage
526
+ pageRoute={new Route("/dashboard/settings/probes")}
527
+ currentProject={null}
528
+ hasPaymentMethod={true}
529
+ />
530
+ </MemoryRouter>,
531
+ );
532
+
533
+ await waitFor(() => {
534
+ expect(screen.getAllByTestId("row-actions")).toHaveLength(1);
535
+ });
536
+
537
+ return screen.getByTestId("row-actions");
538
+ };
539
+
540
+ describe("Custom probes: Show ID and Key is never the row's button", () => {
541
+ test("a probe row shows View, with Show ID and Key in the menu", async () => {
542
+ signInAsOwner();
543
+
544
+ const rowActions: HTMLElement = await renderMonitorProbes();
545
+
546
+ expect(rowButtonLabels(rowActions)).toEqual(["View Probe", "More actions"]);
547
+ expect(
548
+ within(rowActions).queryByRole("button", { name: "Show ID and Key" }),
549
+ ).toBeNull();
550
+ expect(menuLabels(openMenuIn(rowActions))).toEqual(["Show ID and Key"]);
551
+ });
552
+
553
+ /*
554
+ * View only appears once the permission snapshot says the viewer may read
555
+ * probes - and the snapshot arrives on a response header, so for the first
556
+ * paint after a login or a project switch it is empty. Show ID and Key is
557
+ * then the row's only action, and styled NORMAL: without the MoreMenu mark
558
+ * it would sit on every row as the button, which is the one place a
559
+ * secret-revealing utility should not be.
560
+ */
561
+ test("with View not on offer, Show ID and Key still waits in the menu", async () => {
562
+ startSession({ isMasterAdmin: false, projectPermissions: [] });
563
+
564
+ const rowActions: HTMLElement = await renderMonitorProbes();
565
+
566
+ expect(rowButtonLabels(rowActions)).toEqual(["More actions"]);
567
+ expect(menuLabels(openMenuIn(rowActions))).toEqual(["Show ID and Key"]);
568
+ });
569
+
570
+ test("Show ID and Key from the menu reveals that probe's ID and key", async () => {
571
+ signInAsOwner();
572
+
573
+ const rowActions: HTMLElement = await renderMonitorProbes();
574
+
575
+ fireEvent.click(
576
+ within(openMenuIn(rowActions)).getByRole("menuitem", {
577
+ name: "Show ID and Key",
578
+ }),
579
+ );
580
+
581
+ await waitFor(() => {
582
+ expect(screen.getByTestId("modal-title")).toHaveTextContent("Probe Key");
583
+ });
584
+ expect(screen.getByTestId("confirm-modal-description")).toHaveTextContent(
585
+ `Probe ID: ${PROBE_ID}`,
586
+ );
587
+ expect(screen.getByTestId("confirm-modal-description")).toHaveTextContent(
588
+ `Probe Key: ${PROBE_KEY}`,
589
+ );
590
+ });
591
+ });
592
+
593
+ /*
594
+ * ---------------------------------------------------------------------------
595
+ * DISCOVERY SCANS: Review Results is why a scan with results exists.
596
+ * ---------------------------------------------------------------------------
597
+ */
598
+
599
+ const HOST: DiscoveredNetworkDevice = {
600
+ ipAddress: "10.0.0.7",
601
+ snmpReachable: false,
602
+ isAlreadyRegistered: false,
603
+ };
604
+
605
+ type ScanCase = {
606
+ name: string;
607
+ id: string;
608
+ overrides: Partial<Record<string, unknown>>;
609
+ };
610
+
611
+ /*
612
+ * One scan in every state the Review Results rule tells apart, named for what
613
+ * the row should offer. Pending and just-claimed scans still carry the hosts of
614
+ * their previous run - those belong to a run that is over, which is why
615
+ * neither may be reviewed.
616
+ */
617
+ const COMPLETED_SCAN: ScanCase = {
618
+ name: "Completed with hosts",
619
+ id: "44444444-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
620
+ overrides: { status: DiscoveryScanStatus.Completed },
621
+ };
622
+
623
+ const RUNNING_SCAN: ScanCase = {
624
+ name: "Running with partial hosts",
625
+ id: "55555555-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
626
+ overrides: { status: DiscoveryScanStatus.InProgress },
627
+ };
628
+
629
+ const FAILED_SCAN: ScanCase = {
630
+ name: "Failed after partial hosts",
631
+ id: "66666666-cccc-4ccc-8ccc-cccccccccccc",
632
+ overrides: {
633
+ status: DiscoveryScanStatus.Failed,
634
+ statusMessage: "Probe lost connection during discovery.",
635
+ },
636
+ };
637
+
638
+ const JUST_CLAIMED_SCAN: ScanCase = {
639
+ name: "Just claimed",
640
+ id: "77777777-dddd-4ddd-8ddd-dddddddddddd",
641
+ overrides: {
642
+ status: DiscoveryScanStatus.InProgress,
643
+ statusMessage: DISCOVERY_SCAN_STARTED_MESSAGE,
644
+ },
645
+ };
646
+
647
+ const PENDING_SCAN: ScanCase = {
648
+ name: "Queued",
649
+ id: "88888888-eeee-4eee-8eee-eeeeeeeeeeee",
650
+ overrides: { status: DiscoveryScanStatus.Pending, startedAt: undefined },
651
+ };
652
+
653
+ const RUNNING_EMPTY_SCAN: ScanCase = {
654
+ name: "Running with no hosts yet",
655
+ id: "99999999-ffff-4fff-8fff-ffffffffffff",
656
+ overrides: {
657
+ status: DiscoveryScanStatus.InProgress,
658
+ respondedHostCount: 0,
659
+ discoveredDevices: [],
660
+ },
661
+ };
662
+
663
+ const ALL_SCANS: Array<ScanCase> = [
664
+ COMPLETED_SCAN,
665
+ RUNNING_SCAN,
666
+ FAILED_SCAN,
667
+ JUST_CLAIMED_SCAN,
668
+ PENDING_SCAN,
669
+ RUNNING_EMPTY_SCAN,
670
+ ];
671
+
672
+ const buildScan: (scanCase: ScanCase) => NetworkDeviceDiscoveryScan = (
673
+ scanCase: ScanCase,
674
+ ): NetworkDeviceDiscoveryScan => {
675
+ return Object.assign(
676
+ new NetworkDeviceDiscoveryScan(),
677
+ {
678
+ _id: scanCase.id,
679
+ name: scanCase.name,
680
+ cidr: "10.0.0.0/24",
681
+ startedAt: new Date("2026-09-09T12:00:00Z"),
682
+ scannedHostCount: 256,
683
+ respondedHostCount: 1,
684
+ discoveredDevices: [HOST],
685
+ },
686
+ scanCase.overrides,
687
+ );
688
+ };
689
+
690
+ const mockScanRows: () => void = (): void => {
691
+ getCommonHeadersMock.mockReturnValue({});
692
+
693
+ getListMock.mockImplementation((params: any): Promise<ListResultJSON> => {
694
+ if (params.modelType === NetworkDeviceDiscoveryScan) {
695
+ return listOf(ALL_SCANS.map(buildScan));
696
+ }
697
+
698
+ return listOf([]);
699
+ });
700
+
701
+ // The review dialog re-reads the scan it opens for.
702
+ getItemMock.mockImplementation((params: any): Promise<unknown> => {
703
+ if (params.modelType === NetworkDeviceDiscoveryScan) {
704
+ const scanCase: ScanCase | undefined = ALL_SCANS.find(
705
+ (candidate: ScanCase) => {
706
+ return candidate.id === params.id.toString();
707
+ },
708
+ );
709
+
710
+ return Promise.resolve(
711
+ scanCase
712
+ ? Object.assign(buildScan(scanCase), { isSnmpEnabled: false })
713
+ : null,
714
+ );
715
+ }
716
+
717
+ return Promise.resolve(null);
718
+ });
719
+ };
720
+
721
+ const renderDiscovery: () => Promise<void> = async (): Promise<void> => {
722
+ mockScanRows();
723
+
724
+ render(
725
+ <MemoryRouter>
726
+ <DiscoveryPage
727
+ pageRoute={new Route("/dashboard/network-devices/discovery")}
728
+ currentProject={Object.assign(new Project(), {
729
+ id: new ObjectID(PROJECT_ID),
730
+ })}
731
+ hasPaymentMethod={true}
732
+ />
733
+ </MemoryRouter>,
734
+ );
735
+
736
+ await waitFor(() => {
737
+ expect(screen.getAllByTestId("row-actions")).toHaveLength(ALL_SCANS.length);
738
+ });
739
+ };
740
+
741
+ // The actions of the table row that names this scan.
742
+ const rowActionsFor: (scanCase: ScanCase) => HTMLElement = (
743
+ scanCase: ScanCase,
744
+ ): HTMLElement => {
745
+ const rowActions: HTMLElement | undefined = screen
746
+ .getAllByTestId("row-actions")
747
+ .find((candidate: HTMLElement) => {
748
+ return (candidate.closest("tr")?.textContent || "").includes(
749
+ scanCase.name,
750
+ );
751
+ });
752
+
753
+ if (!rowActions) {
754
+ throw new Error(`No row for the "${scanCase.name}" scan.`);
755
+ }
756
+
757
+ return rowActions;
758
+ };
759
+
760
+ describe("Discovery scans: Review Results is the row's button whenever it is offered", () => {
761
+ test.each([COMPLETED_SCAN, RUNNING_SCAN, FAILED_SCAN])(
762
+ "$name: Review Results on the row, Edit and Delete in the menu",
763
+ async (scanCase: ScanCase) => {
764
+ signInAsOwner();
765
+ await renderDiscovery();
766
+
767
+ const rowActions: HTMLElement = rowActionsFor(scanCase);
768
+
769
+ expect(rowButtonLabels(rowActions)).toEqual([
770
+ "Review Results",
771
+ "More actions",
772
+ ]);
773
+ expect(within(rowActions).queryByText("Edit")).toBeNull();
774
+ expect(menuLabels(openMenuIn(rowActions))).toEqual(["Edit", "Delete"]);
775
+ },
776
+ );
777
+
778
+ /*
779
+ * The mark only decides between actions that are offered. A scan with
780
+ * nothing reviewable does not show Review Results at all, so Edit - the first
781
+ * call to action left - is its button.
782
+ */
783
+ test.each([JUST_CLAIMED_SCAN, PENDING_SCAN, RUNNING_EMPTY_SCAN])(
784
+ "$name: nothing to review, so Edit is the button",
785
+ async (scanCase: ScanCase) => {
786
+ signInAsOwner();
787
+ await renderDiscovery();
788
+
789
+ const rowActions: HTMLElement = rowActionsFor(scanCase);
790
+
791
+ expect(rowButtonLabels(rowActions)).toEqual(["Edit", "More actions"]);
792
+ expect(menuLabels(openMenuIn(rowActions))).toEqual(["Delete"]);
793
+ },
794
+ );
795
+
796
+ test("the row's Review Results button opens the review for that scan", async () => {
797
+ signInAsOwner();
798
+ await renderDiscovery();
799
+
800
+ fireEvent.click(
801
+ within(rowActionsFor(RUNNING_SCAN)).getByRole("button", {
802
+ name: "Review Results",
803
+ }),
804
+ );
805
+
806
+ await waitFor(() => {
807
+ expect(screen.getByTestId("modal-title")).toHaveTextContent(
808
+ "Review Discovered Devices",
809
+ );
810
+ });
811
+
812
+ const scanReads: Array<any> = (getItemMock as any).mock.calls.filter(
813
+ (call: Array<any>): boolean => {
814
+ return call[0].modelType === NetworkDeviceDiscoveryScan;
815
+ },
816
+ );
817
+
818
+ expect(scanReads).toHaveLength(1);
819
+ expect(scanReads[0][0].id.toString()).toBe(RUNNING_SCAN.id);
820
+ });
821
+
822
+ test("Edit from the menu opens the edit form for that scan", async () => {
823
+ signInAsOwner();
824
+ await renderDiscovery();
825
+
826
+ fireEvent.click(
827
+ within(openMenuIn(rowActionsFor(COMPLETED_SCAN))).getByRole("menuitem", {
828
+ name: "Edit",
829
+ }),
830
+ );
831
+
832
+ await waitFor(() => {
833
+ expect(screen.getByTestId("modal-title")).toHaveTextContent(
834
+ "Edit Discovery Scan",
835
+ );
836
+ });
837
+ });
838
+
839
+ /*
840
+ * A viewer is never offered Edit (the page hides it rather than open a form
841
+ * they could not save), and Delete is shown locked. Review Results is still
842
+ * theirs to use.
843
+ */
844
+ test("a viewer still gets Review Results on the row, and no Edit anywhere", async () => {
845
+ startSession({
846
+ isMasterAdmin: false,
847
+ projectPermissions: [Permission.Viewer],
848
+ });
849
+ await renderDiscovery();
850
+
851
+ const rowActions: HTMLElement = rowActionsFor(COMPLETED_SCAN);
852
+
853
+ expect(rowButtonLabels(rowActions)).toEqual([
854
+ "Review Results",
855
+ "More actions",
856
+ ]);
857
+
858
+ const menu: HTMLElement = openMenuIn(rowActions);
859
+
860
+ expect(menuLabels(menu)).toEqual(["Delete"]);
861
+ expect(
862
+ within(menu).getByRole("menuitem", { name: "Delete" }),
863
+ ).toHaveAttribute("aria-disabled", "true");
864
+ });
865
+ });