@oneuptime/common 14.0.1 → 14.0.2

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 (1090) hide show
  1. package/Models/DatabaseModels/AlertEpisodeMember.ts +8 -1
  2. package/Models/DatabaseModels/AutoRemediationSuggestion.ts +63 -0
  3. package/Models/DatabaseModels/IncidentEpisodeMember.ts +8 -1
  4. package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +9 -2
  5. package/Models/DatabaseModels/IncidentPublicNote.ts +9 -2
  6. package/Models/DatabaseModels/KubernetesCluster.ts +429 -0
  7. package/Models/DatabaseModels/Monitor.ts +48 -0
  8. package/Models/DatabaseModels/Runner.ts +5 -4
  9. package/Models/DatabaseModels/RunnerJob.ts +66 -0
  10. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +10 -2
  11. package/Models/DatabaseModels/WorkflowVariable.ts +479 -2
  12. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +79 -25
  13. package/Server/API/AIInvestigationAPI.ts +341 -0
  14. package/Server/API/AutoRemediationAPI.ts +184 -2
  15. package/Server/API/CommonAPI.ts +70 -0
  16. package/Server/API/KubernetesClusterAiAccessAPI.ts +793 -0
  17. package/Server/API/MicrosoftTeamsAPI.ts +770 -315
  18. package/Server/API/MonitorAPI.ts +140 -0
  19. package/Server/API/OnCallScheduleTimelineAPI.ts +5 -21
  20. package/Server/API/SlackAPI.ts +447 -99
  21. package/Server/API/StatusPageAPI.ts +146 -26
  22. package/Server/API/TelemetryAPI.ts +216 -5
  23. package/Server/API/UserTwoFactorBackupCodeAPI.ts +1 -0
  24. package/Server/API/WorkflowVariableAPI.ts +156 -0
  25. package/Server/Infrastructure/GlobalCache.ts +35 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.ts +97 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.ts +129 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.ts +25 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.ts +20 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.ts +38 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  32. package/Server/Middleware/MasterAdminAuthorization.ts +28 -0
  33. package/Server/Middleware/TelemetryIngest.ts +47 -2
  34. package/Server/Middleware/UserAuthorization.ts +56 -2
  35. package/Server/Services/AIAgentService.ts +1 -0
  36. package/Server/Services/AccessTokenService.ts +121 -48
  37. package/Server/Services/AlertEpisodeMemberService.ts +9 -0
  38. package/Server/Services/AlertEpisodeService.ts +14 -1
  39. package/Server/Services/AlertService.ts +134 -22
  40. package/Server/Services/AutoRemediationRuleEngineService.ts +968 -39
  41. package/Server/Services/AutoRemediationRuleService.ts +118 -0
  42. package/Server/Services/BillingService.ts +1 -0
  43. package/Server/Services/InboundEmail/Providers/SendGridInboundProvider.ts +16 -22
  44. package/Server/Services/IncidentEpisodeMemberService.ts +9 -0
  45. package/Server/Services/IncidentEpisodePublicNoteService.ts +66 -0
  46. package/Server/Services/IncidentEpisodeRoleMemberService.ts +27 -0
  47. package/Server/Services/IncidentEpisodeService.ts +14 -1
  48. package/Server/Services/IncidentGroupingEngineService.ts +11 -0
  49. package/Server/Services/IncidentMemberService.ts +21 -0
  50. package/Server/Services/IncidentPublicNoteService.ts +63 -0
  51. package/Server/Services/IncidentService.ts +120 -20
  52. package/Server/Services/IncidentStateTimelineService.ts +15 -0
  53. package/Server/Services/IncidentTemplateService.ts +83 -3
  54. package/Server/Services/KubernetesClusterAiAccessService.ts +1943 -0
  55. package/Server/Services/KubernetesClusterService.ts +1570 -1
  56. package/Server/Services/LogAggregationService.ts +14 -6
  57. package/Server/Services/MonitorService.ts +651 -52
  58. package/Server/Services/MonitorStatusTimelineService.ts +639 -2
  59. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +2 -0
  60. package/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.ts +2 -0
  61. package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +2 -0
  62. package/Server/Services/OnCallDutyPolicyScheduleService.ts +3 -0
  63. package/Server/Services/OnCallNotificationAlertingService.ts +36 -12
  64. package/Server/Services/OnCallSetupReminderService.ts +1 -0
  65. package/Server/Services/ProbeService.ts +7 -1
  66. package/Server/Services/ProjectService.ts +11 -1
  67. package/Server/Services/RunbookCredentialService.ts +26 -1
  68. package/Server/Services/RunbookSecretService.ts +36 -0
  69. package/Server/Services/RunnerJobService.ts +941 -23
  70. package/Server/Services/RunnerService.ts +439 -6
  71. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +66 -0
  72. package/Server/Services/ScheduledMaintenanceService.ts +124 -19
  73. package/Server/Services/ScheduledMaintenanceTemplateService.ts +82 -3
  74. package/Server/Services/ServiceLevelObjectiveService.ts +14 -1
  75. package/Server/Services/StatusPagePrivateUserService.ts +1 -0
  76. package/Server/Services/StatusPageService.ts +301 -74
  77. package/Server/Services/StatusPageSubscriberService.ts +4 -0
  78. package/Server/Services/TeamMemberService.ts +309 -7
  79. package/Server/Services/TraceAggregationService.ts +10 -6
  80. package/Server/Services/UserEmailService.ts +1 -0
  81. package/Server/Services/UserNotificationMethodAdminService.ts +1 -0
  82. package/Server/Services/UserNotificationRuleAdminService.ts +1 -0
  83. package/Server/Services/UserNotificationRuleService.ts +4 -0
  84. package/Server/Services/UserService.ts +122 -1
  85. package/Server/Services/WorkflowVariableService.ts +593 -8
  86. package/Server/Services/WorkspaceNotificationRuleService.ts +588 -8
  87. package/Server/Services/WorkspaceProjectAuthTokenService.ts +170 -1
  88. package/Server/Types/Database/QueryHelper.ts +22 -0
  89. package/Server/Types/Markdown.ts +502 -27
  90. package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +182 -0
  91. package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +525 -0
  92. package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +854 -0
  93. package/Server/Utils/AI/CodeFix/CodeFixAgentAuth.ts +22 -2
  94. package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +1916 -307
  95. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +1601 -74
  96. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +139 -7
  97. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +58 -1
  98. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +54 -1
  99. package/Server/Utils/AI/Toolbox/AIActionTools.ts +14 -6
  100. package/Server/Utils/AI/Toolbox/ResourceTools.ts +4 -2
  101. package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +1341 -150
  102. package/Server/Utils/AutoRemediation/RemediationVerifier.ts +375 -4
  103. package/Server/Utils/Database/AffectedResourceRelations.ts +127 -0
  104. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +240 -1
  105. package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +1 -0
  106. package/Server/Utils/Monitor/MonitorAlert.ts +83 -9
  107. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +5 -1
  108. package/Server/Utils/Monitor/MonitorIncident.ts +104 -9
  109. package/Server/Utils/Monitor/MonitorPayloadRedaction.ts +124 -7
  110. package/Server/Utils/Monitor/ProbeMonitorsNotification.ts +407 -0
  111. package/Server/Utils/OnCall/OnCallShiftReminderRunner.ts +1 -0
  112. package/Server/Utils/PushNotificationUtil.ts +45 -0
  113. package/Server/Utils/Rules/OwnerRuleAssignment.ts +40 -3
  114. package/Server/Utils/Runbook/RunbookExecutePermission.ts +56 -6
  115. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +223 -33
  116. package/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.ts +559 -0
  117. package/Server/Utils/StartServer.ts +4 -3
  118. package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +528 -0
  119. package/Server/Utils/TwoFactorBackupCodeNotification.ts +1 -0
  120. package/Server/Utils/UserPermission/UserPermission.ts +16 -0
  121. package/Server/Utils/Workflow/OAuth2TokenClient.ts +704 -0
  122. package/Server/Utils/Workflow/WorkflowVariableOAuthToken.ts +318 -0
  123. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +47 -7
  124. package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +57 -16
  125. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +193 -214
  126. package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +57 -13
  127. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.ts +54 -17
  128. package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +179 -161
  129. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +281 -167
  130. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.ts +114 -0
  131. package/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.ts +895 -0
  132. package/Server/Utils/Workspace/Slack/Actions/ActionTypes.ts +7 -9
  133. package/Server/Utils/Workspace/Slack/Actions/Alert.ts +96 -227
  134. package/Server/Utils/Workspace/Slack/Actions/AlertEpisode.ts +93 -214
  135. package/Server/Utils/Workspace/Slack/Actions/Auth.ts +30 -3
  136. package/Server/Utils/Workspace/Slack/Actions/Authorization.ts +99 -0
  137. package/Server/Utils/Workspace/Slack/Actions/Incident.ts +117 -283
  138. package/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.ts +101 -196
  139. package/Server/Utils/Workspace/Slack/Actions/ReactionNote.ts +329 -0
  140. package/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.ts +111 -287
  141. package/Server/Utils/Workspace/Slack/Slack.ts +86 -17
  142. package/Server/Utils/Workspace/Slack/app-manifest.json +2 -0
  143. package/Server/Utils/Workspace/Workspace.ts +171 -54
  144. package/Server/Utils/Workspace/WorkspaceActionAuthorization.ts +252 -0
  145. package/Server/Utils/Workspace/WorkspaceBase.ts +39 -0
  146. package/Server/Utils/Workspace/WorkspaceOAuthState.ts +280 -0
  147. package/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.ts +96 -0
  148. package/Server/Utils/Workspace/WorkspaceReactionNote.ts +620 -0
  149. package/Tests/App/Dashboard/AttributesJSONDashboardSurfaces.test.tsx +496 -0
  150. package/Tests/App/Dashboard/AutoRemediationRulesTableCommandRunners.test.tsx +152 -0
  151. package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +32 -0
  152. package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +794 -0
  153. package/Tests/App/Dashboard/CreateOAuthWorkflowVariableModal.test.tsx +840 -0
  154. package/Tests/App/Dashboard/CreateWorkflowModal.test.tsx +653 -0
  155. package/Tests/App/Dashboard/DatabaseMonitorStepForm.test.tsx +197 -0
  156. package/Tests/App/Dashboard/DatabaseMonitorView.test.tsx +376 -0
  157. package/Tests/App/Dashboard/DisabledWarningRobustness.test.tsx +262 -0
  158. package/Tests/App/Dashboard/EventNotes.test.tsx +2080 -0
  159. package/Tests/App/Dashboard/EventNotesPages.test.tsx +486 -0
  160. package/Tests/App/Dashboard/EventNotesUtil.test.ts +933 -0
  161. package/Tests/App/Dashboard/ExceptionMonitorEnvironmentFilter.test.tsx +218 -0
  162. package/Tests/App/Dashboard/IncidentChangeStateNotifyDefault.test.tsx +665 -0
  163. package/Tests/App/Dashboard/IncidentEpisodeFeedPublicNoteNotifyDefault.test.tsx +494 -0
  164. package/Tests/App/Dashboard/IncidentEpisodeOverviewNotifyDefault.test.tsx +706 -0
  165. package/Tests/App/Dashboard/IncidentFeedPublicNoteNotifyDefault.test.tsx +472 -0
  166. package/Tests/App/Dashboard/IncidentOverviewNotifyDefault.test.tsx +858 -0
  167. package/Tests/App/Dashboard/IncomingEmailAddressSettings.test.tsx +567 -0
  168. package/Tests/App/Dashboard/InvestigationClusterToolFormat.test.ts +241 -0
  169. package/Tests/App/Dashboard/InvestigationEvidenceKubectl.test.tsx +322 -0
  170. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +12 -0
  171. package/Tests/App/Dashboard/InvestigationPanelClusterAccess.test.tsx +476 -0
  172. package/Tests/App/Dashboard/InvestigationRunDetailsKubectl.test.tsx +383 -0
  173. package/Tests/App/Dashboard/KubectlActivitySummary.test.tsx +366 -0
  174. package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +2886 -0
  175. package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +2688 -0
  176. package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +915 -0
  177. package/Tests/App/Dashboard/LayerDateTimeFieldTimezoneName.test.tsx +66 -0
  178. package/Tests/App/Dashboard/LogMonitorPreview.test.tsx +174 -0
  179. package/Tests/App/Dashboard/MonitorFeedRefresh.test.tsx +279 -0
  180. package/Tests/App/Dashboard/MonitorMetricQueryConfig.test.ts +244 -0
  181. package/Tests/App/Dashboard/MonitorOpenWorkCard.test.tsx +381 -0
  182. package/Tests/App/Dashboard/MonitorOpenWorkHook.test.tsx +784 -0
  183. package/Tests/App/Dashboard/MonitorOverviewData.test.tsx +2199 -0
  184. package/Tests/App/Dashboard/MonitorOverviewHero.test.tsx +1169 -0
  185. package/Tests/App/Dashboard/MonitorOverviewInput.test.ts +1127 -0
  186. package/Tests/App/Dashboard/MonitorOverviewPage.test.tsx +2136 -0
  187. package/Tests/App/Dashboard/MonitorOverviewSelectReadable.test.ts +368 -0
  188. package/Tests/App/Dashboard/MonitorOverviewStatBar.test.tsx +526 -0
  189. package/Tests/App/Dashboard/MonitorOverviewSupportingCards.test.tsx +542 -0
  190. package/Tests/App/Dashboard/MonitorOwnersCombine.test.ts +299 -0
  191. package/Tests/App/Dashboard/MonitorProbesCard.test.tsx +602 -0
  192. package/Tests/App/Dashboard/MonitorResponseTimeCard.test.tsx +386 -0
  193. package/Tests/App/Dashboard/MonitorSetupAndConnectionCards.test.tsx +612 -0
  194. package/Tests/App/Dashboard/MonitorStatusChangesCard.test.tsx +257 -0
  195. package/Tests/App/Dashboard/MonitorSummaryTestMonitorButton.test.tsx +360 -1
  196. package/Tests/App/Dashboard/MonitorUptimeHistoryCard.test.tsx +835 -0
  197. package/Tests/App/Dashboard/MonitorUptimeSummaryHook.test.tsx +971 -0
  198. package/Tests/App/Dashboard/MonitorViewLayout.test.tsx +580 -0
  199. package/Tests/App/Dashboard/OnCallLayerRestrictionTimesPreserved.test.tsx +441 -0
  200. package/Tests/App/Dashboard/OnCallNavbar.test.tsx +214 -0
  201. package/Tests/App/Dashboard/OnCallSchedulePreviewCalendarDisplay.test.tsx +1389 -0
  202. package/Tests/App/Dashboard/OnCallSchedulePreviewOverrides.test.tsx +205 -1
  203. package/Tests/App/Dashboard/OnCallScheduleTimeInputsSettingsZone.test.tsx +198 -0
  204. package/Tests/App/Dashboard/PublicNotePagesNotifyDefault.test.tsx +524 -0
  205. package/Tests/App/Dashboard/RemediationSuggestionCardApproval.test.tsx +702 -0
  206. package/Tests/App/Dashboard/RemoveUserFromProject.test.tsx +427 -0
  207. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +4 -0
  208. package/Tests/App/Dashboard/RumSessionReplaySideMenu.test.tsx +3 -1
  209. package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +166 -0
  210. package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +622 -0
  211. package/Tests/App/Dashboard/ScheduledMaintenanceChangeStateNotifyDefault.test.tsx +1491 -0
  212. package/Tests/App/Dashboard/ScheduledMaintenanceFeedPublicNoteNotifyDefault.test.tsx +489 -0
  213. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewNotifyDefault.test.tsx +909 -0
  214. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +14 -0
  215. package/Tests/App/Dashboard/ScheduledMaintenanceWindowStatsTranslation.test.tsx +307 -0
  216. package/Tests/App/Dashboard/SecurityEventAttributeColumnPicker.test.tsx +542 -0
  217. package/Tests/App/Dashboard/SecurityEventConnectionFormModal.test.tsx +174 -0
  218. package/Tests/App/Dashboard/SecurityEventConnectionsEmptyState.test.tsx +973 -212
  219. package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +491 -52
  220. package/Tests/App/Dashboard/SecurityEventDetailPanel.test.tsx +301 -0
  221. package/Tests/App/Dashboard/SecurityEventListRow.test.tsx +158 -1
  222. package/Tests/App/Dashboard/SecurityEventProviderTile.test.tsx +869 -0
  223. package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +959 -94
  224. package/Tests/App/Dashboard/SecurityEventsNoResults.test.tsx +2 -0
  225. package/Tests/App/Dashboard/SecurityEventsViewer.test.tsx +274 -1
  226. package/Tests/App/Dashboard/TeamMembershipRemoval.test.ts +900 -0
  227. package/Tests/App/Dashboard/TeamMembershipRemovalPages.test.tsx +460 -0
  228. package/Tests/App/Dashboard/TimezoneElements.test.tsx +321 -0
  229. package/Tests/App/Dashboard/TimezoneSelectButton.test.tsx +634 -0
  230. package/Tests/App/Dashboard/TraceExplorer.test.tsx +260 -0
  231. package/Tests/App/Dashboard/TraceMonitorPreview.test.tsx +182 -0
  232. package/Tests/App/Dashboard/UserTimezoneInit.test.tsx +544 -0
  233. package/Tests/App/Dashboard/WorkflowVariableModals.test.tsx +1630 -0
  234. package/Tests/App/Dashboard/WorkflowVariableRoutes.test.tsx +603 -0
  235. package/Tests/App/Dashboard/WorkflowVariableTokenStatus.test.tsx +589 -0
  236. package/Tests/App/Dashboard/WorkflowVariableUtil.test.ts +1543 -0
  237. package/Tests/App/Dashboard/WorkflowVariableView.test.tsx +3227 -0
  238. package/Tests/App/Dashboard/WorkflowVariablesTable.test.tsx +1277 -395
  239. package/Tests/App/StatusPage/StatusPageOverviewMonitorGroupUptime.test.tsx +714 -0
  240. package/Tests/App/StatusPage/StatusPageOverviewUptimeBars.NewYork.test.tsx +1009 -0
  241. package/Tests/App/StatusPage/StatusPageOverviewUptimeBars.test.tsx +1092 -0
  242. package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +5 -0
  243. package/Tests/Models/DatabaseModels/KubernetesClusterAiAccessColumns.test.ts +520 -0
  244. package/Tests/Models/DatabaseModels/MonitorSecretKeyColumnAccessControl.test.ts +66 -2
  245. package/Tests/Models/DatabaseModels/WorkspaceProjectAuthTokenAccessControl.test.ts +236 -0
  246. package/Tests/Models/IncidentEpisodePublicNoteNotifyColumnContract.test.ts +103 -0
  247. package/Tests/Models/IncidentPublicNoteNotifyColumnContract.test.ts +96 -0
  248. package/Tests/Models/ScheduledMaintenancePublicNoteNotifyColumnContract.test.ts +111 -0
  249. package/Tests/Server/API/AIInvestigationAPI.test.ts +976 -0
  250. package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +836 -0
  251. package/Tests/Server/API/CommonAPIAssertCanCreateTable.test.ts +565 -0
  252. package/Tests/Server/API/CommonAPIAssertCanReadTable.test.ts +282 -0
  253. package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +1744 -0
  254. package/Tests/Server/API/LogHistogramAPI.test.ts +371 -0
  255. package/Tests/Server/API/MicrosoftTeamsLegacyWebhookRemoval.test.ts +125 -30
  256. package/Tests/Server/API/MicrosoftTeamsOAuthState.test.ts +1121 -0
  257. package/Tests/Server/API/MonitorUptimeSummaryAPI.test.ts +685 -0
  258. package/Tests/Server/API/SessionReplayAPI.test.ts +602 -1
  259. package/Tests/Server/API/SlackChannelCacheAPI.test.ts +358 -0
  260. package/Tests/Server/API/SlackOAuthState.test.ts +688 -0
  261. package/Tests/Server/API/StatusPageOverviewMonitorGroupUptime.test.ts +527 -0
  262. package/Tests/Server/API/StatusPageTestEmailReportAuth.test.ts +2 -0
  263. package/Tests/Server/API/StatusPageUptimeAPI.test.ts +427 -0
  264. package/Tests/Server/API/UserProjectsAPI.test.ts +4 -0
  265. package/Tests/Server/API/WorkflowVariableAPI.test.ts +404 -0
  266. package/Tests/Server/API/WorkspaceOAuthTestHelpers.ts +289 -0
  267. package/Tests/Server/API/WorkspaceSendTestNotificationRoutes.test.ts +2064 -0
  268. package/Tests/Server/Infrastructure/GlobalCache.test.ts +86 -0
  269. package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +589 -0
  270. package/Tests/Server/Infrastructure/Postgres/AddOAuth2WorkflowVariablesMigration.test.ts +254 -0
  271. package/Tests/Server/Middleware/BlockedUserMiddleware.test.ts +403 -0
  272. package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +13 -0
  273. package/Tests/Server/Middleware/PublicRouteUserMiddleware.test.ts +2 -0
  274. package/Tests/Server/Middleware/RemovedProjectMemberAuthorization.test.ts +469 -0
  275. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +77 -1
  276. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +211 -0
  277. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +358 -0
  278. package/Tests/Server/Middleware/UserAuthorization.test.ts +97 -0
  279. package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +2 -0
  280. package/Tests/Server/Services/AccessTokenProjectUserGrant.test.ts +14 -2
  281. package/Tests/Server/Services/AccessTokenRemovedMemberAccess.test.ts +1044 -0
  282. package/Tests/Server/Services/AddOwnersIdempotency.test.ts +5 -0
  283. package/Tests/Server/Services/AlertEpisodeMemberCreatePermission.test.ts +139 -0
  284. package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +1361 -0
  285. package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +375 -0
  286. package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +2384 -0
  287. package/Tests/Server/Services/FindOwnersProjectMembership.test.ts +267 -0
  288. package/Tests/Server/Services/InboundEmail/SendGridInboundProviderAddress.test.ts +90 -0
  289. package/Tests/Server/Services/IncidentEpisodeMemberCreatePermission.test.ts +143 -0
  290. package/Tests/Server/Services/IncidentEpisodePublicNoteNotifyDefault.test.ts +805 -0
  291. package/Tests/Server/Services/IncidentPublicNoteNotifyDefault.test.ts +724 -0
  292. package/Tests/Server/Services/IncidentRoleProjectMembership.test.ts +233 -0
  293. package/Tests/Server/Services/KubernetesClusterAiAccessAgentRunnerAssignments.test.ts +372 -0
  294. package/Tests/Server/Services/KubernetesClusterAiAccessBindingGuard.test.ts +1876 -0
  295. package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +620 -0
  296. package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +421 -0
  297. package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +3662 -0
  298. package/Tests/Server/Services/KubernetesClusterAiAccessSubjectClusters.test.ts +405 -0
  299. package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +975 -0
  300. package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +497 -0
  301. package/Tests/Server/Services/KubernetesClusterServiceDeleteSettlesRemediation.test.ts +328 -0
  302. package/Tests/Server/Services/LogAggregationService.test.ts +99 -0
  303. package/Tests/Server/Services/MonitorServiceIncomingEmailCustomAddress.test.ts +447 -0
  304. package/Tests/Server/Services/MonitorServiceProbeFlagSync.test.ts +1334 -0
  305. package/Tests/Server/Services/MonitorServiceProbeStatusGrouping.test.ts +1640 -0
  306. package/Tests/Server/Services/MonitorServiceRefreshCurrentStatus.test.ts +225 -0
  307. package/Tests/Server/Services/MonitorStatusBridgeProbePath.test.ts +8 -8
  308. package/Tests/Server/Services/MonitorStatusTimelineDailyAggregates.test.ts +264 -1
  309. package/Tests/Server/Services/MonitorStatusTimelineMergedDowntime.test.ts +284 -0
  310. package/Tests/Server/Services/MonitorUptimeSummaryService.test.ts +1043 -0
  311. package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +5 -0
  312. package/Tests/Server/Services/OnCallUndeliverablePageOwnerMembership.test.ts +359 -0
  313. package/Tests/Server/Services/ProbeServiceDashboardLink.test.ts +191 -0
  314. package/Tests/Server/Services/ProjectOwnersProjectMembership.test.ts +221 -0
  315. package/Tests/Server/Services/RuleRun/IncidentAlertMaintenanceRuleEnginesRun.test.ts +5 -0
  316. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupARun.test.ts +28 -0
  317. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +9 -1
  318. package/Tests/Server/Services/RunnerJobEnqueueAiCommandAgentRunner.test.ts +230 -0
  319. package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +978 -0
  320. package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +866 -0
  321. package/Tests/Server/Services/RunnerJobSubmitResultRedaction.test.ts +322 -0
  322. package/Tests/Server/Services/RunnerJobSubmitResultUnstorableText.test.ts +357 -0
  323. package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +227 -0
  324. package/Tests/Server/Services/RunnerServiceAgentName.test.ts +581 -0
  325. package/Tests/Server/Services/ScheduledMaintenancePublicNoteNotifyDefault.test.ts +802 -0
  326. package/Tests/Server/Services/ScheduledMaintenanceSubscriberTemplateFormats.test.ts +53 -0
  327. package/Tests/Server/Services/ServiceLevelObjectiveLabelAndOwnerRuleEngines.test.ts +5 -0
  328. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +12 -0
  329. package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +1176 -1
  330. package/Tests/Server/Services/TeamMemberBillingSeatSync.test.ts +9 -0
  331. package/Tests/Server/Services/TeamMemberOnCallCleanup.test.ts +18 -0
  332. package/Tests/Server/Services/TeamMemberProjectMembership.test.ts +255 -0
  333. package/Tests/Server/Services/TeamMemberRemovalRevokesProjectAccess.test.ts +600 -0
  334. package/Tests/Server/Services/TeamMemberResourceCleanup.test.ts +731 -0
  335. package/Tests/Server/Services/TeamMemberWorkspaceAccountCleanup.test.ts +164 -0
  336. package/Tests/Server/Services/TraceAggregationService.test.ts +64 -0
  337. package/Tests/Server/Services/UserServiceBlockedUser.test.ts +293 -0
  338. package/Tests/Server/Services/WorkflowVariableOAuthHooks.test.ts +1016 -0
  339. package/Tests/Server/Services/WorkflowVariableOAuthPostgres.test.ts +543 -0
  340. package/Tests/Server/Services/WorkflowVariableRenameUniqueness.test.ts +16 -5
  341. package/Tests/Server/Services/WorkspaceNotificationRuleNoteDelivery.test.ts +473 -0
  342. package/Tests/Server/Services/WorkspaceNotificationRuleSendTestNotification.test.ts +3690 -0
  343. package/Tests/Server/Services/WorkspaceProjectAuthTokenMiscDataSecrets.test.ts +374 -0
  344. package/Tests/Server/Services/WorkspaceProjectAuthTokenSlackChannelCache.test.ts +143 -0
  345. package/Tests/Server/Types/Database/Permissions/WorkflowVariableOAuthColumnPermission.test.ts +250 -0
  346. package/Tests/Server/Types/Database/QueryHelperJsonContains.test.ts +96 -0
  347. package/Tests/Server/Types/Markdown.test.ts +1033 -0
  348. package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +285 -0
  349. package/Tests/Server/Utils/AI/CodeFix/CodeFixAgentAuth.test.ts +159 -1
  350. package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +752 -0
  351. package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +1840 -0
  352. package/Tests/Server/Utils/AI/KubectlJobRunner.test.ts +1067 -0
  353. package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +355 -0
  354. package/Tests/Server/Utils/AI/PostIncidentStatusUpdateTool.test.ts +496 -0
  355. package/Tests/Server/Utils/AI/RemediationCommandTools.test.ts +305 -0
  356. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +1365 -0
  357. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +639 -0
  358. package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +1585 -0
  359. package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +1065 -0
  360. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +2138 -1
  361. package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +1035 -0
  362. package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +517 -0
  363. package/Tests/Server/Utils/AI/ResourceTools.test.ts +27 -1
  364. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +1371 -24
  365. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorRollbackRace.test.ts +962 -0
  366. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +518 -0
  367. package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +939 -2
  368. package/Tests/Server/Utils/Database/ProjectScopedRelationReferences.test.ts +371 -0
  369. package/Tests/Server/Utils/Monitor/AffectedResourceList.test.ts +64 -0
  370. package/Tests/Server/Utils/Monitor/DatabaseMetricObservationRemediation.test.ts +102 -0
  371. package/Tests/Server/Utils/Monitor/MonitorAlertCriteriaReferences.test.ts +362 -0
  372. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorBreachingSamples.test.ts +55 -0
  373. package/Tests/Server/Utils/Monitor/MonitorEmailAddressRedaction.test.ts +255 -0
  374. package/Tests/Server/Utils/Monitor/MonitorIncidentCriteriaReferences.test.ts +347 -0
  375. package/Tests/Server/Utils/Monitor/MonitorIncidentMemberRoleMembership.test.ts +203 -0
  376. package/Tests/Server/Utils/Monitor/ProbeMonitorsNotification.test.ts +1147 -0
  377. package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +79 -0
  378. package/Tests/Server/Utils/ResourceFeed/ResourceFeedUtil.test.ts +21 -1
  379. package/Tests/Server/Utils/Rules/OwnerRuleAssignment.test.ts +155 -1
  380. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +288 -0
  381. package/Tests/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.test.ts +304 -0
  382. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +40 -3
  383. package/Tests/Server/Utils/Workflow/OAuth2TokenClient.test.ts +702 -0
  384. package/Tests/Server/Utils/Workflow/OAuth2TokenClientHttpIntegration.test.ts +507 -0
  385. package/Tests/Server/Utils/Workflow/WorkflowVariableOAuthToken.test.ts +831 -0
  386. package/Tests/Server/Utils/Workspace/MicrosoftTeamsActionAuthorization.test.ts +63 -1
  387. package/Tests/Server/Utils/Workspace/MicrosoftTeamsAppAccessToken.test.ts +256 -0
  388. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +60 -0
  389. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChatActionAuthorization.test.ts +442 -0
  390. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +44 -2
  391. package/Tests/Server/Utils/Workspace/MicrosoftTeamsDirectMessage.test.ts +55 -0
  392. package/Tests/Server/Utils/Workspace/MicrosoftTeamsReactionNoteSync.test.ts +1522 -0
  393. package/Tests/Server/Utils/Workspace/MicrosoftTeamsServiceUrl.test.ts +130 -0
  394. package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +4 -4
  395. package/Tests/Server/Utils/Workspace/Slack/SlackActionAuthorization.test.ts +691 -0
  396. package/Tests/Server/Utils/Workspace/Slack/SlackMessageByTimestamp.test.ts +253 -0
  397. package/Tests/Server/Utils/Workspace/Slack/SlackReactionNote.test.ts +574 -0
  398. package/Tests/Server/Utils/Workspace/WorkspaceActionAuthorization.test.ts +488 -0
  399. package/Tests/Server/Utils/Workspace/WorkspaceCreateProjectReferences.test.ts +861 -0
  400. package/Tests/Server/Utils/Workspace/WorkspaceMessageAuthor.test.ts +635 -0
  401. package/Tests/Server/Utils/Workspace/WorkspaceOAuthState.test.ts +548 -0
  402. package/Tests/Server/Utils/Workspace/WorkspaceReactionNote.test.ts +839 -0
  403. package/Tests/Server/Utils/Workspace/WorkspaceSendErrorMessage.test.ts +725 -0
  404. package/Tests/Types/AutoRemediation/AiRemediationCommandPlan.test.ts +283 -9
  405. package/Tests/Types/DateBrowserLocalWallClock.test.ts +280 -0
  406. package/Tests/Types/DateLocalShortMonthNameFallback.test.ts +389 -0
  407. package/Tests/Types/DateUserTimezone.test.ts +177 -4
  408. package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +306 -0
  409. package/Tests/Types/Kubernetes/KubernetesClusterAiAccess.test.ts +283 -0
  410. package/Tests/Types/Kubernetes/KubernetesRunnerPostureWriteScope.test.ts +68 -0
  411. package/Tests/Types/Monitor/DatabaseMonitor/SqlServerPlatform.test.ts +144 -0
  412. package/Tests/Types/Monitor/MonitorStepExceptionMonitor.test.ts +160 -0
  413. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +53 -0
  414. package/Tests/Types/Runbook/RunbookStepType.test.ts +91 -16
  415. package/Tests/Types/Runner/RunnerLiveStatus.test.ts +14 -3
  416. package/Tests/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.test.ts +15 -0
  417. package/Tests/Types/StatusPage/PublicNoteSubscriberNotificationDefault.test.ts +1868 -0
  418. package/Tests/Types/Timezone.test.ts +5 -0
  419. package/Tests/Types/TimezoneAlias.test.ts +1034 -0
  420. package/Tests/Types/Workflow/JiraTemplateFixtures.ts +833 -0
  421. package/Tests/Types/Workflow/JiraTemplateScripts.test.ts +5414 -0
  422. package/Tests/Types/Workflow/JiraTemplateSimulation.test.ts +4803 -0
  423. package/Tests/Types/Workflow/JiraTemplates.test.ts +5429 -0
  424. package/Tests/Types/Workflow/Templates.test.ts +79 -4
  425. package/Tests/Types/Workflow/WorkflowVariableOAuth.test.ts +520 -0
  426. package/Tests/Types/Workspace/WorkspaceNoteReaction.test.ts +177 -0
  427. package/Tests/UI/Components/AttributesJSON/AttributesJSONView.test.tsx +390 -0
  428. package/Tests/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.test.tsx +566 -0
  429. package/Tests/UI/Components/AttributesJSON/JSONHighlight.test.ts +131 -0
  430. package/Tests/UI/Components/BasicFormDropdownNormalization.test.tsx +276 -1
  431. package/Tests/UI/Components/Calendar/Calendar.test.tsx +1611 -0
  432. package/Tests/UI/Components/Calendar/CalendarDayLayout.test.ts +1486 -0
  433. package/Tests/UI/Components/Calendar/CalendarDayLayoutDst.test.ts +632 -0
  434. package/Tests/UI/Components/Calendar/CalendarDst.test.tsx +388 -0
  435. package/Tests/UI/Components/Charts/ChartGroupPlotFloor.test.tsx +170 -0
  436. package/Tests/UI/Components/Charts/HistogramSelection.test.ts +282 -0
  437. package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +6 -0
  438. package/Tests/UI/Components/CustomTimeRangeModalTimezoneTranslation.test.tsx +285 -0
  439. package/Tests/UI/Components/Dropdown.test.tsx +999 -2
  440. package/Tests/UI/Components/Forms/FormFieldCheckboxTranslation.test.tsx +216 -0
  441. package/Tests/UI/Components/Forms/FormFieldTimezoneDescriptionTranslation.test.tsx +461 -0
  442. package/Tests/UI/Components/Forms/IncidentEpisodePublicNoteNotifyPayload.test.tsx +641 -0
  443. package/Tests/UI/Components/Forms/IncidentPublicNoteNotifyPayload.test.tsx +346 -0
  444. package/Tests/UI/Components/Forms/ScheduledMaintenancePublicNoteNotifyPayload.test.tsx +493 -0
  445. package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +911 -2
  446. package/Tests/UI/Components/Graphs/DayUptimeGraphTimezone.NewYork.test.tsx +730 -0
  447. package/Tests/UI/Components/Graphs/DayUptimeGraphTimezone.Tokyo.test.tsx +506 -0
  448. package/Tests/UI/Components/HistogramClickToZoom.test.tsx +619 -0
  449. package/Tests/UI/Components/LogDetailsPanelAttributesJSON.test.tsx +248 -0
  450. package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +47 -1
  451. package/Tests/UI/Components/LogsViewerSmallScreens.test.tsx +620 -0
  452. package/Tests/UI/Components/ModelPageModelChange.test.tsx +242 -3
  453. package/Tests/UI/Components/ModelTable/BaseModelTableDeleteConfirmation.test.tsx +521 -0
  454. package/Tests/UI/Components/MonitorGraphs/Uptime.test.tsx +406 -2
  455. package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +169 -2
  456. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +266 -0
  457. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerSmallScreens.test.tsx +439 -0
  458. package/Tests/UI/Components/TimezoneDropdownLegacyValues.test.tsx +704 -0
  459. package/Tests/UI/Components/UseHistogramZoom.test.tsx +89 -1
  460. package/Tests/UI/Components/UseLogsHistogram.test.tsx +175 -0
  461. package/Tests/UI/Monitor/MonitorSummarySnapshotRender.test.tsx +5 -5
  462. package/Tests/UI/Telemetry/TelemetryDetailPanel.test.tsx +28 -0
  463. package/Tests/UI/Utils/ProjectUsersModelAPI.test.ts +51 -0
  464. package/Tests/UI/Utils/Timezone.test.ts +747 -33
  465. package/Tests/UI/Workspace/SendTestNotificationButton.test.tsx +1854 -0
  466. package/Tests/UI/Workspace/WorkspaceCardsSendTestNotification.test.tsx +1864 -0
  467. package/Tests/Utils/AI/InvestigationReport.test.ts +435 -7
  468. package/Tests/Utils/AiRemediation/KubectlAllowlistValidatorParity.test.ts +1084 -0
  469. package/Tests/Utils/AiRemediation/KubectlOutputRedactor.test.ts +2531 -0
  470. package/Tests/Utils/AiRemediation/KubectlPolicy.test.ts +1895 -0
  471. package/Tests/Utils/AiRemediation/KubectlPolicyAllowlist.test.ts +428 -0
  472. package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +828 -0
  473. package/Tests/Utils/AiRemediation/KubectlPolicyCustomResourceScope.test.ts +573 -0
  474. package/Tests/Utils/AiRemediation/KubectlPolicyDenials.test.ts +1525 -0
  475. package/Tests/Utils/AiRemediation/KubectlPolicyExposeOverrides.test.ts +275 -0
  476. package/Tests/Utils/AiRemediation/KubectlPolicyNodePatch.test.ts +428 -0
  477. package/Tests/Utils/AiRemediation/KubectlPolicyObjectWords.test.ts +195 -0
  478. package/Tests/Utils/AiRemediation/KubectlPolicyPatchParents.test.ts +637 -0
  479. package/Tests/Utils/AiRemediation/KubectlPolicyPodSecurityBaseline.test.ts +322 -0
  480. package/Tests/Utils/AiRemediation/KubectlPolicySafeWriteScope.test.ts +1026 -0
  481. package/Tests/Utils/AiRemediation/KubectlWaitBudget.test.ts +267 -0
  482. package/Tests/Utils/AiRemediation/KubectlWriteScope.test.ts +390 -0
  483. package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +777 -0
  484. package/Tests/Utils/AiRemediation/KubectlWriteScopeClusterScoped.test.ts +613 -0
  485. package/Tests/Utils/AiRemediation/KubectlWriteScopeEntryPoint.test.ts +576 -0
  486. package/Tests/Utils/AiRemediation/KubectlWriteScopeKubectlSpellings.test.ts +752 -0
  487. package/Tests/Utils/AiRemediation/KubectlWriteScopeObjectWords.test.ts +358 -0
  488. package/Tests/Utils/AiRemediation/KubectlWriteScopeOverrides.test.ts +293 -0
  489. package/Tests/Utils/AiRemediation/KubectlWriteScopeParityCases.ts +598 -0
  490. package/Tests/Utils/AiRemediation/KubectlWriteScopePolicyParity.test.ts +403 -0
  491. package/Tests/Utils/Dashboard/DashboardClockComponent.test.ts +154 -5
  492. package/Tests/Utils/Monitor/IncomingEmailMonitorAddress.test.ts +478 -0
  493. package/Tests/Utils/Monitor/MonitorCheckScheduleUtil.test.ts +646 -0
  494. package/Tests/Utils/Monitor/MonitorOverviewCriteriaUtil.test.ts +292 -0
  495. package/Tests/Utils/Monitor/MonitorOverviewFamily.test.ts +274 -0
  496. package/Tests/Utils/Monitor/MonitorOverviewPresentationUtil.test.ts +3100 -0
  497. package/Tests/Utils/Monitor/MonitorOverviewProbeUtil.test.ts +1412 -0
  498. package/Tests/Utils/Monitor/MonitorOverviewTargetUtil.test.ts +374 -0
  499. package/Tests/Utils/Monitor/MonitorStatusHistoryUtil.test.ts +332 -0
  500. package/Tests/Utils/Monitor/MonitorUptimeSummaryUtil.test.ts +946 -0
  501. package/Tests/Utils/Rum/SessionIdentity.test.ts +94 -0
  502. package/Tests/Utils/Rum/SessionReplayWafCompatibility.test.ts +840 -0
  503. package/Tests/Utils/Rum/SessionReplayWireEncoding.test.ts +208 -0
  504. package/Tests/Utils/Rum/UserFlow.test.ts +1010 -0
  505. package/Tests/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.test.ts +217 -0
  506. package/Tests/Utils/StatusPage/ResourceUptime.test.ts +1272 -1
  507. package/Tests/Utils/StatusPage/UptimeDailyAggregateTotals.test.ts +298 -0
  508. package/Tests/Utils/StatusPage/UptimeDailyAggregateUtil.test.ts +649 -1
  509. package/Tests/Utils/StatusPage/UptimeDailyAggregateWindow.test.ts +314 -0
  510. package/Tests/Utils/Telemetry/AttributesJSON.test.ts +454 -0
  511. package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +418 -2
  512. package/Tests/Utils/Uptime/DayUptimeGraphUtilMidnightDst.test.ts +160 -0
  513. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Auckland.test.ts +45 -0
  514. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Kolkata.test.ts +40 -0
  515. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.London.test.ts +147 -0
  516. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.NewYork.test.ts +48 -0
  517. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Tokyo.test.ts +39 -0
  518. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezoneCases.ts +1015 -0
  519. package/Tests/Utils/Uptime/UptimeUtil.test.ts +75 -0
  520. package/Tests/Utils/Uptime/UptimeUtilChronologicalOrder.test.ts +1279 -0
  521. package/Types/AutoRemediation/AiRemediationCommandPlan.ts +203 -5
  522. package/Types/Date.ts +121 -7
  523. package/Types/Email/EmailMessage.ts +8 -0
  524. package/Types/Email/EmailTemplateType.ts +1 -0
  525. package/Types/Exception/ExceptionMessages.ts +1 -0
  526. package/Types/Kubernetes/KubernetesClusterAiAccess.ts +488 -0
  527. package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +54 -0
  528. package/Types/Kubernetes/KubernetesClusterAiAccessToolNames.ts +17 -0
  529. package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +9 -0
  530. package/Types/Monitor/DatabaseMonitor/SqlServerPlatform.ts +117 -0
  531. package/Types/Monitor/KubernetesAlertTemplates.ts +6 -5
  532. package/Types/Monitor/MonitorStepExceptionMonitor.ts +56 -0
  533. package/Types/Monitor/MonitorUptimeSummary.ts +113 -0
  534. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +11 -0
  535. package/Types/Rum/SessionReplay.ts +55 -2
  536. package/Types/Rum/SessionReplayApi.ts +44 -1
  537. package/Types/Rum/UserFlow.ts +187 -0
  538. package/Types/Runbook/RunbookStepType.ts +10 -0
  539. package/Types/Runbook/RunnerJobOrigin.ts +15 -0
  540. package/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.ts +6 -2
  541. package/Types/StatusPage/MergedDowntimeTotals.ts +17 -0
  542. package/Types/StatusPage/PublicNoteSubscriberNotificationDefault.ts +148 -0
  543. package/Types/StatusPage/UptimeDailyAggregate.ts +15 -0
  544. package/Types/Telemetry/TelemetryIngestSurface.ts +9 -0
  545. package/Types/Timezone.ts +5 -0
  546. package/Types/TimezoneAlias.ts +385 -0
  547. package/Types/Workflow/Templates.ts +3041 -2
  548. package/Types/Workflow/WorkflowVariableOAuth.ts +476 -0
  549. package/Types/Workspace/WorkspaceNoteReaction.ts +132 -0
  550. package/Typings/Index.d.ts +24 -0
  551. package/UI/Components/AttributesJSON/AttributesJSONPreferences.ts +175 -0
  552. package/UI/Components/AttributesJSON/AttributesJSONView.tsx +138 -0
  553. package/UI/Components/AttributesJSON/AttributesViewToggle.tsx +79 -0
  554. package/UI/Components/AttributesJSON/BracesGlyph.tsx +30 -0
  555. package/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.tsx +491 -0
  556. package/UI/Components/AttributesJSON/JSONHighlight.ts +77 -0
  557. package/UI/Components/Calendar/Calendar.css +83 -0
  558. package/UI/Components/Calendar/Calendar.tsx +136 -7
  559. package/UI/Components/Calendar/CalendarDayLayout.ts +236 -0
  560. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +23 -1
  561. package/UI/Components/Charts/Utils/HistogramSelection.ts +117 -0
  562. package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +269 -0
  563. package/UI/Components/Charts/Utils/useHistogramZoom.ts +26 -2
  564. package/UI/Components/Date/CustomTimeRangeModal.tsx +26 -3
  565. package/UI/Components/Dropdown/Dropdown.tsx +58 -9
  566. package/UI/Components/Forms/Fields/FormField.tsx +49 -14
  567. package/UI/Components/Graphs/DayUptimeGraph.tsx +166 -25
  568. package/UI/Components/Graphs/UptimeBarTooltip.tsx +10 -2
  569. package/UI/Components/Graphs/UptimeDaySummary.tsx +8 -0
  570. package/UI/Components/LogsViewer/LogsViewer.tsx +52 -5
  571. package/UI/Components/LogsViewer/components/ColumnSelector.tsx +13 -2
  572. package/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.tsx +13 -1
  573. package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +91 -76
  574. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +15 -1
  575. package/UI/Components/LogsViewer/components/LogsHistogram.tsx +28 -106
  576. package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +54 -6
  577. package/UI/Components/LogsViewer/components/SavedViewsDropdown.tsx +8 -2
  578. package/UI/Components/LogsViewer/useLogsHistogram.ts +39 -6
  579. package/UI/Components/ModelTable/BaseModelTable.tsx +66 -14
  580. package/UI/Components/MonitorGraphs/Uptime.tsx +12 -0
  581. package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +10 -2
  582. package/UI/Components/Page/ModelPage.tsx +59 -3
  583. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +69 -5
  584. package/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.tsx +12 -1
  585. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +15 -1
  586. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +36 -104
  587. package/UI/Components/TelemetryViewer/components/TelemetrySearchBar.tsx +9 -1
  588. package/UI/Utils/ModelAPI/ProjectUsersModelAPI.ts +19 -1
  589. package/UI/Utils/Timezone.ts +69 -28
  590. package/Utils/AI/InvestigationReport.ts +195 -25
  591. package/Utils/AiRemediation/KubectlOutputRedactor.ts +1724 -0
  592. package/Utils/AiRemediation/KubectlPolicy.ts +4136 -0
  593. package/Utils/AiRemediation/KubectlWaitBudget.ts +156 -0
  594. package/Utils/AiRemediation/KubectlWriteScope.ts +1964 -0
  595. package/Utils/Dashboard/Components/DashboardClockComponent.ts +7 -6
  596. package/Utils/Monitor/IncomingEmailMonitorAddress.ts +292 -0
  597. package/Utils/Monitor/MonitorCheckScheduleUtil.ts +654 -0
  598. package/Utils/Monitor/MonitorOverviewCriteriaUtil.ts +188 -0
  599. package/Utils/Monitor/MonitorOverviewFamily.ts +263 -0
  600. package/Utils/Monitor/MonitorOverviewPresentationUtil.ts +1958 -0
  601. package/Utils/Monitor/MonitorOverviewProbeUtil.ts +979 -0
  602. package/Utils/Monitor/MonitorOverviewTargetUtil.ts +299 -0
  603. package/Utils/Monitor/MonitorStatusHistoryUtil.ts +201 -0
  604. package/Utils/Monitor/MonitorUptimeSummaryUtil.ts +638 -0
  605. package/Utils/Rum/SessionIdentity.ts +44 -0
  606. package/Utils/Rum/SessionReplayWireEncoding.ts +137 -0
  607. package/Utils/Rum/UserFlow.ts +1527 -0
  608. package/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.ts +107 -0
  609. package/Utils/StatusPage/ResourceUptime.ts +99 -0
  610. package/Utils/StatusPage/UptimeDailyAggregateUtil.ts +197 -0
  611. package/Utils/Telemetry/AttributesJSON.ts +367 -0
  612. package/Utils/Uptime/DayUptimeGraphUtil.ts +165 -0
  613. package/Utils/Uptime/UptimeUtil.ts +122 -38
  614. package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +8 -1
  615. package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -1
  616. package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js +62 -0
  617. package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js.map +1 -1
  618. package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js +8 -1
  619. package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js.map +1 -1
  620. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +10 -3
  621. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
  622. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +10 -3
  623. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  624. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +434 -0
  625. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  626. package/build/dist/Models/DatabaseModels/Monitor.js +49 -0
  627. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  628. package/build/dist/Models/DatabaseModels/Runner.js +4 -4
  629. package/build/dist/Models/DatabaseModels/Runner.js.map +1 -1
  630. package/build/dist/Models/DatabaseModels/RunnerJob.js +66 -0
  631. package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
  632. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +11 -3
  633. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  634. package/build/dist/Models/DatabaseModels/WorkflowVariable.js +487 -3
  635. package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
  636. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js +64 -16
  637. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  638. package/build/dist/Server/API/AIInvestigationAPI.js +205 -0
  639. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  640. package/build/dist/Server/API/AutoRemediationAPI.js +115 -2
  641. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  642. package/build/dist/Server/API/CommonAPI.js +49 -0
  643. package/build/dist/Server/API/CommonAPI.js.map +1 -1
  644. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +564 -0
  645. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -0
  646. package/build/dist/Server/API/MicrosoftTeamsAPI.js +465 -176
  647. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  648. package/build/dist/Server/API/MonitorAPI.js +107 -1
  649. package/build/dist/Server/API/MonitorAPI.js.map +1 -1
  650. package/build/dist/Server/API/OnCallScheduleTimelineAPI.js +5 -16
  651. package/build/dist/Server/API/OnCallScheduleTimelineAPI.js.map +1 -1
  652. package/build/dist/Server/API/SlackAPI.js +322 -78
  653. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  654. package/build/dist/Server/API/StatusPageAPI.js +123 -17
  655. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  656. package/build/dist/Server/API/TelemetryAPI.js +144 -5
  657. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  658. package/build/dist/Server/API/UserTwoFactorBackupCodeAPI.js +1 -0
  659. package/build/dist/Server/API/UserTwoFactorBackupCodeAPI.js.map +1 -1
  660. package/build/dist/Server/API/WorkflowVariableAPI.js +109 -0
  661. package/build/dist/Server/API/WorkflowVariableAPI.js.map +1 -0
  662. package/build/dist/Server/Infrastructure/GlobalCache.js +29 -0
  663. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  664. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.js +38 -0
  665. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.js.map +1 -0
  666. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.js +54 -0
  667. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.js.map +1 -0
  668. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.js +14 -0
  669. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.js.map +1 -0
  670. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.js +12 -0
  671. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.js.map +1 -0
  672. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.js +32 -0
  673. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.js.map +1 -0
  674. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  675. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  676. package/build/dist/Server/Middleware/MasterAdminAuthorization.js +21 -0
  677. package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
  678. package/build/dist/Server/Middleware/TelemetryIngest.js +32 -2
  679. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  680. package/build/dist/Server/Middleware/UserAuthorization.js +39 -6
  681. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  682. package/build/dist/Server/Services/AIAgentService.js +1 -0
  683. package/build/dist/Server/Services/AIAgentService.js.map +1 -1
  684. package/build/dist/Server/Services/AccessTokenService.js +87 -42
  685. package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
  686. package/build/dist/Server/Services/AlertEpisodeMemberService.js +4 -0
  687. package/build/dist/Server/Services/AlertEpisodeMemberService.js.map +1 -1
  688. package/build/dist/Server/Services/AlertEpisodeService.js +12 -1
  689. package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
  690. package/build/dist/Server/Services/AlertService.js +110 -23
  691. package/build/dist/Server/Services/AlertService.js.map +1 -1
  692. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +716 -30
  693. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
  694. package/build/dist/Server/Services/AutoRemediationRuleService.js +100 -0
  695. package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
  696. package/build/dist/Server/Services/BillingService.js +1 -0
  697. package/build/dist/Server/Services/BillingService.js.map +1 -1
  698. package/build/dist/Server/Services/InboundEmail/Providers/SendGridInboundProvider.js +11 -16
  699. package/build/dist/Server/Services/InboundEmail/Providers/SendGridInboundProvider.js.map +1 -1
  700. package/build/dist/Server/Services/IncidentEpisodeMemberService.js +4 -0
  701. package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
  702. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +48 -0
  703. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
  704. package/build/dist/Server/Services/IncidentEpisodeRoleMemberService.js +21 -0
  705. package/build/dist/Server/Services/IncidentEpisodeRoleMemberService.js.map +1 -1
  706. package/build/dist/Server/Services/IncidentEpisodeService.js +12 -1
  707. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  708. package/build/dist/Server/Services/IncidentGroupingEngineService.js +8 -0
  709. package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
  710. package/build/dist/Server/Services/IncidentMemberService.js +14 -0
  711. package/build/dist/Server/Services/IncidentMemberService.js.map +1 -1
  712. package/build/dist/Server/Services/IncidentPublicNoteService.js +48 -0
  713. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  714. package/build/dist/Server/Services/IncidentService.js +99 -21
  715. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  716. package/build/dist/Server/Services/IncidentStateTimelineService.js +12 -0
  717. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  718. package/build/dist/Server/Services/IncidentTemplateService.js +68 -4
  719. package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
  720. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +1470 -0
  721. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -0
  722. package/build/dist/Server/Services/KubernetesClusterService.js +1097 -0
  723. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  724. package/build/dist/Server/Services/LogAggregationService.js +14 -6
  725. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  726. package/build/dist/Server/Services/MonitorService.js +487 -48
  727. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  728. package/build/dist/Server/Services/MonitorStatusTimelineService.js +540 -3
  729. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  730. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +2 -0
  731. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  732. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js +2 -0
  733. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js.map +1 -1
  734. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +2 -0
  735. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
  736. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +3 -0
  737. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
  738. package/build/dist/Server/Services/OnCallNotificationAlertingService.js +29 -7
  739. package/build/dist/Server/Services/OnCallNotificationAlertingService.js.map +1 -1
  740. package/build/dist/Server/Services/OnCallSetupReminderService.js +1 -0
  741. package/build/dist/Server/Services/OnCallSetupReminderService.js.map +1 -1
  742. package/build/dist/Server/Services/ProbeService.js +7 -1
  743. package/build/dist/Server/Services/ProbeService.js.map +1 -1
  744. package/build/dist/Server/Services/ProjectService.js +11 -1
  745. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  746. package/build/dist/Server/Services/RunbookCredentialService.js +24 -0
  747. package/build/dist/Server/Services/RunbookCredentialService.js.map +1 -1
  748. package/build/dist/Server/Services/RunbookSecretService.js +44 -0
  749. package/build/dist/Server/Services/RunbookSecretService.js.map +1 -1
  750. package/build/dist/Server/Services/RunnerJobService.js +641 -21
  751. package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
  752. package/build/dist/Server/Services/RunnerService.js +344 -5
  753. package/build/dist/Server/Services/RunnerService.js.map +1 -1
  754. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +48 -0
  755. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  756. package/build/dist/Server/Services/ScheduledMaintenanceService.js +102 -20
  757. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  758. package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js +67 -4
  759. package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js.map +1 -1
  760. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +12 -1
  761. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
  762. package/build/dist/Server/Services/StatusPagePrivateUserService.js +1 -0
  763. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  764. package/build/dist/Server/Services/StatusPageService.js +230 -32
  765. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  766. package/build/dist/Server/Services/StatusPageSubscriberService.js +4 -0
  767. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  768. package/build/dist/Server/Services/TeamMemberService.js +270 -11
  769. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  770. package/build/dist/Server/Services/TraceAggregationService.js +10 -6
  771. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  772. package/build/dist/Server/Services/UserEmailService.js +1 -0
  773. package/build/dist/Server/Services/UserEmailService.js.map +1 -1
  774. package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1 -0
  775. package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -1
  776. package/build/dist/Server/Services/UserNotificationRuleAdminService.js +1 -0
  777. package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -1
  778. package/build/dist/Server/Services/UserNotificationRuleService.js +4 -0
  779. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  780. package/build/dist/Server/Services/UserService.js +107 -1
  781. package/build/dist/Server/Services/UserService.js.map +1 -1
  782. package/build/dist/Server/Services/WorkflowVariableService.js +396 -7
  783. package/build/dist/Server/Services/WorkflowVariableService.js.map +1 -1
  784. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +463 -7
  785. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  786. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +144 -2
  787. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
  788. package/build/dist/Server/Types/Database/QueryHelper.js +20 -0
  789. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  790. package/build/dist/Server/Types/Markdown.js +394 -27
  791. package/build/dist/Server/Types/Markdown.js.map +1 -1
  792. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +123 -0
  793. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -0
  794. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +344 -0
  795. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -0
  796. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +587 -0
  797. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -0
  798. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentAuth.js +18 -2
  799. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentAuth.js.map +1 -1
  800. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +1380 -239
  801. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
  802. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +1099 -68
  803. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  804. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +88 -6
  805. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  806. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +45 -11
  807. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  808. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +41 -11
  809. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  810. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js +11 -4
  811. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -1
  812. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js +4 -2
  813. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js.map +1 -1
  814. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +997 -141
  815. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
  816. package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js +299 -4
  817. package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js.map +1 -1
  818. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js +120 -0
  819. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js.map +1 -0
  820. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +160 -1
  821. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
  822. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +1 -0
  823. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
  824. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +59 -12
  825. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  826. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +5 -1
  827. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  828. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +84 -22
  829. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  830. package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js +70 -5
  831. package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js.map +1 -1
  832. package/build/dist/Server/Utils/Monitor/ProbeMonitorsNotification.js +249 -0
  833. package/build/dist/Server/Utils/Monitor/ProbeMonitorsNotification.js.map +1 -0
  834. package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js +1 -0
  835. package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js.map +1 -1
  836. package/build/dist/Server/Utils/PushNotificationUtil.js +27 -0
  837. package/build/dist/Server/Utils/PushNotificationUtil.js.map +1 -1
  838. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js +26 -3
  839. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js.map +1 -1
  840. package/build/dist/Server/Utils/Runbook/RunbookExecutePermission.js +38 -3
  841. package/build/dist/Server/Utils/Runbook/RunbookExecutePermission.js.map +1 -1
  842. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +143 -23
  843. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  844. package/build/dist/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.js +406 -0
  845. package/build/dist/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.js.map +1 -0
  846. package/build/dist/Server/Utils/StartServer.js +4 -3
  847. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  848. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +382 -0
  849. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -0
  850. package/build/dist/Server/Utils/TwoFactorBackupCodeNotification.js +1 -0
  851. package/build/dist/Server/Utils/TwoFactorBackupCodeNotification.js.map +1 -1
  852. package/build/dist/Server/Utils/UserPermission/UserPermission.js +10 -0
  853. package/build/dist/Server/Utils/UserPermission/UserPermission.js.map +1 -1
  854. package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js +447 -0
  855. package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js.map +1 -0
  856. package/build/dist/Server/Utils/Workflow/WorkflowVariableOAuthToken.js +202 -0
  857. package/build/dist/Server/Utils/Workflow/WorkflowVariableOAuthToken.js.map +1 -0
  858. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +39 -1
  859. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
  860. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +44 -4
  861. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
  862. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +150 -191
  863. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
  864. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +44 -4
  865. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
  866. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.js +39 -17
  867. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.js.map +1 -1
  868. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js +151 -145
  869. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js.map +1 -1
  870. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +221 -127
  871. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  872. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.js +91 -0
  873. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.js.map +1 -0
  874. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.js +673 -0
  875. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.js.map +1 -0
  876. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js +3 -9
  877. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js.map +1 -1
  878. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +65 -166
  879. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -1
  880. package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js +63 -157
  881. package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js.map +1 -1
  882. package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js +23 -3
  883. package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js.map +1 -1
  884. package/build/dist/Server/Utils/Workspace/Slack/Actions/Authorization.js +92 -0
  885. package/build/dist/Server/Utils/Workspace/Slack/Actions/Authorization.js.map +1 -0
  886. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +81 -210
  887. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
  888. package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js +68 -138
  889. package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js.map +1 -1
  890. package/build/dist/Server/Utils/Workspace/Slack/Actions/ReactionNote.js +240 -0
  891. package/build/dist/Server/Utils/Workspace/Slack/Actions/ReactionNote.js.map +1 -0
  892. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js +85 -212
  893. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js.map +1 -1
  894. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +60 -17
  895. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  896. package/build/dist/Server/Utils/Workspace/Slack/app-manifest.json +2 -0
  897. package/build/dist/Server/Utils/Workspace/Workspace.js +134 -41
  898. package/build/dist/Server/Utils/Workspace/Workspace.js.map +1 -1
  899. package/build/dist/Server/Utils/Workspace/WorkspaceActionAuthorization.js +197 -0
  900. package/build/dist/Server/Utils/Workspace/WorkspaceActionAuthorization.js.map +1 -0
  901. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js +32 -0
  902. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
  903. package/build/dist/Server/Utils/Workspace/WorkspaceOAuthState.js +199 -0
  904. package/build/dist/Server/Utils/Workspace/WorkspaceOAuthState.js.map +1 -0
  905. package/build/dist/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.js +91 -0
  906. package/build/dist/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.js.map +1 -0
  907. package/build/dist/Server/Utils/Workspace/WorkspaceReactionNote.js +450 -0
  908. package/build/dist/Server/Utils/Workspace/WorkspaceReactionNote.js.map +1 -0
  909. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +103 -5
  910. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
  911. package/build/dist/Types/Date.js +97 -7
  912. package/build/dist/Types/Date.js.map +1 -1
  913. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  914. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  915. package/build/dist/Types/Exception/ExceptionMessages.js +1 -0
  916. package/build/dist/Types/Exception/ExceptionMessages.js.map +1 -1
  917. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +245 -0
  918. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -0
  919. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +49 -0
  920. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -0
  921. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessToolNames.js +16 -0
  922. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessToolNames.js.map +1 -0
  923. package/build/dist/Types/Monitor/DatabaseMonitor/SqlServerPlatform.js +104 -0
  924. package/build/dist/Types/Monitor/DatabaseMonitor/SqlServerPlatform.js.map +1 -0
  925. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +6 -5
  926. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  927. package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js +32 -0
  928. package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js.map +1 -1
  929. package/build/dist/Types/Monitor/MonitorUptimeSummary.js +52 -0
  930. package/build/dist/Types/Monitor/MonitorUptimeSummary.js.map +1 -0
  931. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +9 -1
  932. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  933. package/build/dist/Types/Rum/SessionReplay.js +52 -2
  934. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  935. package/build/dist/Types/Rum/SessionReplayApi.js +11 -0
  936. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
  937. package/build/dist/Types/Rum/UserFlow.js +115 -0
  938. package/build/dist/Types/Rum/UserFlow.js.map +1 -0
  939. package/build/dist/Types/Runbook/RunbookStepType.js +10 -0
  940. package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
  941. package/build/dist/Types/Runbook/RunnerJobOrigin.js +14 -0
  942. package/build/dist/Types/Runbook/RunnerJobOrigin.js.map +1 -1
  943. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js +2 -2
  944. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js.map +1 -1
  945. package/build/dist/Types/StatusPage/MergedDowntimeTotals.js +2 -0
  946. package/build/dist/Types/StatusPage/MergedDowntimeTotals.js.map +1 -0
  947. package/build/dist/Types/StatusPage/PublicNoteSubscriberNotificationDefault.js +65 -0
  948. package/build/dist/Types/StatusPage/PublicNoteSubscriberNotificationDefault.js.map +1 -0
  949. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +8 -0
  950. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
  951. package/build/dist/Types/Timezone.js +5 -0
  952. package/build/dist/Types/Timezone.js.map +1 -1
  953. package/build/dist/Types/TimezoneAlias.js +340 -0
  954. package/build/dist/Types/TimezoneAlias.js.map +1 -0
  955. package/build/dist/Types/Workflow/Templates.js +2694 -2
  956. package/build/dist/Types/Workflow/Templates.js.map +1 -1
  957. package/build/dist/Types/Workflow/WorkflowVariableOAuth.js +314 -0
  958. package/build/dist/Types/Workflow/WorkflowVariableOAuth.js.map +1 -0
  959. package/build/dist/Types/Workspace/WorkspaceNoteReaction.js +98 -0
  960. package/build/dist/Types/Workspace/WorkspaceNoteReaction.js.map +1 -0
  961. package/build/dist/UI/Components/AttributesJSON/AttributesJSONPreferences.js +95 -0
  962. package/build/dist/UI/Components/AttributesJSON/AttributesJSONPreferences.js.map +1 -0
  963. package/build/dist/UI/Components/AttributesJSON/AttributesJSONView.js +44 -0
  964. package/build/dist/UI/Components/AttributesJSON/AttributesJSONView.js.map +1 -0
  965. package/build/dist/UI/Components/AttributesJSON/AttributesViewToggle.js +27 -0
  966. package/build/dist/UI/Components/AttributesJSON/AttributesViewToggle.js.map +1 -0
  967. package/build/dist/UI/Components/AttributesJSON/BracesGlyph.js +9 -0
  968. package/build/dist/UI/Components/AttributesJSON/BracesGlyph.js.map +1 -0
  969. package/build/dist/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.js +260 -0
  970. package/build/dist/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.js.map +1 -0
  971. package/build/dist/UI/Components/AttributesJSON/JSONHighlight.js +56 -0
  972. package/build/dist/UI/Components/AttributesJSON/JSONHighlight.js.map +1 -0
  973. package/build/dist/UI/Components/Calendar/Calendar.js +94 -7
  974. package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
  975. package/build/dist/UI/Components/Calendar/CalendarDayLayout.js +136 -0
  976. package/build/dist/UI/Components/Calendar/CalendarDayLayout.js.map +1 -0
  977. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +1 -1
  978. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  979. package/build/dist/UI/Components/Charts/Utils/HistogramSelection.js +72 -0
  980. package/build/dist/UI/Components/Charts/Utils/HistogramSelection.js.map +1 -0
  981. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +178 -0
  982. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -0
  983. package/build/dist/UI/Components/Charts/Utils/useHistogramZoom.js +13 -1
  984. package/build/dist/UI/Components/Charts/Utils/useHistogramZoom.js.map +1 -1
  985. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +20 -4
  986. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -1
  987. package/build/dist/UI/Components/Dropdown/Dropdown.js +33 -9
  988. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  989. package/build/dist/UI/Components/Forms/Fields/FormField.js +36 -13
  990. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  991. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +117 -11
  992. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
  993. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -1
  994. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
  995. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -1
  996. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +36 -8
  997. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  998. package/build/dist/UI/Components/LogsViewer/components/ColumnSelector.js +10 -2
  999. package/build/dist/UI/Components/LogsViewer/components/ColumnSelector.js.map +1 -1
  1000. package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js +9 -1
  1001. package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js.map +1 -1
  1002. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +16 -15
  1003. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
  1004. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +1 -1
  1005. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  1006. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +14 -74
  1007. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
  1008. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +22 -5
  1009. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
  1010. package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js +9 -2
  1011. package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js.map +1 -1
  1012. package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js +16 -5
  1013. package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js.map +1 -1
  1014. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +23 -8
  1015. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  1016. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +7 -1
  1017. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  1018. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +5 -1
  1019. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
  1020. package/build/dist/UI/Components/Page/ModelPage.js +37 -3
  1021. package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
  1022. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +27 -6
  1023. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  1024. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js +7 -1
  1025. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js.map +1 -1
  1026. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +1 -1
  1027. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  1028. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +17 -77
  1029. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  1030. package/build/dist/UI/Components/TelemetryViewer/components/TelemetrySearchBar.js +10 -1
  1031. package/build/dist/UI/Components/TelemetryViewer/components/TelemetrySearchBar.js.map +1 -1
  1032. package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js +15 -1
  1033. package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js.map +1 -1
  1034. package/build/dist/UI/Utils/Timezone.js +52 -17
  1035. package/build/dist/UI/Utils/Timezone.js.map +1 -1
  1036. package/build/dist/Utils/AI/InvestigationReport.js +116 -21
  1037. package/build/dist/Utils/AI/InvestigationReport.js.map +1 -1
  1038. package/build/dist/Utils/AiRemediation/KubectlOutputRedactor.js +1209 -0
  1039. package/build/dist/Utils/AiRemediation/KubectlOutputRedactor.js.map +1 -0
  1040. package/build/dist/Utils/AiRemediation/KubectlPolicy.js +2973 -0
  1041. package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -0
  1042. package/build/dist/Utils/AiRemediation/KubectlWaitBudget.js +99 -0
  1043. package/build/dist/Utils/AiRemediation/KubectlWaitBudget.js.map +1 -0
  1044. package/build/dist/Utils/AiRemediation/KubectlWriteScope.js +1429 -0
  1045. package/build/dist/Utils/AiRemediation/KubectlWriteScope.js.map +1 -0
  1046. package/build/dist/Utils/Dashboard/Components/DashboardClockComponent.js +7 -6
  1047. package/build/dist/Utils/Dashboard/Components/DashboardClockComponent.js.map +1 -1
  1048. package/build/dist/Utils/Monitor/IncomingEmailMonitorAddress.js +214 -0
  1049. package/build/dist/Utils/Monitor/IncomingEmailMonitorAddress.js.map +1 -0
  1050. package/build/dist/Utils/Monitor/MonitorCheckScheduleUtil.js +471 -0
  1051. package/build/dist/Utils/Monitor/MonitorCheckScheduleUtil.js.map +1 -0
  1052. package/build/dist/Utils/Monitor/MonitorOverviewCriteriaUtil.js +107 -0
  1053. package/build/dist/Utils/Monitor/MonitorOverviewCriteriaUtil.js.map +1 -0
  1054. package/build/dist/Utils/Monitor/MonitorOverviewFamily.js +191 -0
  1055. package/build/dist/Utils/Monitor/MonitorOverviewFamily.js.map +1 -0
  1056. package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js +1259 -0
  1057. package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js.map +1 -0
  1058. package/build/dist/Utils/Monitor/MonitorOverviewProbeUtil.js +593 -0
  1059. package/build/dist/Utils/Monitor/MonitorOverviewProbeUtil.js.map +1 -0
  1060. package/build/dist/Utils/Monitor/MonitorOverviewTargetUtil.js +195 -0
  1061. package/build/dist/Utils/Monitor/MonitorOverviewTargetUtil.js.map +1 -0
  1062. package/build/dist/Utils/Monitor/MonitorStatusHistoryUtil.js +127 -0
  1063. package/build/dist/Utils/Monitor/MonitorStatusHistoryUtil.js.map +1 -0
  1064. package/build/dist/Utils/Monitor/MonitorUptimeSummaryUtil.js +464 -0
  1065. package/build/dist/Utils/Monitor/MonitorUptimeSummaryUtil.js.map +1 -0
  1066. package/build/dist/Utils/Rum/SessionIdentity.js +31 -1
  1067. package/build/dist/Utils/Rum/SessionIdentity.js.map +1 -1
  1068. package/build/dist/Utils/Rum/SessionReplayWireEncoding.js +128 -0
  1069. package/build/dist/Utils/Rum/SessionReplayWireEncoding.js.map +1 -0
  1070. package/build/dist/Utils/Rum/UserFlow.js +941 -0
  1071. package/build/dist/Utils/Rum/UserFlow.js.map +1 -0
  1072. package/build/dist/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.js +82 -0
  1073. package/build/dist/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.js.map +1 -0
  1074. package/build/dist/Utils/StatusPage/ResourceUptime.js +46 -0
  1075. package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
  1076. package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js +148 -0
  1077. package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js.map +1 -1
  1078. package/build/dist/Utils/Telemetry/AttributesJSON.js +245 -0
  1079. package/build/dist/Utils/Telemetry/AttributesJSON.js.map +1 -0
  1080. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +103 -0
  1081. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -1
  1082. package/build/dist/Utils/Uptime/UptimeUtil.js +91 -27
  1083. package/build/dist/Utils/Uptime/UptimeUtil.js.map +1 -1
  1084. package/jest.config.json +2 -1
  1085. package/package.json +2 -1
  1086. package/tsconfig.tests.json +36 -0
  1087. package/Tests/UI/Components/EmptyState/EmptyStateGuideLinks.test.tsx +0 -337
  1088. package/UI/Components/EmptyState/EmptyStateGuideLinks.tsx +0 -124
  1089. package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js +0 -47
  1090. package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js.map +0 -1
@@ -1,5 +1,12 @@
1
1
  import "@testing-library/jest-dom";
2
- import { afterEach, describe, expect, jest, test } from "@jest/globals";
2
+ import {
3
+ afterEach,
4
+ beforeAll,
5
+ describe,
6
+ expect,
7
+ jest,
8
+ test,
9
+ } from "@jest/globals";
3
10
  import {
4
11
  cleanup,
5
12
  fireEvent,
@@ -8,12 +15,15 @@ import {
8
15
  screen,
9
16
  within,
10
17
  } from "@testing-library/react";
18
+ import userEvent from "@testing-library/user-event";
19
+ import { UserEvent } from "@testing-library/user-event/dist/types/setup/setup";
20
+ import { createInstance, i18n } from "i18next";
11
21
  import React from "react";
22
+ import { I18nextProvider } from "react-i18next";
12
23
  import SecurityEventConnectionsEmptyState, {
13
24
  SECURITY_EVENT_CONNECTIONS_EMPTY_STATE_ID,
14
25
  SECURITY_EVENT_CONNECTION_REQUIREMENTS,
15
26
  SecurityEventConnectionRequirement,
16
- securityEventConnectorGuideLinks,
17
27
  } from "../../../../App/FeatureSet/Dashboard/src/Components/SecurityEvents/SecurityEventConnectionsEmptyState";
18
28
  import { connectorDocsUrl } from "../../../../App/FeatureSet/Dashboard/src/Components/SecurityEvents/SecurityEventConnectionDiagnosticsUtil";
19
29
  import IconProp from "../../../Types/Icon/IconProp";
@@ -22,98 +32,286 @@ import {
22
32
  SecurityEventConnectorDefinition,
23
33
  } from "../../../Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog";
24
34
  import SecurityEventConnectorProvider from "../../../Types/SecurityEvent/Connectors/SecurityEventConnectorProvider";
25
- import { EmptyStateGuideLink } from "../../../UI/Components/EmptyState/EmptyStateGuideLinks";
35
+ import Icon from "../../../UI/Components/Icon/Icon";
26
36
  import getJestMockFunction, { MockFunction } from "../../MockType";
27
37
 
28
38
  /*
29
- * Security Events > Connections with no connections: what a connection
30
- * does, the button that adds one, what it needs before its first poll, and
31
- * one setup-guide card per provider.
39
+ * Security Events > Connections with no connections.
40
+ *
41
+ * It used to be a centred icon and paragraph, a button, a grey "Before you
42
+ * connect" box and a "Setup guides" grid of eight heavy docs cards, each
43
+ * block a different width and alignment. Now it is a centred header (badge,
44
+ * title, one sentence, Add connection), then every product in the catalog
45
+ * as one tile that starts a connection with that product already selected
46
+ * (the setup guide is a separate link on the tile), then what a connection
47
+ * needs.
32
48
  *
33
- * It replaced a paragraph and a bulleted list centred inside the table,
34
- * whose bullets sat at the far left edge of the table while the links sat
35
- * in the middle.
49
+ * SecurityEventProviderTile has its own tests; these check how the empty
50
+ * state lays the tiles out, wires them to onAddConnection, and gates them.
36
51
  */
37
52
 
38
- const EXPECTED_GUIDES: Array<{ title: string; category: string }> = [
39
- { title: "Microsoft Sentinel", category: "SIEM" },
40
- { title: "Microsoft Defender XDR", category: "EDR / XDR" },
41
- { title: "CrowdStrike Falcon", category: "EDR / XDR" },
42
- { title: "Splunk Enterprise Security", category: "SIEM" },
43
- { title: "Elastic Security", category: "SIEM" },
44
- { title: "AWS Security Hub", category: "Cloud security" },
45
- { title: "Okta System Log", category: "Identity" },
46
- { title: "Google SecOps", category: "SIEM" },
53
+ const ID: string = SECURITY_EVENT_CONNECTIONS_EMPTY_STATE_ID;
54
+
55
+ const DISABLED_REASON: string =
56
+ "You do not have permission to create security event connections.";
57
+
58
+ /*
59
+ * The catalog order, written out: the tiles are the list the Add connection
60
+ * form offers, so a change here is a change to the product, not a detail.
61
+ */
62
+ const EXPECTED_PRODUCTS: Array<{
63
+ provider: SecurityEventConnectorProvider;
64
+ title: string;
65
+ category: string;
66
+ }> = [
67
+ {
68
+ provider: SecurityEventConnectorProvider.MicrosoftSentinel,
69
+ title: "Microsoft Sentinel",
70
+ category: "SIEM",
71
+ },
72
+ {
73
+ provider: SecurityEventConnectorProvider.MicrosoftDefenderXdr,
74
+ title: "Microsoft Defender XDR",
75
+ category: "EDR / XDR",
76
+ },
77
+ {
78
+ provider: SecurityEventConnectorProvider.CrowdStrikeFalcon,
79
+ title: "CrowdStrike Falcon",
80
+ category: "EDR / XDR",
81
+ },
82
+ {
83
+ provider: SecurityEventConnectorProvider.SplunkEnterpriseSecurity,
84
+ title: "Splunk Enterprise Security",
85
+ category: "SIEM",
86
+ },
87
+ {
88
+ provider: SecurityEventConnectorProvider.ElasticSecurity,
89
+ title: "Elastic Security",
90
+ category: "SIEM",
91
+ },
92
+ {
93
+ provider: SecurityEventConnectorProvider.AwsSecurityHub,
94
+ title: "AWS Security Hub",
95
+ category: "Cloud security",
96
+ },
97
+ {
98
+ provider: SecurityEventConnectorProvider.OktaSystemLog,
99
+ title: "Okta System Log",
100
+ category: "Identity",
101
+ },
102
+ {
103
+ provider: SecurityEventConnectorProvider.GoogleSecOps,
104
+ title: "Google SecOps",
105
+ category: "SIEM",
106
+ },
47
107
  ];
48
108
 
109
+ /*
110
+ * Real i18next instances rather than a mocked hook. "german" also has
111
+ * entries for a product name and for the permission reason, neither of
112
+ * which the empty state may look up: a product name is a brand, and the
113
+ * reason is already the API's own sentence.
114
+ */
115
+ const english: i18n = createInstance();
116
+ const german: i18n = createInstance();
117
+
118
+ beforeAll(async (): Promise<void> => {
119
+ await english.init({
120
+ lng: "en",
121
+ fallbackLng: "en",
122
+ resources: { en: { translation: {} } },
123
+ interpolation: { escapeValue: false },
124
+ });
125
+ await german.init({
126
+ lng: "de",
127
+ fallbackLng: "de",
128
+ resources: {
129
+ de: {
130
+ translation: {
131
+ "No security event connections yet":
132
+ "Noch keine Verbindungen für Sicherheitsereignisse",
133
+ "Pick a product to connect": "Wählen Sie ein Produkt",
134
+ "Supported products": "Unterstützte Produkte",
135
+ "What you'll need": "Was Sie brauchen",
136
+ "A read-only credential": "Ein schreibgeschützter Zugang",
137
+ "Add connection": "Verbindung hinzufügen",
138
+ Connect: "Verbinden",
139
+ "Setup guide": "Einrichtungsanleitung",
140
+ "(opens in a new tab)": "(öffnet in einem neuen Tab)",
141
+ // Bait: neither of these may be looked up.
142
+ "Microsoft Sentinel": "Microsoft Wächter",
143
+ [DISABLED_REASON]: "Sie dürfen keine Verbindungen erstellen.",
144
+ },
145
+ },
146
+ },
147
+ interpolation: { escapeValue: false },
148
+ });
149
+ });
150
+
49
151
  afterEach((): void => {
50
152
  cleanup();
51
153
  jest.restoreAllMocks();
52
154
  });
53
155
 
54
- function renderEmptyState(
55
- props: {
56
- canCreate?: boolean;
57
- createDisabledReason?: string | undefined;
58
- onAddConnection?: MockFunction;
59
- } = {},
60
- ): RenderResult {
156
+ interface RenderOptions {
157
+ canCreate?: boolean | undefined;
158
+ createDisabledReason?: string | undefined;
159
+ onAddConnection?: MockFunction | undefined;
160
+ translations?: i18n | undefined;
161
+ }
162
+
163
+ function renderEmptyState(options: RenderOptions = {}): RenderResult {
61
164
  return render(
62
- <SecurityEventConnectionsEmptyState
63
- canCreate={props.canCreate ?? true}
64
- createDisabledReason={props.createDisabledReason}
65
- onAddConnection={props.onAddConnection || getJestMockFunction()}
66
- />,
165
+ <I18nextProvider i18n={options.translations || english}>
166
+ <SecurityEventConnectionsEmptyState
167
+ canCreate={options.canCreate ?? true}
168
+ createDisabledReason={options.createDisabledReason}
169
+ onAddConnection={options.onAddConnection || getJestMockFunction()}
170
+ />
171
+ </I18nextProvider>,
67
172
  );
68
173
  }
69
174
 
175
+ function renderBlocked(onAddConnection?: MockFunction): RenderResult {
176
+ return renderEmptyState({
177
+ canCreate: false,
178
+ createDisabledReason: DISABLED_REASON,
179
+ onAddConnection,
180
+ });
181
+ }
182
+
70
183
  function root(): HTMLElement {
71
- return document.getElementById(
72
- SECURITY_EVENT_CONNECTIONS_EMPTY_STATE_ID,
73
- ) as HTMLElement;
184
+ return document.getElementById(ID) as HTMLElement;
74
185
  }
75
186
 
76
- function guides(): HTMLElement {
77
- return screen.getByRole("list", { name: "Setup guides" });
187
+ // The centred header: badge, title, description, button, reason.
188
+ function hero(): HTMLElement {
189
+ return root().children[0] as HTMLElement;
78
190
  }
79
191
 
80
192
  function addButton(): HTMLElement {
81
- return screen.getByTestId(
82
- `${SECURITY_EVENT_CONNECTIONS_EMPTY_STATE_ID}-add-connection`,
193
+ return screen.getByTestId(`${ID}-add-connection`);
194
+ }
195
+
196
+ function providersSection(): HTMLElement {
197
+ return document.getElementById(`${ID}-providers`) as HTMLElement;
198
+ }
199
+
200
+ function requirementsSection(): HTMLElement {
201
+ return document.getElementById(`${ID}-requirements`) as HTMLElement;
202
+ }
203
+
204
+ function tiles(): Array<HTMLElement> {
205
+ return within(providersSection()).getAllByRole("listitem");
206
+ }
207
+
208
+ function tileFor(provider: SecurityEventConnectorProvider): HTMLElement {
209
+ return screen.getByTestId(`${ID}-provider-${provider}`);
210
+ }
211
+
212
+ function connectButton(title: string): HTMLElement {
213
+ return screen.getByRole("button", { name: `Connect ${title}` });
214
+ }
215
+
216
+ function guideLinkFor(title: string): HTMLElement {
217
+ return screen.getByRole("link", {
218
+ name: `${title} Setup guide (opens in a new tab)`,
219
+ });
220
+ }
221
+
222
+ function follows(first: Element, second: Element): boolean {
223
+ return Boolean(
224
+ first.compareDocumentPosition(second) & Node.DOCUMENT_POSITION_FOLLOWING,
83
225
  );
84
226
  }
85
227
 
228
+ // The inner markup of an icon on its own, to compare with a rendered one.
229
+ function iconMarkup(icon: IconProp): string {
230
+ const view: RenderResult = render(<Icon icon={icon} className="h-5 w-5" />);
231
+ const svg: SVGElement | null = view.container.querySelector("svg");
232
+ const markup: string = svg ? svg.innerHTML : "";
233
+ view.unmount();
234
+ view.container.remove();
235
+ return markup;
236
+ }
237
+
238
+ function svgMarkup(element: Element): string {
239
+ const svg: SVGElement | null = element.querySelector("svg");
240
+ return svg ? svg.innerHTML : "";
241
+ }
242
+
243
+ function classTokens(element: Element): Array<string> {
244
+ return (element.getAttribute("class") || "")
245
+ .split(/\s+/)
246
+ .filter((token: string): boolean => {
247
+ return token.length > 0;
248
+ });
249
+ }
250
+
251
+ /*
252
+ * Guide links open in a new tab and are left to the browser, which jsdom
253
+ * answers with a "navigation not implemented" error. Cancelling the
254
+ * default below React's root keeps that out of the output without
255
+ * touching the handlers under test.
256
+ */
257
+ function suppressNavigation(): void {
258
+ root().addEventListener("click", (event: Event): void => {
259
+ event.preventDefault();
260
+ });
261
+ }
262
+
263
+ async function tabStops(
264
+ user: UserEvent,
265
+ count: number,
266
+ ): Promise<Array<Element | null>> {
267
+ const stops: Array<Element | null> = [];
268
+ for (let index: number = 0; index < count; index++) {
269
+ await user.tab();
270
+ stops.push(document.activeElement);
271
+ }
272
+ return stops;
273
+ }
274
+
275
+ /*
276
+ * toEqual on DOM nodes compares their markup, which two tiles could share;
277
+ * a focus order is about which element, so compare identities.
278
+ */
279
+ function expectSameElements(
280
+ actual: Array<Element | null>,
281
+ expected: Array<Element>,
282
+ ): void {
283
+ expect(actual).toHaveLength(expected.length);
284
+ actual.forEach((element: Element | null, index: number): void => {
285
+ expect(element).toBe(expected[index]);
286
+ });
287
+ }
288
+
86
289
  describe("SecurityEventConnectionsEmptyState", () => {
87
290
  describe("header", () => {
88
- test("is an EmptyState with the connection icon, a title and one sentence of what a connection does", () => {
291
+ test("has the root id, a level 3 title and one sentence of what a connection does", () => {
89
292
  renderEmptyState();
90
293
 
91
294
  expect(SECURITY_EVENT_CONNECTIONS_EMPTY_STATE_ID).toBe(
92
295
  "security-event-connections-empty-state",
93
296
  );
94
297
  expect(root()).toBeInTheDocument();
95
- expect(
96
- screen.getByRole("heading", {
97
- level: 3,
98
- name: "No security event connections yet",
99
- }),
100
- ).toBeInTheDocument();
101
- expect(
102
- screen.getByTestId(
103
- `${SECURITY_EVENT_CONNECTIONS_EMPTY_STATE_ID}-description`,
104
- ),
105
- ).toHaveTextContent(
298
+ const title: HTMLElement = screen.getByRole("heading", {
299
+ level: 3,
300
+ name: "No security event connections yet",
301
+ });
302
+ expect(title.tagName).toBe("H3");
303
+ expect(hero()).toContainElement(title);
304
+ expect(screen.getByTestId(`${ID}-description`)).toHaveTextContent(
106
305
  "Connect a SIEM, EDR / XDR, cloud security or identity product and OneUptime polls it on a schedule, importing each new alert, finding or log event as an OCSF security event.",
107
306
  );
307
+ expect(hero()).toContainElement(screen.getByTestId(`${ID}-description`));
108
308
  });
109
309
 
110
310
  test("the description names every provider category the catalog has", () => {
111
311
  renderEmptyState();
112
312
 
113
313
  const description: string =
114
- screen.getByTestId(
115
- `${SECURITY_EVENT_CONNECTIONS_EMPTY_STATE_ID}-description`,
116
- ).textContent || "";
314
+ screen.getByTestId(`${ID}-description`).textContent || "";
117
315
  for (const definition of SecurityEventConnectorCatalog) {
118
316
  expect(description.toLowerCase()).toContain(
119
317
  definition.category.toLowerCase(),
@@ -121,21 +319,70 @@ describe("SecurityEventConnectionsEmptyState", () => {
121
319
  }
122
320
  });
123
321
 
322
+ test("opens with a decorative, tinted badge drawn with the Link icon", () => {
323
+ renderEmptyState();
324
+
325
+ const badge: HTMLElement = hero().children[0] as HTMLElement;
326
+ expect(badge).toHaveAttribute("aria-hidden", "true");
327
+ expect(badge).toHaveClass(
328
+ "rounded-xl",
329
+ "bg-indigo-50",
330
+ "text-indigo-600",
331
+ "ring-1",
332
+ "ring-indigo-200",
333
+ );
334
+ expect(badge.textContent).toBe("");
335
+ expect(svgMarkup(badge)).toBe(iconMarkup(IconProp.Link));
336
+ expect(follows(badge, screen.getByRole("heading", { level: 3 }))).toBe(
337
+ true,
338
+ );
339
+ });
340
+
341
+ test("is centred, while the root is left-aligned for the tiles", () => {
342
+ renderEmptyState();
343
+
344
+ expect(hero()).toHaveClass(
345
+ "flex",
346
+ "flex-col",
347
+ "items-center",
348
+ "text-center",
349
+ );
350
+ expect(root()).toHaveClass("mx-auto", "w-full", "max-w-5xl", "text-left");
351
+ });
352
+
124
353
  /*
125
- * Inside a table the full-page 13rem padding pushed the Refresh link
126
- * far below the content.
354
+ * It renders inside the table's ErrorMessage: the full-page 13rem
355
+ * padding of the old EmptyState pushed the Refresh link far below the
356
+ * content.
127
357
  */
128
- test("uses compact table padding rather than the full-page default", () => {
358
+ test("uses compact padding rather than the full-page default", () => {
129
359
  renderEmptyState();
130
360
 
131
- expect(root()).toHaveClass("py-4");
361
+ expect(root()).toHaveClass("py-2");
132
362
  expect(root()).not.toHaveClass("pt-52");
133
363
  expect(root()).not.toHaveClass("pb-52");
364
+ expect(root()).not.toHaveClass("py-4");
365
+ });
366
+
367
+ test("has one level 3 title and two level 4 section headings under it", () => {
368
+ renderEmptyState();
369
+
370
+ expect(screen.getAllByRole("heading", { level: 3 })).toHaveLength(1);
371
+ const sectionHeadings: Array<HTMLElement> = screen.getAllByRole(
372
+ "heading",
373
+ { level: 4 },
374
+ );
375
+ expect(
376
+ sectionHeadings.map((heading: HTMLElement): string => {
377
+ return heading.textContent || "";
378
+ }),
379
+ ).toEqual(["Pick a product to connect", "What you'll need"]);
380
+ expect(screen.getAllByRole("heading")).toHaveLength(3);
134
381
  });
135
382
  });
136
383
 
137
384
  describe("Add connection", () => {
138
- test("is a primary button that opens the create form", () => {
385
+ test("is a primary button in the header that opens the create form with no provider", () => {
139
386
  const onAddConnection: MockFunction = getJestMockFunction();
140
387
  renderEmptyState({ onAddConnection });
141
388
 
@@ -143,55 +390,48 @@ describe("SecurityEventConnectionsEmptyState", () => {
143
390
  name: "Add connection",
144
391
  });
145
392
  expect(button).toBe(addButton());
393
+ expect(hero()).toContainElement(button);
146
394
  expect(button).toBeEnabled();
147
395
  expect(button).toHaveClass("bg-indigo-600");
148
396
  // Cancels the variant's modal-footer margin so it sits on the centre line.
149
397
  expect(button).toHaveClass("md:!ml-0");
398
+ expect(svgMarkup(button)).toBe(iconMarkup(IconProp.Add));
150
399
 
151
400
  fireEvent.click(button);
152
401
  expect(onAddConnection).toHaveBeenCalledTimes(1);
402
+ // No provider, and not the click event either.
403
+ expect(onAddConnection.mock.calls[0]).toEqual([]);
153
404
  });
154
405
 
155
- test("comes before the requirements and the guides", () => {
406
+ test("comes before the tiles and the requirements", () => {
156
407
  renderEmptyState();
157
408
 
158
- const requirements: HTMLElement = document.getElementById(
159
- `${SECURITY_EVENT_CONNECTIONS_EMPTY_STATE_ID}-requirements`,
160
- ) as HTMLElement;
161
- expect(
162
- addButton().compareDocumentPosition(requirements) &
163
- Node.DOCUMENT_POSITION_FOLLOWING,
164
- ).toBeTruthy();
165
- expect(
166
- requirements.compareDocumentPosition(guides()) &
167
- Node.DOCUMENT_POSITION_FOLLOWING,
168
- ).toBeTruthy();
409
+ expect(follows(addButton(), providersSection())).toBe(true);
410
+ expect(follows(addButton(), tiles()[0]!)).toBe(true);
411
+ expect(follows(addButton(), requirementsSection())).toBe(true);
169
412
  });
170
413
 
171
414
  test("is disabled, with the permission reason, for a member who cannot create connections", () => {
172
415
  const onAddConnection: MockFunction = getJestMockFunction();
173
- renderEmptyState({
174
- canCreate: false,
175
- createDisabledReason:
176
- "You do not have permission to create security event connections.",
177
- onAddConnection,
178
- });
416
+ renderBlocked(onAddConnection);
179
417
 
180
418
  const button: HTMLElement = addButton();
181
419
  expect(button).toBeDisabled();
182
420
  expect(button).toHaveClass("bg-indigo-300");
421
+ expect(button).not.toHaveClass("bg-indigo-600");
183
422
 
184
423
  /*
185
424
  * A disabled button cannot be hovered, so the tooltip hangs off a
186
425
  * focusable wrapper instead.
187
426
  */
188
427
  const wrapper: HTMLElement = screen.getByTestId(
189
- `${SECURITY_EVENT_CONNECTIONS_EMPTY_STATE_ID}-add-connection-disabled-wrapper`,
428
+ `${ID}-add-connection-disabled-wrapper`,
190
429
  );
191
430
  expect(wrapper).toHaveAttribute("tabindex", "0");
192
431
  expect(wrapper).toContainElement(button);
193
432
 
194
433
  fireEvent.click(button);
434
+ fireEvent.click(wrapper);
195
435
  expect(onAddConnection).not.toHaveBeenCalled();
196
436
  });
197
437
 
@@ -203,35 +443,413 @@ describe("SecurityEventConnectionsEmptyState", () => {
203
443
 
204
444
  expect(addButton()).toBeEnabled();
205
445
  expect(
206
- screen.queryByTestId(
207
- `${SECURITY_EVENT_CONNECTIONS_EMPTY_STATE_ID}-add-connection-disabled-wrapper`,
208
- ),
446
+ screen.queryByTestId(`${ID}-add-connection-disabled-wrapper`),
209
447
  ).not.toBeInTheDocument();
210
448
  });
211
449
 
212
450
  test("stays visible, disabled, even without a reason", () => {
213
451
  renderEmptyState({ canCreate: false });
214
452
 
453
+ expect(addButton()).toBeVisible();
215
454
  expect(addButton()).toBeDisabled();
455
+ // No reason, no tooltip, so no wrapper to focus.
456
+ expect(
457
+ screen.queryByTestId(`${ID}-add-connection-disabled-wrapper`),
458
+ ).not.toBeInTheDocument();
459
+ });
460
+ });
461
+
462
+ describe("disabled reason", () => {
463
+ test("is written out under the disabled button, since a tooltip never shows on touch", () => {
464
+ renderBlocked();
465
+
466
+ const reason: HTMLElement = screen.getByTestId(`${ID}-disabled-reason`);
467
+ expect(reason).toHaveTextContent(DISABLED_REASON);
468
+ expect(reason.textContent).toBe(DISABLED_REASON);
469
+ expect(hero()).toContainElement(reason);
470
+ expect(follows(addButton(), reason)).toBe(true);
471
+ expect(follows(reason, providersSection())).toBe(true);
472
+ });
473
+
474
+ test("leads with a decorative lock icon", () => {
475
+ renderBlocked();
476
+
477
+ const reason: HTMLElement = screen.getByTestId(`${ID}-disabled-reason`);
478
+ const svg: SVGElement | null = reason.querySelector("svg");
479
+ expect(svg).not.toBeNull();
480
+ expect(svg).toHaveAttribute("aria-hidden", "true");
481
+ expect(svg!.innerHTML).toBe(iconMarkup(IconProp.Lock));
482
+ expect(reason.querySelectorAll("svg")).toHaveLength(1);
483
+ });
484
+
485
+ test("shows the API's own sentence, not a translation of it", () => {
486
+ renderEmptyState({
487
+ canCreate: false,
488
+ createDisabledReason: DISABLED_REASON,
489
+ translations: german,
490
+ });
491
+
492
+ const reason: HTMLElement = screen.getByTestId(`${ID}-disabled-reason`);
493
+ expect(reason.textContent).toBe(DISABLED_REASON);
494
+ expect(
495
+ screen.queryByText("Sie dürfen keine Verbindungen erstellen."),
496
+ ).not.toBeInTheDocument();
497
+ });
498
+
499
+ test("is not shown to a member who can create connections, even with a reason", () => {
500
+ renderEmptyState({
501
+ canCreate: true,
502
+ createDisabledReason: "Stale reason",
503
+ });
504
+
505
+ expect(
506
+ screen.queryByTestId(`${ID}-disabled-reason`),
507
+ ).not.toBeInTheDocument();
508
+ expect(screen.queryByText("Stale reason")).not.toBeInTheDocument();
509
+ });
510
+
511
+ test.each([
512
+ ["no reason", undefined],
513
+ ["an empty reason", ""],
514
+ ])(
515
+ "is not shown for a blocked member with %s",
516
+ (_label: string, createDisabledReason: string | undefined) => {
517
+ renderEmptyState({ canCreate: false, createDisabledReason });
518
+
519
+ expect(
520
+ screen.queryByTestId(`${ID}-disabled-reason`),
521
+ ).not.toBeInTheDocument();
522
+ expect(root().querySelectorAll("svg")).toHaveLength(
523
+ // Badge, Add icon, 8 tile badges, 8 external-link icons, 2 requirements.
524
+ 1 + 1 + 8 + 8 + 2,
525
+ );
526
+ },
527
+ );
528
+ });
529
+
530
+ describe("layout", () => {
531
+ test("runs header, then products, then requirements", () => {
532
+ renderEmptyState();
533
+
534
+ const children: Array<Element> = Array.from(root().children);
535
+ expect(children).toHaveLength(3);
536
+ expect(children[0]).toBe(hero());
537
+ expect(children[1]).toBe(providersSection());
538
+ expect(children[2]).toBe(requirementsSection());
539
+ expect(providersSection().tagName).toBe("SECTION");
540
+ expect(requirementsSection().tagName).toBe("SECTION");
541
+ });
542
+
543
+ test("keeps that order for a member who cannot create connections", () => {
544
+ renderBlocked();
545
+
546
+ expect(follows(hero(), providersSection())).toBe(true);
547
+ expect(follows(providersSection(), requirementsSection())).toBe(true);
548
+ expect(
549
+ follows(
550
+ screen.getByTestId(`${ID}-disabled-reason`),
551
+ providersSection(),
552
+ ),
553
+ ).toBe(true);
554
+ });
555
+
556
+ /*
557
+ * The old layout put a grey requirements box between the button and
558
+ * the guides. The requirements now come last, separated by a rule,
559
+ * and are not a box.
560
+ */
561
+ test("the requirements are no longer a grey box before the products", () => {
562
+ renderEmptyState();
563
+
564
+ expect(follows(requirementsSection(), providersSection())).toBe(false);
565
+ for (const tile of tiles()) {
566
+ expect(follows(tile, requirementsSection())).toBe(true);
567
+ }
568
+ expect(requirementsSection()).not.toHaveClass("bg-gray-50");
569
+ expect(requirementsSection()).not.toHaveClass("rounded-lg");
570
+ expect(requirementsSection()).not.toHaveClass("ring-1");
571
+ expect(requirementsSection()).toHaveClass(
572
+ "border-t",
573
+ "border-gray-100",
574
+ "pt-6",
575
+ );
576
+ });
577
+
578
+ test("the product grid is one column, two from sm and four from lg", () => {
579
+ renderEmptyState();
580
+
581
+ const list: HTMLElement = screen.getByRole("list", {
582
+ name: "Pick a product to connect",
583
+ });
584
+ expect(list).toHaveClass(
585
+ "grid",
586
+ "grid-cols-1",
587
+ "gap-3",
588
+ "sm:grid-cols-2",
589
+ "lg:grid-cols-4",
590
+ );
591
+ });
592
+ });
593
+
594
+ describe("providers", () => {
595
+ test("are a region and a list named by their heading", () => {
596
+ renderEmptyState();
597
+
598
+ const region: HTMLElement = screen.getByRole("region", {
599
+ name: "Pick a product to connect",
600
+ });
601
+ expect(region).toBe(providersSection());
602
+ const heading: HTMLElement = within(region).getByRole("heading", {
603
+ level: 4,
604
+ name: "Pick a product to connect",
605
+ });
606
+ expect(heading).toHaveAttribute("id", `${ID}-providers-heading`);
607
+ expect(region).toHaveAttribute(
608
+ "aria-labelledby",
609
+ `${ID}-providers-heading`,
610
+ );
611
+
612
+ const list: HTMLElement = within(region).getByRole("list", {
613
+ name: "Pick a product to connect",
614
+ });
615
+ expect(list).toHaveAttribute(
616
+ "aria-labelledby",
617
+ `${ID}-providers-heading`,
618
+ );
619
+ expect(within(list).getAllByRole("listitem")).toHaveLength(
620
+ SecurityEventConnectorCatalog.length,
621
+ );
622
+ });
623
+
624
+ test("are headed Supported products for a member who cannot create connections", () => {
625
+ renderBlocked();
626
+
627
+ expect(screen.getByRole("region", { name: "Supported products" })).toBe(
628
+ providersSection(),
629
+ );
630
+ expect(
631
+ screen.getByRole("heading", { level: 4, name: "Supported products" }),
632
+ ).toBeInTheDocument();
633
+ expect(
634
+ screen.getByRole("list", { name: "Supported products" }),
635
+ ).toBeInTheDocument();
636
+ expect(
637
+ screen.queryByText("Pick a product to connect"),
638
+ ).not.toBeInTheDocument();
639
+ });
640
+
641
+ test("show all eight products, in catalog order", () => {
642
+ renderEmptyState();
643
+
644
+ expect(SecurityEventConnectorCatalog).toHaveLength(8);
645
+ expect(tiles()).toHaveLength(EXPECTED_PRODUCTS.length);
646
+ tiles().forEach((tile: HTMLElement, index: number): void => {
647
+ const expected: {
648
+ provider: SecurityEventConnectorProvider;
649
+ title: string;
650
+ category: string;
651
+ } = EXPECTED_PRODUCTS[index]!;
652
+ expect(tile).toHaveAttribute(
653
+ "data-testid",
654
+ `${ID}-provider-${expected.provider}`,
655
+ );
656
+ expect(tile).toHaveTextContent(expected.title);
657
+ expect(
658
+ document.getElementById(
659
+ `${ID}-provider-${expected.provider}-category`,
660
+ ),
661
+ ).toHaveTextContent(new RegExp(`^${expected.category}$`));
662
+ expect(SecurityEventConnectorCatalog[index]!.provider).toBe(
663
+ expected.provider,
664
+ );
665
+ });
666
+ });
667
+
668
+ test("Google SecOps is last and points at its own guide", () => {
669
+ renderEmptyState();
670
+
671
+ const last: HTMLElement = tiles()[tiles().length - 1]!;
672
+ expect(last).toBe(tileFor(SecurityEventConnectorProvider.GoogleSecOps));
673
+ expect(within(last).getByRole("link")).toHaveAccessibleName(
674
+ "Google SecOps Setup guide (opens in a new tab)",
675
+ );
676
+ expect(within(last).getByRole("link").getAttribute("href")).toMatch(
677
+ /\/docs\/integrations\/google-secops$/,
678
+ );
679
+ });
680
+
681
+ test.each(SecurityEventConnectorCatalog)(
682
+ "$title's tile opens Add connection with $provider selected",
683
+ (definition: SecurityEventConnectorDefinition) => {
684
+ const onAddConnection: MockFunction = getJestMockFunction();
685
+ renderEmptyState({ onAddConnection });
686
+
687
+ const button: HTMLElement = connectButton(definition.title);
688
+ expect(tileFor(definition.provider)).toContainElement(button);
689
+ expect(button).toHaveAccessibleDescription(definition.category);
690
+
691
+ fireEvent.click(button);
692
+
693
+ expect(onAddConnection).toHaveBeenCalledTimes(1);
694
+ expect(onAddConnection.mock.calls[0]).toEqual([definition.provider]);
695
+ },
696
+ );
697
+
698
+ test("each tile passes its own provider, in the order they are clicked", () => {
699
+ const onAddConnection: MockFunction = getJestMockFunction();
700
+ renderEmptyState({ onAddConnection });
701
+
702
+ for (const tile of [...tiles()].reverse()) {
703
+ fireEvent.click(within(tile).getByRole("button"));
704
+ }
705
+
706
+ expect(onAddConnection.mock.calls).toEqual(
707
+ [...SecurityEventConnectorCatalog]
708
+ .reverse()
709
+ .map(
710
+ (definition: SecurityEventConnectorDefinition): Array<string> => {
711
+ return [definition.provider];
712
+ },
713
+ ),
714
+ );
715
+ });
716
+
717
+ test.each(SecurityEventConnectorCatalog)(
718
+ "$title's setup guide opens its docs page in a new tab",
719
+ (definition: SecurityEventConnectorDefinition) => {
720
+ renderEmptyState();
721
+
722
+ const link: HTMLElement = guideLinkFor(definition.title);
723
+ expect(tileFor(definition.provider)).toContainElement(link);
724
+ expect(link).toHaveAttribute(
725
+ "href",
726
+ connectorDocsUrl(definition).toString(),
727
+ );
728
+ expect(link.getAttribute("href")).toMatch(
729
+ /\/docs\/integrations\/[a-z-]+$/,
730
+ );
731
+ expect(link).toHaveAttribute("target", "_blank");
732
+ },
733
+ );
734
+
735
+ test("clicking a setup guide does not open Add connection", () => {
736
+ const onAddConnection: MockFunction = getJestMockFunction();
737
+ renderEmptyState({ onAddConnection });
738
+ suppressNavigation();
739
+
740
+ for (const definition of SecurityEventConnectorCatalog) {
741
+ fireEvent.click(guideLinkFor(definition.title));
742
+ }
743
+
744
+ expect(onAddConnection).not.toHaveBeenCalled();
745
+ });
746
+
747
+ test("tiles have no connect buttons for a member who cannot create connections", () => {
748
+ const onAddConnection: MockFunction = getJestMockFunction();
749
+ renderBlocked(onAddConnection);
750
+
751
+ for (const expected of EXPECTED_PRODUCTS) {
752
+ const tile: HTMLElement = tileFor(expected.provider);
753
+ expect(within(tile).queryByRole("button")).not.toBeInTheDocument();
754
+ expect(
755
+ within(tile).getByText(expected.title, { selector: "p" }),
756
+ ).toBeInTheDocument();
757
+ // The guide stays: reading it is not creating anything.
758
+ expect(within(tile).getByRole("link")).toHaveAccessibleName(
759
+ `${expected.title} Setup guide (opens in a new tab)`,
760
+ );
761
+ fireEvent.click(tile);
762
+ }
763
+ expect(root().querySelectorAll("[data-provider-tile]")).toHaveLength(0);
764
+ expect(onAddConnection).not.toHaveBeenCalled();
765
+ });
766
+
767
+ test("every tile has the same structure and classes", () => {
768
+ renderEmptyState();
769
+
770
+ const signatures: Array<string> = tiles().map(
771
+ (tile: HTMLElement): string => {
772
+ return [tile, ...(Array.from(tile.children) as Array<HTMLElement>)]
773
+ .map((element: HTMLElement): string => {
774
+ return `${element.tagName}.${classTokens(element).join(".")}`;
775
+ })
776
+ .join(" > ");
777
+ },
778
+ );
779
+ expect(new Set(signatures).size).toBe(1);
780
+ for (const tile of tiles()) {
781
+ // Badge, text, plus.
782
+ expect(tile.children).toHaveLength(3);
783
+ }
784
+ });
785
+
786
+ test("static tiles share one structure too, without the plus", () => {
787
+ renderBlocked();
788
+
789
+ for (const tile of tiles()) {
790
+ expect(tile.children).toHaveLength(2);
791
+ expect(tile).not.toHaveClass("group");
792
+ }
793
+ });
794
+
795
+ test("each tile shows its catalog icon, and no two tiles share one", () => {
796
+ renderEmptyState();
797
+
798
+ const markups: Array<string> = SecurityEventConnectorCatalog.map(
799
+ (definition: SecurityEventConnectorDefinition): string => {
800
+ const badge: Element = tileFor(definition.provider).children[0]!;
801
+ expect(badge).toHaveAttribute("aria-hidden", "true");
802
+ const markup: string = svgMarkup(badge);
803
+ expect(markup.length).toBeGreaterThan(0);
804
+ return markup;
805
+ },
806
+ );
807
+ expect(new Set(markups).size).toBe(markups.length);
808
+
809
+ SecurityEventConnectorCatalog.forEach(
810
+ (definition: SecurityEventConnectorDefinition, index: number): void => {
811
+ expect(markups[index]).toBe(iconMarkup(definition.icon));
812
+ },
813
+ );
814
+ });
815
+
816
+ test("tiles use the empty state's id as their prefix", () => {
817
+ renderEmptyState();
818
+
819
+ for (const definition of SecurityEventConnectorCatalog) {
820
+ expect(connectButton(definition.title)).toHaveAttribute(
821
+ "aria-describedby",
822
+ `${ID}-provider-${definition.provider}-category`,
823
+ );
824
+ }
216
825
  });
217
826
  });
218
827
 
219
828
  describe("requirements", () => {
220
- test("lists a read-only credential and a running worker, in that order", () => {
829
+ test("are a region and a list named What you'll need", () => {
221
830
  renderEmptyState();
222
831
 
223
- const requirements: HTMLElement = document.getElementById(
224
- `${SECURITY_EVENT_CONNECTIONS_EMPTY_STATE_ID}-requirements`,
225
- ) as HTMLElement;
832
+ const region: HTMLElement = screen.getByRole("region", {
833
+ name: "What you'll need",
834
+ });
835
+ expect(region).toBe(requirementsSection());
226
836
  expect(
227
- within(requirements).getByRole("heading", {
837
+ within(region).getByRole("heading", {
228
838
  level: 4,
229
- name: "Before you connect",
839
+ name: "What you'll need",
230
840
  }),
231
- ).toBeInTheDocument();
841
+ ).toHaveAttribute("id", `${ID}-requirements-heading`);
842
+ expect(
843
+ within(region).getByRole("list", { name: "What you'll need" }),
844
+ ).toHaveAttribute("aria-labelledby", `${ID}-requirements-heading`);
845
+ });
232
846
 
233
- const items: Array<HTMLElement> =
234
- within(requirements).getAllByRole("listitem");
847
+ test("lists a read-only credential and a running worker, in that order", () => {
848
+ renderEmptyState();
849
+
850
+ const items: Array<HTMLElement> = within(
851
+ screen.getByRole("list", { name: "What you'll need" }),
852
+ ).getAllByRole("listitem");
235
853
  expect(items).toHaveLength(2);
236
854
  expect(items[0]).toHaveTextContent("A read-only credential");
237
855
  expect(items[0]).toHaveTextContent(
@@ -259,190 +877,333 @@ describe("SecurityEventConnectionsEmptyState", () => {
259
877
 
260
878
  for (const requirement of SECURITY_EVENT_CONNECTION_REQUIREMENTS) {
261
879
  const item: HTMLElement = screen.getByTestId(
262
- `${SECURITY_EVENT_CONNECTIONS_EMPTY_STATE_ID}-requirement-${requirement.id}`,
880
+ `${ID}-requirement-${requirement.id}`,
263
881
  );
882
+ expect(requirementsSection()).toContainElement(item);
264
883
  expect(item).toHaveTextContent(requirement.title);
265
884
  expect(item).toHaveTextContent(requirement.description);
885
+ const iconBadge: Element = item.children[0]!;
886
+ expect(iconBadge).toHaveAttribute("aria-hidden", "true");
266
887
  const svg: SVGElement | null = item.querySelector("svg");
267
888
  expect(svg).not.toBeNull();
268
889
  expect(svg).toHaveAttribute("aria-hidden", "true");
890
+ expect(svg!.innerHTML).toBe(iconMarkup(requirement.icon));
269
891
  }
270
892
  });
271
893
 
272
894
  test("stack on narrow screens and sit side by side from md up", () => {
273
895
  renderEmptyState();
274
896
 
275
- const list: HTMLElement = within(
276
- document.getElementById(
277
- `${SECURITY_EVENT_CONNECTIONS_EMPTY_STATE_ID}-requirements`,
278
- ) as HTMLElement,
279
- ).getByRole("list");
280
- expect(list).toHaveClass("grid", "md:grid-cols-2");
897
+ expect(
898
+ screen.getByRole("list", { name: "What you'll need" }),
899
+ ).toHaveClass("grid", "grid-cols-1", "md:grid-cols-2");
281
900
  });
282
901
 
283
902
  test("are shown to members who cannot create connections too", () => {
284
- renderEmptyState({ canCreate: false });
903
+ renderBlocked();
285
904
 
905
+ expect(
906
+ screen.getByRole("region", { name: "What you'll need" }),
907
+ ).toBeVisible();
286
908
  expect(screen.getByText("A read-only credential")).toBeVisible();
287
909
  expect(screen.getByText("A running OneUptime worker")).toBeVisible();
288
910
  });
289
911
  });
290
912
 
291
- describe("setup guides", () => {
292
- test("show one card per provider, in catalog order, with its category", () => {
913
+ describe("accessibility", () => {
914
+ test("has the Add button and one connect button per product, and nothing else", () => {
293
915
  renderEmptyState();
294
916
 
295
- const links: Array<HTMLElement> = within(guides()).getAllByRole("link");
296
- expect(links).toHaveLength(SecurityEventConnectorCatalog.length);
297
- links.forEach((link: HTMLElement, index: number): void => {
298
- const expected: { title: string; category: string } =
299
- EXPECTED_GUIDES[index]!;
300
- expect(link).toHaveAccessibleName(
301
- `${expected.title} ${expected.category} (opens in a new tab)`,
302
- );
303
- expect(within(link).getByText(expected.title)).toHaveClass(
304
- "font-medium",
305
- );
306
- expect(within(link).getByText(expected.category)).toHaveClass(
307
- "text-xs",
308
- );
309
- });
917
+ const names: Array<string> = screen
918
+ .getAllByRole("button")
919
+ .map((button: HTMLElement): string => {
920
+ return button.getAttribute("data-testid") === `${ID}-add-connection`
921
+ ? "Add connection"
922
+ : `tile:${button.getAttribute("data-provider-tile")}`;
923
+ });
924
+ expect(names).toEqual([
925
+ "Add connection",
926
+ ...EXPECTED_PRODUCTS.map(
927
+ (expected: { provider: SecurityEventConnectorProvider }): string => {
928
+ return `tile:${expected.provider}`;
929
+ },
930
+ ),
931
+ ]);
932
+ expect(screen.getAllByRole("button")).toHaveLength(
933
+ 1 + SecurityEventConnectorCatalog.length,
934
+ );
310
935
  });
311
936
 
312
- test("every card opens that provider's docs page in a new tab", () => {
313
- renderEmptyState();
937
+ test("a blocked member sees only the disabled Add button", () => {
938
+ renderBlocked();
314
939
 
315
- for (const definition of SecurityEventConnectorCatalog) {
316
- const link: HTMLElement = within(guides()).getByRole("link", {
317
- name: new RegExp(`^${definition.title} `),
940
+ const buttons: Array<HTMLElement> = screen.getAllByRole("button");
941
+ expect(buttons).toHaveLength(1);
942
+ expect(buttons[0]).toBe(addButton());
943
+ expect(buttons[0]).toBeDisabled();
944
+ });
945
+
946
+ test.each([true, false])(
947
+ "the only links are the eight setup guides, one per tile (canCreate: %s)",
948
+ (canCreate: boolean) => {
949
+ renderEmptyState({ canCreate });
950
+
951
+ const links: Array<HTMLElement> = screen.getAllByRole("link");
952
+ expect(links).toHaveLength(SecurityEventConnectorCatalog.length);
953
+ links.forEach((link: HTMLElement, index: number): void => {
954
+ expect(tiles()[index]).toContainElement(link);
955
+ expect(link).toHaveAccessibleName(
956
+ `${EXPECTED_PRODUCTS[index]!.title} Setup guide (opens in a new tab)`,
957
+ );
318
958
  });
319
- expect(link).toHaveAttribute(
320
- "href",
321
- connectorDocsUrl(definition).toString(),
322
- );
323
- expect(link.getAttribute("href")).toMatch(
324
- /\/docs\/integrations\/[a-z-]+$/,
959
+ },
960
+ );
961
+
962
+ test.each([true, false])(
963
+ "no control is nested inside another (canCreate: %s)",
964
+ (canCreate: boolean) => {
965
+ renderEmptyState({ canCreate, createDisabledReason: DISABLED_REASON });
966
+
967
+ expect(
968
+ root().querySelectorAll(
969
+ "a a, a button, button a, button button, a [tabindex], button [tabindex], a input, button input",
970
+ ),
971
+ ).toHaveLength(0);
972
+ },
973
+ );
974
+
975
+ test.each([true, false])(
976
+ "every id is unique and every aria reference resolves (canCreate: %s)",
977
+ (canCreate: boolean) => {
978
+ renderEmptyState({ canCreate, createDisabledReason: DISABLED_REASON });
979
+
980
+ const ids: Array<string> = Array.from(
981
+ root().querySelectorAll("[id]"),
982
+ ).map((element: Element): string => {
983
+ return element.id;
984
+ });
985
+ expect(new Set(ids).size).toBe(ids.length);
986
+
987
+ const references: Array<Element> = Array.from(
988
+ root().querySelectorAll("[aria-labelledby], [aria-describedby]"),
325
989
  );
326
- expect(link).toHaveAttribute("target", "_blank");
327
- expect(link).toHaveAttribute(
328
- "id",
329
- `${SECURITY_EVENT_CONNECTIONS_EMPTY_STATE_ID}-guides-${definition.provider}`,
990
+ expect(references.length).toBeGreaterThan(0);
991
+ for (const element of references) {
992
+ const referenced: Array<string> = [
993
+ element.getAttribute("aria-labelledby") || "",
994
+ element.getAttribute("aria-describedby") || "",
995
+ ]
996
+ .join(" ")
997
+ .split(/\s+/)
998
+ .filter((id: string): boolean => {
999
+ return id.length > 0;
1000
+ });
1001
+ for (const id of referenced) {
1002
+ expect(root()).toContainElement(document.getElementById(id));
1003
+ }
1004
+ }
1005
+ },
1006
+ );
1007
+
1008
+ test.each([true, false])(
1009
+ "every icon is hidden from assistive technology (canCreate: %s)",
1010
+ (canCreate: boolean) => {
1011
+ renderEmptyState({ canCreate, createDisabledReason: DISABLED_REASON });
1012
+
1013
+ const svgs: Array<SVGElement> = Array.from(
1014
+ root().querySelectorAll("svg"),
330
1015
  );
331
- }
332
- });
1016
+ expect(svgs.length).toBeGreaterThan(0);
1017
+ for (const svg of svgs) {
1018
+ expect(svg).toHaveAttribute("aria-hidden", "true");
1019
+ }
1020
+ expect(root().querySelectorAll("[role='img']")).toHaveLength(0);
1021
+ },
1022
+ );
333
1023
 
334
- test("Google SecOps is last and points at its own guide", () => {
1024
+ test("tabs through Add connection, then each tile's button and guide, in catalog order", async (): Promise<void> => {
335
1025
  renderEmptyState();
1026
+ const user: UserEvent = userEvent.setup({ delay: null });
336
1027
 
337
- const links: Array<HTMLElement> = within(guides()).getAllByRole("link");
338
- expect(links[links.length - 1]).toHaveAccessibleName(
339
- "Google SecOps SIEM (opens in a new tab)",
340
- );
341
- expect(links[links.length - 1]?.getAttribute("href")).toMatch(
342
- /\/docs\/integrations\/google-secops$/,
1028
+ const stops: Array<Element | null> = await tabStops(
1029
+ user,
1030
+ 1 + 2 * SecurityEventConnectorCatalog.length,
343
1031
  );
344
- });
345
-
346
- test("each card shows the provider's own icon", () => {
347
- renderEmptyState();
348
1032
 
1033
+ const expected: Array<HTMLElement> = [addButton()];
349
1034
  for (const definition of SecurityEventConnectorCatalog) {
350
- const link: HTMLElement = within(guides()).getByRole("link", {
351
- name: new RegExp(`^${definition.title} `),
352
- });
353
- // The provider icon, then the external-link marker.
354
- expect(link.querySelectorAll("svg")).toHaveLength(2);
1035
+ expected.push(connectButton(definition.title));
1036
+ expected.push(guideLinkFor(definition.title));
355
1037
  }
1038
+ expectSameElements(stops, expected);
356
1039
  });
357
1040
 
358
- test("are the only links in the empty state", () => {
359
- renderEmptyState();
1041
+ test("a blocked member tabs to the reason's wrapper, then the guides only", async (): Promise<void> => {
1042
+ renderBlocked();
1043
+ const user: UserEvent = userEvent.setup({ delay: null });
360
1044
 
361
- expect(screen.getAllByRole("link")).toHaveLength(
362
- within(guides()).getAllByRole("link").length,
1045
+ const stops: Array<Element | null> = await tabStops(
1046
+ user,
1047
+ 1 + SecurityEventConnectorCatalog.length,
363
1048
  );
1049
+
1050
+ expectSameElements(stops, [
1051
+ screen.getByTestId(`${ID}-add-connection-disabled-wrapper`),
1052
+ ...SecurityEventConnectorCatalog.map(
1053
+ (definition: SecurityEventConnectorDefinition): HTMLElement => {
1054
+ return guideLinkFor(definition.title);
1055
+ },
1056
+ ),
1057
+ ]);
1058
+ });
1059
+
1060
+ test("Enter on a focused tile button opens Add connection with that provider", async (): Promise<void> => {
1061
+ const onAddConnection: MockFunction = getJestMockFunction();
1062
+ renderEmptyState({ onAddConnection });
1063
+ const user: UserEvent = userEvent.setup({ delay: null });
1064
+
1065
+ // Add connection, then Sentinel's button and guide, then Defender's button.
1066
+ await tabStops(user, 4);
1067
+ expect(connectButton("Microsoft Defender XDR")).toHaveFocus();
1068
+ await user.keyboard("{Enter}");
1069
+
1070
+ expect(onAddConnection).toHaveBeenCalledTimes(1);
1071
+ expect(onAddConnection.mock.calls[0]).toEqual([
1072
+ SecurityEventConnectorProvider.MicrosoftDefenderXdr,
1073
+ ]);
1074
+ });
1075
+
1076
+ test("Space on the focused Add button opens it with no provider", async (): Promise<void> => {
1077
+ const onAddConnection: MockFunction = getJestMockFunction();
1078
+ renderEmptyState({ onAddConnection });
1079
+ const user: UserEvent = userEvent.setup({ delay: null });
1080
+
1081
+ await user.tab();
1082
+ expect(addButton()).toHaveFocus();
1083
+ await user.keyboard(" ");
1084
+
1085
+ expect(onAddConnection).toHaveBeenCalledTimes(1);
1086
+ expect(onAddConnection.mock.calls[0]).toEqual([]);
364
1087
  });
365
1088
  });
366
1089
 
367
- describe("securityEventConnectorGuideLinks", () => {
368
- test("maps the whole catalog by default", () => {
369
- const links: Array<EmptyStateGuideLink> =
370
- securityEventConnectorGuideLinks();
1090
+ describe("translation", () => {
1091
+ test("translates the copy but not product names or the permission reason", () => {
1092
+ renderEmptyState({
1093
+ canCreate: false,
1094
+ createDisabledReason: DISABLED_REASON,
1095
+ translations: german,
1096
+ });
371
1097
 
372
- expect(links).toHaveLength(SecurityEventConnectorCatalog.length);
373
1098
  expect(
374
- links.map((link: EmptyStateGuideLink): string => {
375
- return link.id;
1099
+ screen.getByRole("heading", {
1100
+ level: 3,
1101
+ name: "Noch keine Verbindungen für Sicherheitsereignisse",
376
1102
  }),
377
- ).toEqual(
378
- SecurityEventConnectorCatalog.map(
379
- (definition: SecurityEventConnectorDefinition): string => {
380
- return definition.provider;
381
- },
382
- ),
1103
+ ).toBeInTheDocument();
1104
+ expect(
1105
+ screen.getByRole("region", { name: "Unterstützte Produkte" }),
1106
+ ).toBe(providersSection());
1107
+ expect(screen.getByRole("region", { name: "Was Sie brauchen" })).toBe(
1108
+ requirementsSection(),
383
1109
  );
384
- });
1110
+ expect(screen.getByText("Ein schreibgeschützter Zugang")).toBeVisible();
1111
+ expect(addButton()).toHaveTextContent("Verbindung hinzufügen");
385
1112
 
386
- test("carries each provider's title, category, icon and docs URL", () => {
387
- const links: Array<EmptyStateGuideLink> =
388
- securityEventConnectorGuideLinks();
389
-
390
- SecurityEventConnectorCatalog.forEach(
391
- (definition: SecurityEventConnectorDefinition, index: number): void => {
392
- const link: EmptyStateGuideLink = links[index]!;
393
- expect(link.title).toBe(definition.title);
394
- expect(link.subtitle).toBe(definition.category);
395
- expect(link.icon).toBe(definition.icon);
396
- expect(link.to.toString()).toBe(
397
- connectorDocsUrl(definition).toString(),
398
- );
399
- expect(link.openInNewTab).toBe(true);
400
- },
1113
+ expect(
1114
+ within(
1115
+ tileFor(SecurityEventConnectorProvider.MicrosoftSentinel),
1116
+ ).getByText("Microsoft Sentinel", { selector: "p" }),
1117
+ ).toBeInTheDocument();
1118
+ expect(screen.queryByText("Microsoft Wächter")).not.toBeInTheDocument();
1119
+ expect(screen.getByTestId(`${ID}-disabled-reason`).textContent).toBe(
1120
+ DISABLED_REASON,
401
1121
  );
402
1122
  });
403
1123
 
404
- test("maps a given catalog, keeping its order", () => {
405
- const okta: SecurityEventConnectorDefinition =
406
- SecurityEventConnectorCatalog.find(
407
- (definition: SecurityEventConnectorDefinition): boolean => {
408
- return (
409
- definition.provider ===
410
- SecurityEventConnectorProvider.OktaSystemLog
411
- );
412
- },
413
- )!;
414
- const sentinel: SecurityEventConnectorDefinition =
415
- SecurityEventConnectorCatalog.find(
416
- (definition: SecurityEventConnectorDefinition): boolean => {
417
- return (
418
- definition.provider ===
419
- SecurityEventConnectorProvider.MicrosoftSentinel
420
- );
421
- },
422
- )!;
423
-
424
- const links: Array<EmptyStateGuideLink> =
425
- securityEventConnectorGuideLinks([okta, sentinel]);
1124
+ test("tile buttons and guides use the translated labels around the brand", () => {
1125
+ renderEmptyState({ translations: german });
426
1126
 
427
1127
  expect(
428
- links.map((link: EmptyStateGuideLink): string => {
429
- return link.title;
1128
+ screen.getByRole("button", { name: "Verbinden Microsoft Sentinel" }),
1129
+ ).toBeInTheDocument();
1130
+ expect(
1131
+ screen.getByRole("link", {
1132
+ name: "Microsoft Sentinel Einrichtungsanleitung (öffnet in einem neuen Tab)",
430
1133
  }),
431
- ).toEqual(["Okta System Log", "Microsoft Sentinel"]);
1134
+ ).toBeInTheDocument();
1135
+ expect(
1136
+ screen.getByRole("region", { name: "Wählen Sie ein Produkt" }),
1137
+ ).toBe(providersSection());
432
1138
  });
1139
+ });
433
1140
 
434
- test("an empty catalog gives no links", () => {
435
- expect(securityEventConnectorGuideLinks([])).toEqual([]);
1141
+ describe("regressions", () => {
1142
+ test("there is no Setup guides list of docs cards any more", () => {
1143
+ renderEmptyState();
1144
+
1145
+ expect(
1146
+ screen.queryByRole("list", { name: "Setup guides" }),
1147
+ ).not.toBeInTheDocument();
1148
+ expect(screen.queryByText("Setup guides")).not.toBeInTheDocument();
1149
+ expect(document.getElementById(`${ID}-guides`)).toBeNull();
1150
+ expect(root().querySelectorAll(`[id^='${ID}-guides']`)).toHaveLength(0);
436
1151
  });
437
1152
 
438
- test("provider ids are unique, so they are safe React keys and element ids", () => {
439
- const ids: Array<string> = securityEventConnectorGuideLinks().map(
440
- (link: EmptyStateGuideLink): string => {
441
- return link.id;
1153
+ /*
1154
+ * The old cards were whole links holding the provider icon as well as
1155
+ * the external-link marker. A guide is now a small text link: its only
1156
+ * icon is the external-link marker, and the provider icon lives on the
1157
+ * tile outside it.
1158
+ */
1159
+ test("a guide link is not a docs card: it carries no provider icon", () => {
1160
+ renderEmptyState();
1161
+
1162
+ const externalLink: string = iconMarkup(IconProp.ExternalLink);
1163
+ for (const link of screen.getAllByRole("link")) {
1164
+ const svgs: Array<SVGElement> = Array.from(
1165
+ link.querySelectorAll("svg"),
1166
+ );
1167
+ expect(svgs).toHaveLength(1);
1168
+ expect(svgs[0]!.innerHTML).toBe(externalLink);
1169
+ }
1170
+ });
1171
+
1172
+ test("there is no Before you connect heading", () => {
1173
+ renderEmptyState();
1174
+
1175
+ expect(screen.queryByText("Before you connect")).not.toBeInTheDocument();
1176
+ expect(
1177
+ root().querySelectorAll("h4.uppercase, h4.tracking-wide"),
1178
+ ).toHaveLength(0);
1179
+ });
1180
+
1181
+ /*
1182
+ * Sentinel, Elastic and Google SecOps all used to be drawn with a
1183
+ * shield, three identical marks in a row of eight.
1184
+ */
1185
+ test("only one tile is drawn with the ShieldCheck icon", () => {
1186
+ renderEmptyState();
1187
+
1188
+ const shield: string = iconMarkup(IconProp.ShieldCheck);
1189
+ const shielded: Array<HTMLElement> = tiles().filter(
1190
+ (tile: HTMLElement): boolean => {
1191
+ return svgMarkup(tile.children[0]!) === shield;
442
1192
  },
443
1193
  );
444
-
445
- expect(new Set(ids).size).toBe(ids.length);
1194
+ expectSameElements(shielded, [
1195
+ tileFor(SecurityEventConnectorProvider.MicrosoftSentinel),
1196
+ ]);
1197
+ expect(
1198
+ svgMarkup(
1199
+ tileFor(SecurityEventConnectorProvider.ElasticSecurity).children[0]!,
1200
+ ),
1201
+ ).toBe(iconMarkup(IconProp.Database));
1202
+ expect(
1203
+ svgMarkup(
1204
+ tileFor(SecurityEventConnectorProvider.GoogleSecOps).children[0]!,
1205
+ ),
1206
+ ).toBe(iconMarkup(IconProp.ViewfinderCircle));
446
1207
  });
447
1208
  });
448
1209
  });