@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
@@ -331,7 +331,15 @@ import OneUptimeDate from "../../../Types/Date";
331
331
  import ObjectID from "../../../Types/ObjectID";
332
332
  import StatusPageSubscriberNotificationStatus from "../../../Types/StatusPage/StatusPageSubscriberNotificationStatus";
333
333
  import IncidentCreatedResend from "../../../Types/StatusPage/IncidentCreatedResend";
334
- import { FormType } from "../../../UI/Components/Forms/ModelForm";
334
+ import ModelForm, {
335
+ FormType,
336
+ ModelField,
337
+ } from "../../../UI/Components/Forms/ModelForm";
338
+ import { ModalWidth } from "../../../UI/Components/Modal/Modal";
339
+ import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
340
+ import Includes from "../../../Types/BaseDatabase/Includes";
341
+ import { JSONObject } from "../../../Types/JSON";
342
+ import JSONFunctions from "../../../Types/JSONFunctions";
335
343
  import SubscriberNotificationResendCopy from "../../../../App/FeatureSet/Dashboard/src/Components/StatusPageSubscribers/SubscriberNotificationResendCopy";
336
344
  import { DetailStyle } from "../../../UI/Components/Detail/Detail";
337
345
  import FormFieldSchemaType from "../../../UI/Components/Forms/Types/FormFieldSchemaType";
@@ -1233,6 +1241,24 @@ describe.each([
1233
1241
  latestProps<{ seriesLabels: unknown }>("SeriesResource").seriesLabels,
1234
1242
  ).toEqual({ "host.name": "prod-01" });
1235
1243
  });
1244
+
1245
+ /*
1246
+ * The Affected Resources editor holds a picker whose placeholder names a
1247
+ * dozen resource types. In the default 512px modal it was cut off and
1248
+ * every chip cramped, so the card edits in a Medium one.
1249
+ */
1250
+ test("the Affected Resources card edits in a Medium modal", async () => {
1251
+ serve(pageCase, { timeline: REOPENED_TIMELINE, title: "Checkout slow" });
1252
+
1253
+ pageCase.renderPage();
1254
+ await waitForPage();
1255
+
1256
+ expect(
1257
+ latestProps<{ createEditModalWidth?: ModalWidth }>(
1258
+ "CardModelDetail:Affected Resources",
1259
+ ).createEditModalWidth,
1260
+ ).toBe(ModalWidth.Medium);
1261
+ });
1236
1262
  });
1237
1263
 
1238
1264
  describe("background refresh", () => {
@@ -1886,7 +1912,13 @@ describe.each([
1886
1912
  */
1887
1913
  interface ResourcesFormFieldProps {
1888
1914
  field?: Record<string, unknown>;
1915
+ title?: string;
1916
+ description?: string;
1889
1917
  fieldType?: FormFieldSchemaType;
1918
+ required?: boolean;
1919
+ placeholder?: string;
1920
+ disabled?: boolean;
1921
+ dropdownModal?: { type: unknown; labelField: string; valueField: string };
1890
1922
  showIf?: (values: unknown) => boolean;
1891
1923
  getCustomElement?: (values: unknown, elementProps: unknown) => ReactElement;
1892
1924
  }
@@ -2908,11 +2940,11 @@ describe("alert-only behaviour", () => {
2908
2940
  });
2909
2941
 
2910
2942
  /*
2911
- * The monitor is shown, never edited: ModelForm loads and saves only the
2912
- * fields registered here, so leaving the monitor out means saving the
2913
- * card can neither move the alert to another monitor nor clear it.
2943
+ * Alert.monitor is a single relation, so it is edited with a dropdown of
2944
+ * its own above the picker (as on the Create page), never as a picker
2945
+ * chip. ModelForm loads and saves only the fields registered here.
2914
2946
  */
2915
- test("its edit form never loads the monitor, so saving cannot change or clear it", () => {
2947
+ test("its edit form offers the monitor in a dropdown of its own, above the picker", () => {
2916
2948
  const formFields: Array<ResourcesFormFieldProps> =
2917
2949
  resourcesCard().formFields;
2918
2950
  const keysOf: (field: ResourcesFormFieldProps) => Array<string> = (
@@ -2923,8 +2955,13 @@ describe("alert-only behaviour", () => {
2923
2955
 
2924
2956
  const formKeys: Array<string> = formFields.flatMap(keysOf);
2925
2957
 
2926
- expect(formKeys).not.toContain("monitor");
2958
+ // The singular relation, never the incident's plural list.
2927
2959
  expect(formKeys).not.toContain("monitors");
2960
+ /*
2961
+ * The lock is read by the page, not registered: ModelForm submits every
2962
+ * registered field, and nobody may update this column.
2963
+ */
2964
+ expect(formKeys).not.toContain("isCreatedAutomatically");
2928
2965
 
2929
2966
  const visibleFields: Array<ResourcesFormFieldProps> = formFields.filter(
2930
2967
  (field: ResourcesFormFieldProps): boolean => {
@@ -2937,11 +2974,30 @@ describe("alert-only behaviour", () => {
2937
2974
  },
2938
2975
  );
2939
2976
 
2940
- // The one visible field is the resource picker, registered on hosts.
2941
- expect(visibleFields.map(keysOf)).toEqual([["hosts"]]);
2942
- expect(visibleFields[0]!.fieldType).toBe(
2943
- FormFieldSchemaType.CustomComponent,
2944
- );
2977
+ // The monitor dropdown first, then the resource picker on hosts.
2978
+ expect(visibleFields.map(keysOf)).toEqual([["monitor"], ["hosts"]]);
2979
+
2980
+ const monitorField: ResourcesFormFieldProps = visibleFields[0]!;
2981
+
2982
+ expect(monitorField.title).toBe("Monitor");
2983
+ expect(monitorField.fieldType).toBe(FormFieldSchemaType.Dropdown);
2984
+ expect(monitorField.dropdownModal).toEqual({
2985
+ type: Monitor,
2986
+ labelField: "name",
2987
+ valueField: "_id",
2988
+ });
2989
+ expect(monitorField.required).toBe(false);
2990
+ /*
2991
+ * The Create page's placeholder: the dashboard translates it by its
2992
+ * English text, and every locale has this spelling.
2993
+ */
2994
+ expect(monitorField.placeholder).toBe("Select Monitor");
2995
+
2996
+ const pickerField: ResourcesFormFieldProps = visibleFields[1]!;
2997
+
2998
+ // Read as a pair with the dropdown above it.
2999
+ expect(pickerField.title).toBe("Other Affected Resources");
3000
+ expect(pickerField.fieldType).toBe(FormFieldSchemaType.CustomComponent);
2945
3001
  // Hidden registrations so the form still loads the other relations.
2946
3002
  expect(hiddenFields.flatMap(keysOf)).toEqual([
2947
3003
  "kubernetesClusters",
@@ -2956,8 +3012,8 @@ describe("alert-only behaviour", () => {
2956
3012
  "services",
2957
3013
  ]);
2958
3014
 
2959
- // The picker it renders offers no monitors to attach either.
2960
- render(visibleFields[0]!.getCustomElement!({}, {}));
3015
+ // The picker does not offer monitors: the dropdown is the one place.
3016
+ render(pickerField.getCustomElement!({}, {}));
2961
3017
 
2962
3018
  const picker: { monitors?: unknown; resourceTypes?: Array<string> } =
2963
3019
  latestProps<{ monitors?: unknown; resourceTypes?: Array<string> }>(
@@ -2975,4 +3031,522 @@ describe("alert-only behaviour", () => {
2975
3031
  );
2976
3032
  });
2977
3033
  });
3034
+
3035
+ /*
3036
+ * An alert raised automatically keeps the monitor it was raised with, and
3037
+ * the server refuses to set, change or clear it (AlertService.
3038
+ * onBeforeUpdate). Raised by a monitor, the alert shows that monitor
3039
+ * locked, with the reason; raised without one (an SLO burn-rate or
3040
+ * security-event alert, or one whose monitor was deleted), it has no
3041
+ * Monitor field at all. The page reads which case it is with its own row,
3042
+ * so the lock is known before any card renders.
3043
+ */
3044
+ describe("the Affected Resources card's monitor lock", () => {
3045
+ interface ServedAlert {
3046
+ isCreatedAutomatically: boolean;
3047
+ monitorId?: string | undefined;
3048
+ }
3049
+
3050
+ type ServeAlertFunction = (served: ServedAlert) => void;
3051
+
3052
+ const serveAlert: ServeAlertFunction = (served: ServedAlert): void => {
3053
+ serve(ALERT_CASE, {
3054
+ timeline: REOPENED_TIMELINE,
3055
+ title: "Checkout slow",
3056
+ });
3057
+
3058
+ getItemMock.mockImplementation(() => {
3059
+ const alert: Alert = ALERT_CASE.buildEvent("Checkout slow") as Alert;
3060
+ alert.isCreatedAutomatically = served.isCreatedAutomatically;
3061
+
3062
+ if (served.monitorId) {
3063
+ alert.monitorId = new ObjectID(served.monitorId);
3064
+ }
3065
+
3066
+ return Promise.resolve(alert);
3067
+ });
3068
+ };
3069
+
3070
+ type MonitorFieldFunction = () => ResourcesFormFieldProps;
3071
+
3072
+ const monitorField: MonitorFieldFunction = (): ResourcesFormFieldProps => {
3073
+ const field: ResourcesFormFieldProps | undefined =
3074
+ resourcesCard().formFields.find(
3075
+ (formField: ResourcesFormFieldProps): boolean => {
3076
+ return Boolean(formField.field?.["monitor"]);
3077
+ },
3078
+ );
3079
+
3080
+ if (!field) {
3081
+ throw new Error("The Affected Resources form has no monitor field");
3082
+ }
3083
+
3084
+ return field;
3085
+ };
3086
+
3087
+ type IsMonitorFieldShownFunction = (values: unknown) => boolean;
3088
+
3089
+ // What the form decides for the Monitor field, given its current values.
3090
+ const isMonitorFieldShown: IsMonitorFieldShownFunction = (
3091
+ values: unknown,
3092
+ ): boolean => {
3093
+ const field: ResourcesFormFieldProps = monitorField();
3094
+
3095
+ return !field.showIf || field.showIf(values);
3096
+ };
3097
+
3098
+ const LOCKED_DESCRIPTION: string =
3099
+ "This alert was raised by this monitor, which resolves it automatically when the monitor recovers, so it can't be moved to another monitor or removed.";
3100
+
3101
+ test("the page reads whether the alert was raised automatically, and its monitor, with its own row", async () => {
3102
+ serveAlert({ isCreatedAutomatically: false });
3103
+
3104
+ ALERT_CASE.renderPage();
3105
+ await waitForPage();
3106
+
3107
+ const pageRead: { select: Record<string, unknown> } | undefined =
3108
+ getItemMock.mock.calls
3109
+ .map((call: Array<unknown>) => {
3110
+ return call[0] as { select: Record<string, unknown> };
3111
+ })
3112
+ .find((request: { select: Record<string, unknown> }): boolean => {
3113
+ return Boolean(request.select["telemetryQuery"]);
3114
+ });
3115
+
3116
+ expect(pageRead).toBeDefined();
3117
+ expect(pageRead!.select["isCreatedAutomatically"]).toBe(true);
3118
+ expect(pageRead!.select["monitorId"]).toBe(true);
3119
+ });
3120
+
3121
+ test("an alert its monitor raised shows the dropdown locked, and says why", async () => {
3122
+ serveAlert({ isCreatedAutomatically: true, monitorId: MONITOR_ID });
3123
+
3124
+ ALERT_CASE.renderPage();
3125
+ await waitForPage();
3126
+
3127
+ expect(isMonitorFieldShown({ monitor: MONITOR_ID })).toBe(true);
3128
+ expect(monitorField().disabled).toBe(true);
3129
+ expect(monitorField().description).toBe(LOCKED_DESCRIPTION);
3130
+ });
3131
+
3132
+ test("a manual alert's monitor can be changed or cleared", async () => {
3133
+ serveAlert({ isCreatedAutomatically: false, monitorId: MONITOR_ID });
3134
+
3135
+ ALERT_CASE.renderPage();
3136
+ await waitForPage();
3137
+
3138
+ expect(isMonitorFieldShown({ monitor: MONITOR_ID })).toBe(true);
3139
+ // Cleared in the open form, it stays there to pick another.
3140
+ expect(isMonitorFieldShown({ monitor: null })).toBe(true);
3141
+ expect(monitorField().disabled).toBe(false);
3142
+ expect(monitorField().description).toBe(
3143
+ "Select the monitor affected by this alert.",
3144
+ );
3145
+ });
3146
+
3147
+ test("a manual alert with no monitor can be given one", async () => {
3148
+ serveAlert({ isCreatedAutomatically: false });
3149
+
3150
+ ALERT_CASE.renderPage();
3151
+ await waitForPage();
3152
+
3153
+ expect(isMonitorFieldShown({})).toBe(true);
3154
+ expect(monitorField().disabled).toBe(false);
3155
+ expect(monitorField().description).toBe(
3156
+ "Select the monitor affected by this alert.",
3157
+ );
3158
+ });
3159
+
3160
+ /*
3161
+ * Nothing to show, and nothing that may be picked: the field is left out
3162
+ * rather than shown empty and locked with a reason that names a monitor
3163
+ * the alert does not have.
3164
+ */
3165
+ test("an automatic alert with no monitor (an SLO burn-rate alert) has no Monitor field", async () => {
3166
+ serveAlert({ isCreatedAutomatically: true });
3167
+
3168
+ ALERT_CASE.renderPage();
3169
+ await waitForPage();
3170
+
3171
+ expect(isMonitorFieldShown({})).toBe(false);
3172
+ expect(isMonitorFieldShown({ monitor: null })).toBe(false);
3173
+ // Still registered: ModelForm loads it and saves back the null it holds.
3174
+ expect(monitorField().field).toEqual({ monitor: true });
3175
+ });
3176
+
3177
+ /*
3178
+ * Saving the card can set, move or clear a manual alert's monitor. The
3179
+ * details card shows it (and reports it for the header's Monitor fact),
3180
+ * and the lock depends on the page's own row, so both are read again
3181
+ * without a reload. Here, an automatic alert's monitor was deleted while
3182
+ * the page was open: after the save, the row the page reads again has no
3183
+ * monitor, and the field locked on it is left out.
3184
+ */
3185
+ test("saving the card re-reads the details card, the page's lock and the feed", async () => {
3186
+ serveAlert({ isCreatedAutomatically: true, monitorId: MONITOR_ID });
3187
+
3188
+ ALERT_CASE.renderPage();
3189
+ await waitForPage();
3190
+
3191
+ expect(isMonitorFieldShown({})).toBe(true);
3192
+ expect(monitorField().disabled).toBe(true);
3193
+
3194
+ const refresherBefore: boolean | undefined =
3195
+ latestProps<CardModelDetailProps>(
3196
+ "CardModelDetail:Alert Details",
3197
+ ).refresher;
3198
+ const feedTokenBefore: number = latestProps<{ refreshToken: number }>(
3199
+ "Feed",
3200
+ ).refreshToken;
3201
+ const readsBefore: number = countItemReads();
3202
+
3203
+ // Its monitor was deleted, which leaves the alert's monitorId NULL.
3204
+ serveAlert({ isCreatedAutomatically: true });
3205
+
3206
+ act(() => {
3207
+ latestProps<CardModelDetailProps>("CardModelDetail:Affected Resources")
3208
+ .onSaveSuccess!();
3209
+ });
3210
+
3211
+ await waitFor(() => {
3212
+ expect(isMonitorFieldShown({})).toBe(false);
3213
+ });
3214
+
3215
+ expect(
3216
+ latestProps<CardModelDetailProps>("CardModelDetail:Alert Details")
3217
+ .refresher,
3218
+ ).toBe(!refresherBefore);
3219
+ expect(latestProps<{ refreshToken: number }>("Feed").refreshToken).toBe(
3220
+ feedTokenBefore + 1,
3221
+ );
3222
+ // One background read of the page's own row, and nothing remounted.
3223
+ expect(countItemReads()).toBe(readsBefore + 1);
3224
+ expect(mountCounts["InvestigationPanel"]).toBe(1);
3225
+ expect(mountCounts["Feed"]).toBe(1);
3226
+ });
3227
+ });
3228
+
3229
+ /*
3230
+ * The card's form fields, rendered in the real ModelForm its Edit modal
3231
+ * opens (EntityDropdown included), against the row as the API hands it to
3232
+ * the form: the monitor as `{ _id }` only.
3233
+ */
3234
+ describe("the Affected Resources edit form, rendered", () => {
3235
+ const OTHER_MONITOR_ID: string = "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbb2";
3236
+ const HOST_ID: string = "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeee1";
3237
+ const OTHER_HOST_ID: string = "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeee2";
3238
+
3239
+ const MONITOR_NAMES: Record<string, string> = {
3240
+ [MONITOR_ID]: "Developer portal",
3241
+ [OTHER_MONITOR_ID]: "Payments API",
3242
+ };
3243
+
3244
+ let formLoadSelect: Record<string, unknown> | null = null;
3245
+
3246
+ interface EditFormOptions {
3247
+ isCreatedAutomatically: boolean;
3248
+ // Whether the alert has a monitor. It has MONITOR_ID unless this is false.
3249
+ hasMonitor?: boolean | undefined;
3250
+ }
3251
+
3252
+ type RenderEditFormFunction = (options: EditFormOptions) => Promise<void>;
3253
+
3254
+ const renderEditForm: RenderEditFormFunction = async (
3255
+ options: EditFormOptions,
3256
+ ): Promise<void> => {
3257
+ const hasMonitor: boolean = options.hasMonitor !== false;
3258
+
3259
+ serve(ALERT_CASE, {
3260
+ timeline: REOPENED_TIMELINE,
3261
+ title: "Checkout slow",
3262
+ });
3263
+
3264
+ getItemMock.mockImplementation(() => {
3265
+ const alert: Alert = ALERT_CASE.buildEvent("Checkout slow") as Alert;
3266
+ alert.isCreatedAutomatically = options.isCreatedAutomatically;
3267
+
3268
+ if (hasMonitor) {
3269
+ alert.monitorId = new ObjectID(MONITOR_ID);
3270
+ }
3271
+
3272
+ return Promise.resolve(alert);
3273
+ });
3274
+
3275
+ ALERT_CASE.renderPage();
3276
+ await waitForPage();
3277
+
3278
+ const fields: Array<ModelField<Alert>> = resourcesCard()
3279
+ .formFields as unknown as Array<ModelField<Alert>>;
3280
+
3281
+ // The page has handed over its fields; only the form is needed now.
3282
+ cleanup();
3283
+
3284
+ // The form is about wiring, not about who may edit which column.
3285
+ jest.spyOn(User, "isMasterAdmin").mockReturnValue(true);
3286
+
3287
+ formLoadSelect = null;
3288
+
3289
+ getItemMock.mockImplementation((...args: Array<unknown>) => {
3290
+ formLoadSelect = (args[0] as { select: Record<string, unknown> })
3291
+ .select;
3292
+
3293
+ return Promise.resolve(
3294
+ BaseModel.fromJSON(
3295
+ {
3296
+ _id: EVENT_ID,
3297
+ // The API answers a relation the row does not hold with null.
3298
+ monitor: hasMonitor ? { _id: MONITOR_ID } : null,
3299
+ hosts: [{ _id: HOST_ID }],
3300
+ services: [],
3301
+ },
3302
+ Alert,
3303
+ ) as Alert,
3304
+ );
3305
+ });
3306
+
3307
+ getListMock.mockImplementation((...args: Array<unknown>) => {
3308
+ const request: {
3309
+ modelType: unknown;
3310
+ query: Record<string, unknown>;
3311
+ } = args[0] as {
3312
+ modelType: unknown;
3313
+ query: Record<string, unknown>;
3314
+ };
3315
+
3316
+ if (request.modelType !== Monitor) {
3317
+ return Promise.resolve(listResult([]));
3318
+ }
3319
+
3320
+ const idFilter: unknown = request.query["_id"];
3321
+ const ids: Array<string> =
3322
+ idFilter instanceof Includes
3323
+ ? (idFilter.values as Array<unknown>).map((id: unknown) => {
3324
+ return String(id);
3325
+ })
3326
+ : Object.keys(MONITOR_NAMES);
3327
+
3328
+ return Promise.resolve(
3329
+ listResult(
3330
+ ids
3331
+ .filter((id: string): boolean => {
3332
+ return Boolean(MONITOR_NAMES[id]);
3333
+ })
3334
+ .map((id: string): Monitor => {
3335
+ const monitor: Monitor = new Monitor();
3336
+ monitor._id = id;
3337
+ monitor.name = MONITOR_NAMES[id]!;
3338
+ return monitor;
3339
+ }),
3340
+ ),
3341
+ );
3342
+ });
3343
+
3344
+ createOrUpdateMock.mockResolvedValue({
3345
+ data: new Alert(),
3346
+ miscData: undefined,
3347
+ });
3348
+
3349
+ render(
3350
+ <ModelForm<Alert>
3351
+ modelType={Alert}
3352
+ id="edit-alert-affected-resources"
3353
+ name="Affected Resources"
3354
+ fields={fields}
3355
+ formType={FormType.Update}
3356
+ modelIdToEdit={new ObjectID(EVENT_ID)}
3357
+ submitButtonText="Save Changes"
3358
+ onSuccess={() => {
3359
+ // asserted through createOrUpdateMock
3360
+ }}
3361
+ />,
3362
+ );
3363
+
3364
+ if (hasMonitor) {
3365
+ await screen.findByText("Developer portal");
3366
+ return;
3367
+ }
3368
+
3369
+ // No monitor name to wait for: the picker renders with the fields.
3370
+ await waitFor(() => {
3371
+ expect(propsHistory("AffectedResourcesPicker").length).toBeGreaterThan(
3372
+ 0,
3373
+ );
3374
+ });
3375
+ };
3376
+
3377
+ type SaveFunction = () => Promise<Alert>;
3378
+
3379
+ const save: SaveFunction = async (): Promise<Alert> => {
3380
+ fireEvent.click(screen.getByRole("button", { name: "Save Changes" }));
3381
+
3382
+ await waitFor(() => {
3383
+ expect(createOrUpdateMock).toHaveBeenCalledTimes(1);
3384
+ });
3385
+
3386
+ return (createOrUpdateMock.mock.calls[0]![0] as { model: Alert }).model;
3387
+ };
3388
+
3389
+ // The body ModelAPI.createOrUpdate sends for this model.
3390
+ type RequestBodyFunction = (model: Alert) => JSONObject;
3391
+
3392
+ const requestBodyOf: RequestBodyFunction = (model: Alert): JSONObject => {
3393
+ return JSONFunctions.serialize(BaseModel.toJSON(model, Alert));
3394
+ };
3395
+
3396
+ type MonitorButtonFunction = () => HTMLButtonElement;
3397
+
3398
+ // The dropdown shows its selection as a button until it is opened.
3399
+ const monitorButton: MonitorButtonFunction = (): HTMLButtonElement => {
3400
+ const button: HTMLButtonElement | null = screen
3401
+ .getByText("Developer portal")
3402
+ .closest("button");
3403
+
3404
+ if (!button) {
3405
+ throw new Error("The monitor dropdown shows no selection");
3406
+ }
3407
+
3408
+ return button;
3409
+ };
3410
+
3411
+ test("loads the monitor as an id and shows its name", async () => {
3412
+ await renderEditForm({ isCreatedAutomatically: false });
3413
+
3414
+ expect(formLoadSelect).not.toBeNull();
3415
+ expect(formLoadSelect!["monitor"]).toBeTruthy();
3416
+ expect(monitorButton()).not.toBeDisabled();
3417
+ });
3418
+
3419
+ test("saving without touching the monitor keeps it", async () => {
3420
+ await renderEditForm({ isCreatedAutomatically: false });
3421
+
3422
+ const saved: Alert = await save();
3423
+
3424
+ expect(saved.monitor?._id?.toString()).toBe(MONITOR_ID);
3425
+ expect(requestBodyOf(saved)["monitor"]).toEqual(
3426
+ expect.objectContaining({ _id: MONITOR_ID }),
3427
+ );
3428
+ });
3429
+
3430
+ test("an edit to the other resources keeps the monitor", async () => {
3431
+ await renderEditForm({ isCreatedAutomatically: false });
3432
+
3433
+ act(() => {
3434
+ latestProps<{ onChange: (payload: unknown) => void }>(
3435
+ "AffectedResourcesPicker",
3436
+ ).onChange([OTHER_HOST_ID]);
3437
+ });
3438
+
3439
+ const saved: Alert = await save();
3440
+
3441
+ expect(saved.monitor?._id?.toString()).toBe(MONITOR_ID);
3442
+ expect(
3443
+ (saved.hosts || []).map((host: BaseModel): string => {
3444
+ return String(host._id);
3445
+ }),
3446
+ ).toEqual([OTHER_HOST_ID]);
3447
+ });
3448
+
3449
+ test("choosing another monitor saves the new one", async () => {
3450
+ await renderEditForm({ isCreatedAutomatically: false });
3451
+
3452
+ fireEvent.click(monitorButton());
3453
+ fireEvent.click(
3454
+ await screen.findByRole("option", { name: /Payments API/ }),
3455
+ );
3456
+
3457
+ const saved: Alert = await save();
3458
+
3459
+ expect(saved.monitor?._id?.toString()).toBe(OTHER_MONITOR_ID);
3460
+ expect(requestBodyOf(saved)["monitor"]).toEqual(
3461
+ expect.objectContaining({ _id: OTHER_MONITOR_ID }),
3462
+ );
3463
+ });
3464
+
3465
+ /*
3466
+ * Clear selection hands the form null. It has to reach the request as an
3467
+ * explicit null: an absent key would leave the monitor where it is.
3468
+ */
3469
+ test("clearing it saves the alert with no monitor", async () => {
3470
+ await renderEditForm({ isCreatedAutomatically: false });
3471
+
3472
+ fireEvent.click(screen.getByRole("button", { name: "Clear selection" }));
3473
+
3474
+ await waitFor(() => {
3475
+ expect(screen.queryByText("Developer portal")).toBeNull();
3476
+ });
3477
+
3478
+ const saved: Alert = await save();
3479
+ const body: JSONObject = requestBodyOf(saved);
3480
+
3481
+ expect(saved.monitor).toBeNull();
3482
+ expect(Object.prototype.hasOwnProperty.call(body, "monitor")).toBe(true);
3483
+ expect(body["monitor"]).toBeNull();
3484
+ });
3485
+
3486
+ test("for an alert its monitor raised, the dropdown cannot be opened or cleared, and saving keeps the monitor", async () => {
3487
+ await renderEditForm({ isCreatedAutomatically: true });
3488
+
3489
+ expect(monitorButton()).toBeDisabled();
3490
+ expect(screen.queryByRole("button", { name: "Clear selection" })).toBe(
3491
+ null,
3492
+ );
3493
+ expect(
3494
+ screen.getByText(/so it can't be moved to another monitor/),
3495
+ ).toBeInTheDocument();
3496
+
3497
+ fireEvent.click(monitorButton());
3498
+
3499
+ expect(screen.queryByRole("listbox")).toBeNull();
3500
+ expect(screen.queryByRole("option", { name: /Payments API/ })).toBeNull();
3501
+
3502
+ const saved: Alert = await save();
3503
+
3504
+ expect(saved.monitor?._id?.toString()).toBe(MONITOR_ID);
3505
+ });
3506
+
3507
+ /*
3508
+ * An automatic alert raised without a monitor has no Monitor field. The
3509
+ * form still loads the hidden field and submits the null it holds, which
3510
+ * the server reads as no change (AlertMonitorEditGuard.test.ts), so the
3511
+ * rest of the card still saves.
3512
+ */
3513
+ test("for an automatic alert with no monitor, the field is left out, and saving keeps it without one", async () => {
3514
+ await renderEditForm({ isCreatedAutomatically: true, hasMonitor: false });
3515
+
3516
+ expect(formLoadSelect!["monitor"]).toBeTruthy();
3517
+ expect(screen.queryByText("Monitor")).toBeNull();
3518
+ expect(screen.queryByPlaceholderText("Select Monitor")).toBeNull();
3519
+ expect(screen.queryByText(/raised by this monitor/)).toBeNull();
3520
+ expect(screen.queryByRole("button", { name: "Clear selection" })).toBe(
3521
+ null,
3522
+ );
3523
+
3524
+ act(() => {
3525
+ latestProps<{ onChange: (payload: unknown) => void }>(
3526
+ "AffectedResourcesPicker",
3527
+ ).onChange([OTHER_HOST_ID]);
3528
+ });
3529
+
3530
+ const saved: Alert = await save();
3531
+ const body: JSONObject = requestBodyOf(saved);
3532
+
3533
+ expect(saved.monitor).toBeNull();
3534
+ expect(body["monitor"]).toBeNull();
3535
+ expect(
3536
+ (saved.hosts || []).map((host: BaseModel): string => {
3537
+ return String(host._id);
3538
+ }),
3539
+ ).toEqual([OTHER_HOST_ID]);
3540
+ });
3541
+
3542
+ test("for a manual alert with no monitor, the dropdown is offered", async () => {
3543
+ await renderEditForm({
3544
+ isCreatedAutomatically: false,
3545
+ hasMonitor: false,
3546
+ });
3547
+
3548
+ expect(screen.getByText("Monitor")).toBeInTheDocument();
3549
+ expect(screen.getByPlaceholderText("Select Monitor")).not.toBeDisabled();
3550
+ });
3551
+ });
2978
3552
  });