@oneuptime/common 14.0.1 → 14.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1241) hide show
  1. package/Models/DatabaseModels/AlertEpisodeMember.ts +8 -1
  2. package/Models/DatabaseModels/AlertFeed.ts +2 -0
  3. package/Models/DatabaseModels/AutoRemediationSuggestion.ts +63 -0
  4. package/Models/DatabaseModels/IncidentAlert.ts +540 -0
  5. package/Models/DatabaseModels/IncidentEpisodeMember.ts +8 -1
  6. package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +9 -2
  7. package/Models/DatabaseModels/IncidentFeed.ts +2 -0
  8. package/Models/DatabaseModels/IncidentPublicNote.ts +9 -2
  9. package/Models/DatabaseModels/Index.ts +2 -0
  10. package/Models/DatabaseModels/KubernetesCluster.ts +429 -0
  11. package/Models/DatabaseModels/Monitor.ts +48 -0
  12. package/Models/DatabaseModels/Project.ts +60 -0
  13. package/Models/DatabaseModels/RumApplication.ts +52 -1
  14. package/Models/DatabaseModels/Runner.ts +5 -4
  15. package/Models/DatabaseModels/RunnerJob.ts +66 -0
  16. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +10 -2
  17. package/Models/DatabaseModels/WorkflowVariable.ts +479 -2
  18. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +79 -25
  19. package/Server/API/AIInvestigationAPI.ts +341 -0
  20. package/Server/API/AutoRemediationAPI.ts +184 -2
  21. package/Server/API/CommonAPI.ts +70 -0
  22. package/Server/API/KubernetesClusterAiAccessAPI.ts +793 -0
  23. package/Server/API/MicrosoftTeamsAPI.ts +770 -315
  24. package/Server/API/MonitorAPI.ts +140 -0
  25. package/Server/API/OnCallScheduleTimelineAPI.ts +5 -21
  26. package/Server/API/SlackAPI.ts +447 -99
  27. package/Server/API/StatusPageAPI.ts +146 -26
  28. package/Server/API/TelemetryAPI.ts +216 -5
  29. package/Server/API/UserTwoFactorBackupCodeAPI.ts +1 -0
  30. package/Server/API/WorkflowVariableAPI.ts +156 -0
  31. package/Server/Infrastructure/GlobalCache.ts +35 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.ts +97 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.ts +129 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.ts +25 -0
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.ts +20 -0
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.ts +38 -0
  37. package/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.ts +28 -0
  38. package/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.ts +89 -0
  39. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +14 -0
  40. package/Server/Middleware/MasterAdminAuthorization.ts +28 -0
  41. package/Server/Middleware/TelemetryIngest.ts +47 -2
  42. package/Server/Middleware/UserAuthorization.ts +56 -2
  43. package/Server/Services/AIAgentService.ts +1 -0
  44. package/Server/Services/AccessTokenService.ts +121 -48
  45. package/Server/Services/AlertEpisodeMemberService.ts +9 -0
  46. package/Server/Services/AlertEpisodeService.ts +14 -1
  47. package/Server/Services/AlertService.ts +134 -22
  48. package/Server/Services/AutoRemediationRuleEngineService.ts +968 -39
  49. package/Server/Services/AutoRemediationRuleService.ts +118 -0
  50. package/Server/Services/BillingService.ts +1 -0
  51. package/Server/Services/InboundEmail/Providers/SendGridInboundProvider.ts +16 -22
  52. package/Server/Services/IncidentAlertService.ts +1811 -0
  53. package/Server/Services/IncidentEpisodeMemberService.ts +9 -0
  54. package/Server/Services/IncidentEpisodePublicNoteService.ts +66 -0
  55. package/Server/Services/IncidentEpisodeRoleMemberService.ts +27 -0
  56. package/Server/Services/IncidentEpisodeService.ts +14 -1
  57. package/Server/Services/IncidentGroupingEngineService.ts +11 -0
  58. package/Server/Services/IncidentMemberService.ts +21 -0
  59. package/Server/Services/IncidentPublicNoteService.ts +63 -0
  60. package/Server/Services/IncidentService.ts +330 -30
  61. package/Server/Services/IncidentStateTimelineService.ts +39 -0
  62. package/Server/Services/IncidentTemplateService.ts +83 -3
  63. package/Server/Services/Index.ts +2 -0
  64. package/Server/Services/KubernetesClusterAiAccessService.ts +1943 -0
  65. package/Server/Services/KubernetesClusterService.ts +1570 -1
  66. package/Server/Services/LogAggregationService.ts +14 -6
  67. package/Server/Services/MonitorService.ts +651 -52
  68. package/Server/Services/MonitorStatusTimelineService.ts +639 -2
  69. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +2 -0
  70. package/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.ts +2 -0
  71. package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +2 -0
  72. package/Server/Services/OnCallDutyPolicyScheduleService.ts +3 -0
  73. package/Server/Services/OnCallNotificationAlertingService.ts +36 -12
  74. package/Server/Services/OnCallSetupReminderService.ts +1 -0
  75. package/Server/Services/ProbeService.ts +7 -1
  76. package/Server/Services/ProjectService.ts +11 -1
  77. package/Server/Services/RunbookCredentialService.ts +26 -1
  78. package/Server/Services/RunbookSecretService.ts +36 -0
  79. package/Server/Services/RunnerJobService.ts +941 -23
  80. package/Server/Services/RunnerService.ts +439 -6
  81. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +66 -0
  82. package/Server/Services/ScheduledMaintenanceService.ts +124 -19
  83. package/Server/Services/ScheduledMaintenanceTemplateService.ts +82 -3
  84. package/Server/Services/ServiceLevelObjectiveService.ts +14 -1
  85. package/Server/Services/StatusPagePrivateUserService.ts +1 -0
  86. package/Server/Services/StatusPageService.ts +301 -74
  87. package/Server/Services/StatusPageSubscriberService.ts +4 -0
  88. package/Server/Services/TeamMemberService.ts +309 -7
  89. package/Server/Services/TraceAggregationService.ts +10 -6
  90. package/Server/Services/UserEmailService.ts +1 -0
  91. package/Server/Services/UserNotificationMethodAdminService.ts +1 -0
  92. package/Server/Services/UserNotificationRuleAdminService.ts +1 -0
  93. package/Server/Services/UserNotificationRuleService.ts +4 -0
  94. package/Server/Services/UserService.ts +122 -1
  95. package/Server/Services/WorkflowVariableService.ts +593 -8
  96. package/Server/Services/WorkspaceNotificationRuleService.ts +588 -8
  97. package/Server/Services/WorkspaceProjectAuthTokenService.ts +170 -1
  98. package/Server/Types/Database/QueryHelper.ts +22 -0
  99. package/Server/Types/Markdown.ts +502 -27
  100. package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +182 -0
  101. package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +525 -0
  102. package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +854 -0
  103. package/Server/Utils/AI/CodeFix/CodeFixAgentAuth.ts +22 -2
  104. package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +1916 -307
  105. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +1601 -74
  106. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +139 -7
  107. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +58 -1
  108. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +54 -1
  109. package/Server/Utils/AI/Toolbox/AIActionTools.ts +14 -6
  110. package/Server/Utils/AI/Toolbox/ResourceTools.ts +4 -2
  111. package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +1341 -150
  112. package/Server/Utils/AutoRemediation/RemediationVerifier.ts +375 -4
  113. package/Server/Utils/Database/AffectedResourceRelations.ts +127 -0
  114. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +240 -1
  115. package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +1 -0
  116. package/Server/Utils/Monitor/MonitorAlert.ts +83 -9
  117. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +5 -1
  118. package/Server/Utils/Monitor/MonitorIncident.ts +104 -9
  119. package/Server/Utils/Monitor/MonitorPayloadRedaction.ts +124 -7
  120. package/Server/Utils/Monitor/ProbeMonitorsNotification.ts +407 -0
  121. package/Server/Utils/OnCall/OnCallShiftReminderRunner.ts +1 -0
  122. package/Server/Utils/PushNotificationUtil.ts +45 -0
  123. package/Server/Utils/Rules/OwnerRuleAssignment.ts +40 -3
  124. package/Server/Utils/Runbook/RunbookExecutePermission.ts +56 -6
  125. package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +24 -2
  126. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +223 -33
  127. package/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.ts +559 -0
  128. package/Server/Utils/StartServer.ts +4 -3
  129. package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +528 -0
  130. package/Server/Utils/TwoFactorBackupCodeNotification.ts +1 -0
  131. package/Server/Utils/UserPermission/UserPermission.ts +16 -0
  132. package/Server/Utils/Workflow/OAuth2TokenClient.ts +704 -0
  133. package/Server/Utils/Workflow/WorkflowVariableOAuthToken.ts +318 -0
  134. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +47 -7
  135. package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +57 -16
  136. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +193 -214
  137. package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +57 -13
  138. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.ts +54 -17
  139. package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +179 -161
  140. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +281 -167
  141. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.ts +114 -0
  142. package/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.ts +895 -0
  143. package/Server/Utils/Workspace/Slack/Actions/ActionTypes.ts +7 -9
  144. package/Server/Utils/Workspace/Slack/Actions/Alert.ts +96 -227
  145. package/Server/Utils/Workspace/Slack/Actions/AlertEpisode.ts +93 -214
  146. package/Server/Utils/Workspace/Slack/Actions/Auth.ts +30 -3
  147. package/Server/Utils/Workspace/Slack/Actions/Authorization.ts +99 -0
  148. package/Server/Utils/Workspace/Slack/Actions/Incident.ts +117 -283
  149. package/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.ts +101 -196
  150. package/Server/Utils/Workspace/Slack/Actions/ReactionNote.ts +329 -0
  151. package/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.ts +111 -287
  152. package/Server/Utils/Workspace/Slack/Slack.ts +86 -17
  153. package/Server/Utils/Workspace/Slack/app-manifest.json +2 -0
  154. package/Server/Utils/Workspace/Workspace.ts +171 -54
  155. package/Server/Utils/Workspace/WorkspaceActionAuthorization.ts +252 -0
  156. package/Server/Utils/Workspace/WorkspaceBase.ts +39 -0
  157. package/Server/Utils/Workspace/WorkspaceOAuthState.ts +280 -0
  158. package/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.ts +96 -0
  159. package/Server/Utils/Workspace/WorkspaceReactionNote.ts +620 -0
  160. package/Tests/App/Dashboard/AttributesJSONDashboardSurfaces.test.tsx +496 -0
  161. package/Tests/App/Dashboard/AutoRemediationRulesTableCommandRunners.test.tsx +152 -0
  162. package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +32 -0
  163. package/Tests/App/Dashboard/BulkIncidentLinkActions.test.tsx +869 -0
  164. package/Tests/App/Dashboard/CephMetricTooltips.test.tsx +1777 -0
  165. package/Tests/App/Dashboard/CloudFleetSummary.test.ts +8 -0
  166. package/Tests/App/Dashboard/CloudMetricTooltips.test.tsx +887 -0
  167. package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +794 -0
  168. package/Tests/App/Dashboard/ContainerHostMetricTooltips.test.tsx +1309 -0
  169. package/Tests/App/Dashboard/CreateOAuthWorkflowVariableModal.test.tsx +840 -0
  170. package/Tests/App/Dashboard/CreateWorkflowModal.test.tsx +653 -0
  171. package/Tests/App/Dashboard/DatabaseMonitorStepForm.test.tsx +197 -0
  172. package/Tests/App/Dashboard/DatabaseMonitorView.test.tsx +376 -0
  173. package/Tests/App/Dashboard/DisabledWarningRobustness.test.tsx +262 -0
  174. package/Tests/App/Dashboard/DiscoveryScanLivePage.test.tsx +39 -0
  175. package/Tests/App/Dashboard/DockerSwarmClustersListTooltips.test.tsx +414 -0
  176. package/Tests/App/Dashboard/DockerSwarmMetricTooltips.test.ts +796 -0
  177. package/Tests/App/Dashboard/DockerSwarmOverviewTooltips.test.tsx +747 -0
  178. package/Tests/App/Dashboard/EventNotes.test.tsx +2080 -0
  179. package/Tests/App/Dashboard/EventNotesPages.test.tsx +486 -0
  180. package/Tests/App/Dashboard/EventNotesUtil.test.ts +933 -0
  181. package/Tests/App/Dashboard/ExceptionMonitorEnvironmentFilter.test.tsx +238 -0
  182. package/Tests/App/Dashboard/HostDetailViewTooltips.test.tsx +725 -0
  183. package/Tests/App/Dashboard/HostListColumnTooltips.test.tsx +472 -0
  184. package/Tests/App/Dashboard/HostMetricTooltips.test.ts +709 -0
  185. package/Tests/App/Dashboard/HostOverviewTooltips.test.tsx +698 -0
  186. package/Tests/App/Dashboard/HostTooltipHarness.ts +124 -0
  187. package/Tests/App/Dashboard/HostsListTooltips.test.tsx +395 -0
  188. package/Tests/App/Dashboard/IncidentAlertLinkDialog.test.tsx +691 -0
  189. package/Tests/App/Dashboard/IncidentAlertLinkHelpers.test.ts +458 -0
  190. package/Tests/App/Dashboard/IncidentAlertLinkPages.test.tsx +828 -0
  191. package/Tests/App/Dashboard/IncidentAlertLinkSideMenus.test.tsx +231 -0
  192. package/Tests/App/Dashboard/IncidentChangeStateNotifyDefault.test.tsx +665 -0
  193. package/Tests/App/Dashboard/IncidentCreateFromAlerts.test.tsx +689 -0
  194. package/Tests/App/Dashboard/IncidentEpisodeFeedPublicNoteNotifyDefault.test.tsx +494 -0
  195. package/Tests/App/Dashboard/IncidentEpisodeOverviewNotifyDefault.test.tsx +706 -0
  196. package/Tests/App/Dashboard/IncidentFeedPublicNoteNotifyDefault.test.tsx +472 -0
  197. package/Tests/App/Dashboard/IncidentOverviewNotifyDefault.test.tsx +858 -0
  198. package/Tests/App/Dashboard/IncomingEmailAddressSettings.test.tsx +567 -0
  199. package/Tests/App/Dashboard/InvestigationClusterToolFormat.test.ts +241 -0
  200. package/Tests/App/Dashboard/InvestigationEvidenceKubectl.test.tsx +322 -0
  201. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +12 -0
  202. package/Tests/App/Dashboard/InvestigationPanelClusterAccess.test.tsx +476 -0
  203. package/Tests/App/Dashboard/InvestigationRunDetailsKubectl.test.tsx +383 -0
  204. package/Tests/App/Dashboard/IoTMetricTooltips.test.tsx +1123 -0
  205. package/Tests/App/Dashboard/KubectlActivitySummary.test.tsx +366 -0
  206. package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +2886 -0
  207. package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +2688 -0
  208. package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +915 -0
  209. package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +837 -0
  210. package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +699 -0
  211. package/Tests/App/Dashboard/KubernetesContainersTabTooltips.test.tsx +320 -0
  212. package/Tests/App/Dashboard/KubernetesCostTooltips.test.tsx +502 -0
  213. package/Tests/App/Dashboard/KubernetesInsightsTooltips.test.tsx +222 -0
  214. package/Tests/App/Dashboard/KubernetesResourceMetricTooltips.test.ts +561 -0
  215. package/Tests/App/Dashboard/KubernetesResourcePagesTooltips.test.tsx +1168 -0
  216. package/Tests/App/Dashboard/LayerDateTimeFieldTimezoneName.test.tsx +66 -0
  217. package/Tests/App/Dashboard/LinkIncidentAlertModal.test.tsx +154 -0
  218. package/Tests/App/Dashboard/LogMonitorPreview.test.tsx +174 -0
  219. package/Tests/App/Dashboard/MetricDescriptionRules.ts +170 -0
  220. package/Tests/App/Dashboard/MetricDescriptionsCatalog.test.ts +206 -0
  221. package/Tests/App/Dashboard/MetricDescriptionsConsistency.test.ts +275 -0
  222. package/Tests/App/Dashboard/MonitorFeedRefresh.test.tsx +279 -0
  223. package/Tests/App/Dashboard/MonitorMetricQueryConfig.test.ts +244 -0
  224. package/Tests/App/Dashboard/MonitorOpenWorkCard.test.tsx +381 -0
  225. package/Tests/App/Dashboard/MonitorOpenWorkHook.test.tsx +784 -0
  226. package/Tests/App/Dashboard/MonitorOverviewData.test.tsx +2199 -0
  227. package/Tests/App/Dashboard/MonitorOverviewHero.test.tsx +1169 -0
  228. package/Tests/App/Dashboard/MonitorOverviewInput.test.ts +1127 -0
  229. package/Tests/App/Dashboard/MonitorOverviewPage.test.tsx +2136 -0
  230. package/Tests/App/Dashboard/MonitorOverviewSelectReadable.test.ts +368 -0
  231. package/Tests/App/Dashboard/MonitorOverviewStatBar.test.tsx +526 -0
  232. package/Tests/App/Dashboard/MonitorOverviewSupportingCards.test.tsx +542 -0
  233. package/Tests/App/Dashboard/MonitorOwnersCombine.test.ts +299 -0
  234. package/Tests/App/Dashboard/MonitorProbesCard.test.tsx +602 -0
  235. package/Tests/App/Dashboard/MonitorResponseTimeCard.test.tsx +386 -0
  236. package/Tests/App/Dashboard/MonitorSetupAndConnectionCards.test.tsx +612 -0
  237. package/Tests/App/Dashboard/MonitorStatusChangesCard.test.tsx +257 -0
  238. package/Tests/App/Dashboard/MonitorSummaryTestMonitorButton.test.tsx +360 -1
  239. package/Tests/App/Dashboard/MonitorUptimeHistoryCard.test.tsx +835 -0
  240. package/Tests/App/Dashboard/MonitorUptimeSummaryHook.test.tsx +971 -0
  241. package/Tests/App/Dashboard/MonitorViewLayout.test.tsx +580 -0
  242. package/Tests/App/Dashboard/NetworkDeviceTooltips.test.tsx +852 -0
  243. package/Tests/App/Dashboard/NetworkDiagnosticsTooltips.test.tsx +556 -0
  244. package/Tests/App/Dashboard/NetworkMetricTooltips.test.ts +1348 -0
  245. package/Tests/App/Dashboard/NetworkSiteTooltips.test.tsx +679 -0
  246. package/Tests/App/Dashboard/OnCallLayerRestrictionTimesPreserved.test.tsx +441 -0
  247. package/Tests/App/Dashboard/OnCallNavbar.test.tsx +214 -0
  248. package/Tests/App/Dashboard/OnCallSchedulePreviewCalendarDisplay.test.tsx +1389 -0
  249. package/Tests/App/Dashboard/OnCallSchedulePreviewOverrides.test.tsx +205 -1
  250. package/Tests/App/Dashboard/OnCallScheduleTimeInputsSettingsZone.test.tsx +198 -0
  251. package/Tests/App/Dashboard/ProxmoxMetricTooltips.test.ts +592 -0
  252. package/Tests/App/Dashboard/ProxmoxOverviewTooltips.test.tsx +1002 -0
  253. package/Tests/App/Dashboard/ProxmoxResourcePageTooltips.test.tsx +923 -0
  254. package/Tests/App/Dashboard/PublicNotePagesNotifyDefault.test.tsx +524 -0
  255. package/Tests/App/Dashboard/RemediationSuggestionCardApproval.test.tsx +702 -0
  256. package/Tests/App/Dashboard/RemoveUserFromProject.test.tsx +427 -0
  257. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +4 -0
  258. package/Tests/App/Dashboard/ResourceOverviewTileTooltips.test.tsx +1066 -0
  259. package/Tests/App/Dashboard/RumOverviewPage.test.tsx +1195 -0
  260. package/Tests/App/Dashboard/RumSessionReplaySideMenu.test.tsx +3 -1
  261. package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +166 -0
  262. package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +622 -0
  263. package/Tests/App/Dashboard/ScheduledMaintenanceChangeStateNotifyDefault.test.tsx +1491 -0
  264. package/Tests/App/Dashboard/ScheduledMaintenanceFeedPublicNoteNotifyDefault.test.tsx +489 -0
  265. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewNotifyDefault.test.tsx +909 -0
  266. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +14 -0
  267. package/Tests/App/Dashboard/ScheduledMaintenanceWindowStatsTranslation.test.tsx +307 -0
  268. package/Tests/App/Dashboard/SecurityEventAttributeColumnPicker.test.tsx +542 -0
  269. package/Tests/App/Dashboard/SecurityEventConnectionFormModal.test.tsx +174 -0
  270. package/Tests/App/Dashboard/SecurityEventConnectionsEmptyState.test.tsx +973 -212
  271. package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +491 -52
  272. package/Tests/App/Dashboard/SecurityEventDetailPanel.test.tsx +301 -0
  273. package/Tests/App/Dashboard/SecurityEventListRow.test.tsx +158 -1
  274. package/Tests/App/Dashboard/SecurityEventProviderTile.test.tsx +869 -0
  275. package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +959 -94
  276. package/Tests/App/Dashboard/SecurityEventsNoResults.test.tsx +2 -0
  277. package/Tests/App/Dashboard/SecurityEventsViewer.test.tsx +274 -1
  278. package/Tests/App/Dashboard/ServerlessMetricTooltips.test.tsx +474 -0
  279. package/Tests/App/Dashboard/ServiceMetricTooltips.test.tsx +772 -0
  280. package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +56 -1
  281. package/Tests/App/Dashboard/TeamMembershipRemoval.test.ts +900 -0
  282. package/Tests/App/Dashboard/TeamMembershipRemovalPages.test.tsx +460 -0
  283. package/Tests/App/Dashboard/TelemetryMetricsSignals.test.ts +1207 -0
  284. package/Tests/App/Dashboard/TelemetryResourceTabTooltips.test.tsx +437 -0
  285. package/Tests/App/Dashboard/TimezoneElements.test.tsx +321 -0
  286. package/Tests/App/Dashboard/TimezoneSelectButton.test.tsx +634 -0
  287. package/Tests/App/Dashboard/TraceExplorer.test.tsx +260 -0
  288. package/Tests/App/Dashboard/TraceMonitorPreview.test.tsx +182 -0
  289. package/Tests/App/Dashboard/UserTimezoneInit.test.tsx +544 -0
  290. package/Tests/App/Dashboard/VMwareMetricTooltips.test.ts +801 -0
  291. package/Tests/App/Dashboard/VMwareOverviewTooltips.test.tsx +601 -0
  292. package/Tests/App/Dashboard/VMwareResourcePagesTooltips.test.tsx +646 -0
  293. package/Tests/App/Dashboard/VMwareTooltipHarness.ts +145 -0
  294. package/Tests/App/Dashboard/WorkflowVariableModals.test.tsx +1630 -0
  295. package/Tests/App/Dashboard/WorkflowVariableRoutes.test.tsx +603 -0
  296. package/Tests/App/Dashboard/WorkflowVariableTokenStatus.test.tsx +589 -0
  297. package/Tests/App/Dashboard/WorkflowVariableUtil.test.ts +1543 -0
  298. package/Tests/App/Dashboard/WorkflowVariableView.test.tsx +3227 -0
  299. package/Tests/App/Dashboard/WorkflowVariablesTable.test.tsx +1277 -395
  300. package/Tests/App/StatusPage/StatusPageOverviewMonitorGroupUptime.test.tsx +714 -0
  301. package/Tests/App/StatusPage/StatusPageOverviewUptimeBars.NewYork.test.tsx +1009 -0
  302. package/Tests/App/StatusPage/StatusPageOverviewUptimeBars.test.tsx +1092 -0
  303. package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +5 -0
  304. package/Tests/Models/DatabaseModels/IncidentAlertModel.test.ts +554 -0
  305. package/Tests/Models/DatabaseModels/KubernetesClusterAiAccessColumns.test.ts +520 -0
  306. package/Tests/Models/DatabaseModels/MonitorSecretKeyColumnAccessControl.test.ts +66 -2
  307. package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +117 -0
  308. package/Tests/Models/DatabaseModels/WorkspaceProjectAuthTokenAccessControl.test.ts +236 -0
  309. package/Tests/Models/IncidentEpisodePublicNoteNotifyColumnContract.test.ts +103 -0
  310. package/Tests/Models/IncidentPublicNoteNotifyColumnContract.test.ts +96 -0
  311. package/Tests/Models/ScheduledMaintenancePublicNoteNotifyColumnContract.test.ts +111 -0
  312. package/Tests/Server/API/AIInvestigationAPI.test.ts +976 -0
  313. package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +836 -0
  314. package/Tests/Server/API/CommonAPIAssertCanCreateTable.test.ts +565 -0
  315. package/Tests/Server/API/CommonAPIAssertCanReadTable.test.ts +282 -0
  316. package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +1744 -0
  317. package/Tests/Server/API/LogHistogramAPI.test.ts +371 -0
  318. package/Tests/Server/API/MicrosoftTeamsLegacyWebhookRemoval.test.ts +125 -30
  319. package/Tests/Server/API/MicrosoftTeamsOAuthState.test.ts +1121 -0
  320. package/Tests/Server/API/MonitorUptimeSummaryAPI.test.ts +685 -0
  321. package/Tests/Server/API/SessionReplayAPI.test.ts +602 -1
  322. package/Tests/Server/API/SlackChannelCacheAPI.test.ts +358 -0
  323. package/Tests/Server/API/SlackOAuthState.test.ts +688 -0
  324. package/Tests/Server/API/StatusPageOverviewMonitorGroupUptime.test.ts +527 -0
  325. package/Tests/Server/API/StatusPageTestEmailReportAuth.test.ts +2 -0
  326. package/Tests/Server/API/StatusPageUptimeAPI.test.ts +427 -0
  327. package/Tests/Server/API/UserProjectsAPI.test.ts +4 -0
  328. package/Tests/Server/API/WorkflowVariableAPI.test.ts +404 -0
  329. package/Tests/Server/API/WorkspaceOAuthTestHelpers.ts +289 -0
  330. package/Tests/Server/API/WorkspaceSendTestNotificationRoutes.test.ts +2064 -0
  331. package/Tests/Server/Infrastructure/GlobalCache.test.ts +86 -0
  332. package/Tests/Server/Infrastructure/Postgres/AddIncidentAlertMigration.test.ts +341 -0
  333. package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +589 -0
  334. package/Tests/Server/Infrastructure/Postgres/AddOAuth2WorkflowVariablesMigration.test.ts +254 -0
  335. package/Tests/Server/Infrastructure/Postgres/AddSessionReplaySameOriginTracePropagationMigration.test.ts +247 -0
  336. package/Tests/Server/Middleware/BlockedUserMiddleware.test.ts +403 -0
  337. package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +13 -0
  338. package/Tests/Server/Middleware/PublicRouteUserMiddleware.test.ts +2 -0
  339. package/Tests/Server/Middleware/RemovedProjectMemberAuthorization.test.ts +469 -0
  340. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +77 -1
  341. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +211 -0
  342. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +358 -0
  343. package/Tests/Server/Middleware/UserAuthorization.test.ts +97 -0
  344. package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +2 -0
  345. package/Tests/Server/Services/AccessTokenProjectUserGrant.test.ts +14 -2
  346. package/Tests/Server/Services/AccessTokenRemovedMemberAccess.test.ts +1044 -0
  347. package/Tests/Server/Services/AddOwnersIdempotency.test.ts +5 -0
  348. package/Tests/Server/Services/AlertEpisodeMemberCreatePermission.test.ts +139 -0
  349. package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +1361 -0
  350. package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +375 -0
  351. package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +2384 -0
  352. package/Tests/Server/Services/FindOwnersProjectMembership.test.ts +267 -0
  353. package/Tests/Server/Services/InboundEmail/SendGridInboundProviderAddress.test.ts +90 -0
  354. package/Tests/Server/Services/IncidentAlertPostgres.test.ts +903 -0
  355. package/Tests/Server/Services/IncidentAlertRegistration.test.ts +96 -0
  356. package/Tests/Server/Services/IncidentAlertService.test.ts +2225 -0
  357. package/Tests/Server/Services/IncidentAlertStateCascade.test.ts +970 -0
  358. package/Tests/Server/Services/IncidentCreateFromAlerts.test.ts +1284 -0
  359. package/Tests/Server/Services/IncidentEpisodeMemberCreatePermission.test.ts +143 -0
  360. package/Tests/Server/Services/IncidentEpisodePublicNoteNotifyDefault.test.ts +805 -0
  361. package/Tests/Server/Services/IncidentPublicNoteNotifyDefault.test.ts +724 -0
  362. package/Tests/Server/Services/IncidentRoleProjectMembership.test.ts +233 -0
  363. package/Tests/Server/Services/KubernetesClusterAiAccessAgentRunnerAssignments.test.ts +372 -0
  364. package/Tests/Server/Services/KubernetesClusterAiAccessBindingGuard.test.ts +1876 -0
  365. package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +620 -0
  366. package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +421 -0
  367. package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +3662 -0
  368. package/Tests/Server/Services/KubernetesClusterAiAccessSubjectClusters.test.ts +405 -0
  369. package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +975 -0
  370. package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +497 -0
  371. package/Tests/Server/Services/KubernetesClusterServiceDeleteSettlesRemediation.test.ts +328 -0
  372. package/Tests/Server/Services/LogAggregationService.test.ts +99 -0
  373. package/Tests/Server/Services/MonitorServiceIncomingEmailCustomAddress.test.ts +447 -0
  374. package/Tests/Server/Services/MonitorServiceProbeFlagSync.test.ts +1334 -0
  375. package/Tests/Server/Services/MonitorServiceProbeStatusGrouping.test.ts +1640 -0
  376. package/Tests/Server/Services/MonitorServiceRefreshCurrentStatus.test.ts +225 -0
  377. package/Tests/Server/Services/MonitorStatusBridgeProbePath.test.ts +8 -8
  378. package/Tests/Server/Services/MonitorStatusTimelineDailyAggregates.test.ts +264 -1
  379. package/Tests/Server/Services/MonitorStatusTimelineMergedDowntime.test.ts +284 -0
  380. package/Tests/Server/Services/MonitorUptimeSummaryService.test.ts +1043 -0
  381. package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +5 -0
  382. package/Tests/Server/Services/OnCallUndeliverablePageOwnerMembership.test.ts +359 -0
  383. package/Tests/Server/Services/ProbeServiceDashboardLink.test.ts +191 -0
  384. package/Tests/Server/Services/ProjectOwnersProjectMembership.test.ts +221 -0
  385. package/Tests/Server/Services/RuleRun/IncidentAlertMaintenanceRuleEnginesRun.test.ts +5 -0
  386. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupARun.test.ts +28 -0
  387. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +9 -1
  388. package/Tests/Server/Services/RunnerJobEnqueueAiCommandAgentRunner.test.ts +230 -0
  389. package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +978 -0
  390. package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +866 -0
  391. package/Tests/Server/Services/RunnerJobSubmitResultRedaction.test.ts +322 -0
  392. package/Tests/Server/Services/RunnerJobSubmitResultUnstorableText.test.ts +357 -0
  393. package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +227 -0
  394. package/Tests/Server/Services/RunnerServiceAgentName.test.ts +581 -0
  395. package/Tests/Server/Services/ScheduledMaintenancePublicNoteNotifyDefault.test.ts +802 -0
  396. package/Tests/Server/Services/ScheduledMaintenanceSubscriberTemplateFormats.test.ts +53 -0
  397. package/Tests/Server/Services/ServiceLevelObjectiveLabelAndOwnerRuleEngines.test.ts +5 -0
  398. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +12 -0
  399. package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +1176 -1
  400. package/Tests/Server/Services/TeamMemberBillingSeatSync.test.ts +9 -0
  401. package/Tests/Server/Services/TeamMemberOnCallCleanup.test.ts +18 -0
  402. package/Tests/Server/Services/TeamMemberProjectMembership.test.ts +255 -0
  403. package/Tests/Server/Services/TeamMemberRemovalRevokesProjectAccess.test.ts +600 -0
  404. package/Tests/Server/Services/TeamMemberResourceCleanup.test.ts +731 -0
  405. package/Tests/Server/Services/TeamMemberWorkspaceAccountCleanup.test.ts +164 -0
  406. package/Tests/Server/Services/TraceAggregationService.test.ts +64 -0
  407. package/Tests/Server/Services/UserServiceBlockedUser.test.ts +293 -0
  408. package/Tests/Server/Services/WorkflowVariableOAuthHooks.test.ts +1016 -0
  409. package/Tests/Server/Services/WorkflowVariableOAuthPostgres.test.ts +543 -0
  410. package/Tests/Server/Services/WorkflowVariableRenameUniqueness.test.ts +16 -5
  411. package/Tests/Server/Services/WorkspaceNotificationRuleNoteDelivery.test.ts +473 -0
  412. package/Tests/Server/Services/WorkspaceNotificationRuleSendTestNotification.test.ts +3690 -0
  413. package/Tests/Server/Services/WorkspaceProjectAuthTokenMiscDataSecrets.test.ts +374 -0
  414. package/Tests/Server/Services/WorkspaceProjectAuthTokenSlackChannelCache.test.ts +143 -0
  415. package/Tests/Server/Types/Database/Permissions/WorkflowVariableOAuthColumnPermission.test.ts +250 -0
  416. package/Tests/Server/Types/Database/QueryHelperJsonContains.test.ts +96 -0
  417. package/Tests/Server/Types/Markdown.test.ts +1033 -0
  418. package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +285 -0
  419. package/Tests/Server/Utils/AI/CodeFix/CodeFixAgentAuth.test.ts +159 -1
  420. package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +752 -0
  421. package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +1840 -0
  422. package/Tests/Server/Utils/AI/KubectlJobRunner.test.ts +1067 -0
  423. package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +355 -0
  424. package/Tests/Server/Utils/AI/PostIncidentStatusUpdateTool.test.ts +496 -0
  425. package/Tests/Server/Utils/AI/RemediationCommandTools.test.ts +305 -0
  426. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +1365 -0
  427. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +639 -0
  428. package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +1585 -0
  429. package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +1065 -0
  430. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +2138 -1
  431. package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +1035 -0
  432. package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +517 -0
  433. package/Tests/Server/Utils/AI/ResourceTools.test.ts +27 -1
  434. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +1371 -24
  435. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorRollbackRace.test.ts +962 -0
  436. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +518 -0
  437. package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +939 -2
  438. package/Tests/Server/Utils/Database/ProjectScopedRelationReferences.test.ts +371 -0
  439. package/Tests/Server/Utils/Monitor/AffectedResourceList.test.ts +64 -0
  440. package/Tests/Server/Utils/Monitor/DatabaseMetricObservationRemediation.test.ts +102 -0
  441. package/Tests/Server/Utils/Monitor/MonitorAlertCriteriaReferences.test.ts +362 -0
  442. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorBreachingSamples.test.ts +55 -0
  443. package/Tests/Server/Utils/Monitor/MonitorEmailAddressRedaction.test.ts +255 -0
  444. package/Tests/Server/Utils/Monitor/MonitorIncidentCriteriaReferences.test.ts +347 -0
  445. package/Tests/Server/Utils/Monitor/MonitorIncidentMemberRoleMembership.test.ts +203 -0
  446. package/Tests/Server/Utils/Monitor/ProbeMonitorsNotification.test.ts +1147 -0
  447. package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +79 -0
  448. package/Tests/Server/Utils/ResourceFeed/ResourceFeedUtil.test.ts +21 -1
  449. package/Tests/Server/Utils/Rules/OwnerRuleAssignment.test.ts +155 -1
  450. package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +103 -0
  451. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +288 -0
  452. package/Tests/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.test.ts +304 -0
  453. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +40 -3
  454. package/Tests/Server/Utils/Workflow/OAuth2TokenClient.test.ts +702 -0
  455. package/Tests/Server/Utils/Workflow/OAuth2TokenClientHttpIntegration.test.ts +507 -0
  456. package/Tests/Server/Utils/Workflow/WorkflowVariableOAuthToken.test.ts +831 -0
  457. package/Tests/Server/Utils/Workspace/MicrosoftTeamsActionAuthorization.test.ts +63 -1
  458. package/Tests/Server/Utils/Workspace/MicrosoftTeamsAppAccessToken.test.ts +256 -0
  459. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +60 -0
  460. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChatActionAuthorization.test.ts +442 -0
  461. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +44 -2
  462. package/Tests/Server/Utils/Workspace/MicrosoftTeamsDirectMessage.test.ts +55 -0
  463. package/Tests/Server/Utils/Workspace/MicrosoftTeamsReactionNoteSync.test.ts +1522 -0
  464. package/Tests/Server/Utils/Workspace/MicrosoftTeamsServiceUrl.test.ts +130 -0
  465. package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +4 -4
  466. package/Tests/Server/Utils/Workspace/Slack/SlackActionAuthorization.test.ts +691 -0
  467. package/Tests/Server/Utils/Workspace/Slack/SlackMessageByTimestamp.test.ts +253 -0
  468. package/Tests/Server/Utils/Workspace/Slack/SlackReactionNote.test.ts +574 -0
  469. package/Tests/Server/Utils/Workspace/WorkspaceActionAuthorization.test.ts +488 -0
  470. package/Tests/Server/Utils/Workspace/WorkspaceCreateProjectReferences.test.ts +861 -0
  471. package/Tests/Server/Utils/Workspace/WorkspaceMessageAuthor.test.ts +635 -0
  472. package/Tests/Server/Utils/Workspace/WorkspaceOAuthState.test.ts +548 -0
  473. package/Tests/Server/Utils/Workspace/WorkspaceReactionNote.test.ts +839 -0
  474. package/Tests/Server/Utils/Workspace/WorkspaceSendErrorMessage.test.ts +725 -0
  475. package/Tests/Types/AutoRemediation/AiRemediationCommandPlan.test.ts +283 -9
  476. package/Tests/Types/DateBrowserLocalWallClock.test.ts +280 -0
  477. package/Tests/Types/DateLocalShortMonthNameFallback.test.ts +389 -0
  478. package/Tests/Types/DateUserTimezone.test.ts +177 -4
  479. package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +306 -0
  480. package/Tests/Types/Kubernetes/KubernetesClusterAiAccess.test.ts +283 -0
  481. package/Tests/Types/Kubernetes/KubernetesRunnerPostureWriteScope.test.ts +68 -0
  482. package/Tests/Types/Monitor/DatabaseMonitor/SqlServerPlatform.test.ts +144 -0
  483. package/Tests/Types/Monitor/MonitorStepExceptionMonitor.test.ts +160 -0
  484. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +53 -0
  485. package/Tests/Types/Rum/WebVitals.test.ts +173 -0
  486. package/Tests/Types/Runbook/RunbookStepType.test.ts +91 -16
  487. package/Tests/Types/Runner/RunnerLiveStatus.test.ts +14 -3
  488. package/Tests/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.test.ts +15 -0
  489. package/Tests/Types/StatusPage/PublicNoteSubscriberNotificationDefault.test.ts +1868 -0
  490. package/Tests/Types/Timezone.test.ts +5 -0
  491. package/Tests/Types/TimezoneAlias.test.ts +1034 -0
  492. package/Tests/Types/Workflow/JiraTemplateFixtures.ts +833 -0
  493. package/Tests/Types/Workflow/JiraTemplateScripts.test.ts +5414 -0
  494. package/Tests/Types/Workflow/JiraTemplateSimulation.test.ts +4803 -0
  495. package/Tests/Types/Workflow/JiraTemplates.test.ts +5429 -0
  496. package/Tests/Types/Workflow/Templates.test.ts +79 -4
  497. package/Tests/Types/Workflow/WorkflowVariableOAuth.test.ts +520 -0
  498. package/Tests/Types/Workspace/WorkspaceNoteReaction.test.ts +177 -0
  499. package/Tests/UI/Components/AttributesJSON/AttributesJSONView.test.tsx +390 -0
  500. package/Tests/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.test.tsx +566 -0
  501. package/Tests/UI/Components/AttributesJSON/JSONHighlight.test.ts +131 -0
  502. package/Tests/UI/Components/BasicFormDropdownNormalization.test.tsx +276 -1
  503. package/Tests/UI/Components/Calendar/Calendar.test.tsx +1611 -0
  504. package/Tests/UI/Components/Calendar/CalendarDayLayout.test.ts +1486 -0
  505. package/Tests/UI/Components/Calendar/CalendarDayLayoutDst.test.ts +632 -0
  506. package/Tests/UI/Components/Calendar/CalendarDst.test.tsx +388 -0
  507. package/Tests/UI/Components/Charts/ChartGroupPlotFloor.test.tsx +170 -0
  508. package/Tests/UI/Components/Charts/HistogramSelection.test.ts +282 -0
  509. package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +6 -0
  510. package/Tests/UI/Components/CustomTimeRangeModalTimezoneTranslation.test.tsx +285 -0
  511. package/Tests/UI/Components/Dropdown.test.tsx +999 -2
  512. package/Tests/UI/Components/FieldLabelInfoCardTooltip.test.tsx +413 -0
  513. package/Tests/UI/Components/Forms/FormFieldCheckboxTranslation.test.tsx +216 -0
  514. package/Tests/UI/Components/Forms/FormFieldTimezoneDescriptionTranslation.test.tsx +461 -0
  515. package/Tests/UI/Components/Forms/IncidentEpisodePublicNoteNotifyPayload.test.tsx +641 -0
  516. package/Tests/UI/Components/Forms/IncidentPublicNoteNotifyPayload.test.tsx +346 -0
  517. package/Tests/UI/Components/Forms/ScheduledMaintenancePublicNoteNotifyPayload.test.tsx +493 -0
  518. package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +911 -2
  519. package/Tests/UI/Components/Graphs/DayUptimeGraphTimezone.NewYork.test.tsx +730 -0
  520. package/Tests/UI/Components/Graphs/DayUptimeGraphTimezone.Tokyo.test.tsx +506 -0
  521. package/Tests/UI/Components/HistogramClickToZoom.test.tsx +619 -0
  522. package/Tests/UI/Components/InfoTooltip.test.tsx +242 -0
  523. package/Tests/UI/Components/LogDetailsPanelAttributesJSON.test.tsx +248 -0
  524. package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +47 -1
  525. package/Tests/UI/Components/LogsViewerSmallScreens.test.tsx +620 -0
  526. package/Tests/UI/Components/ModelPageModelChange.test.tsx +242 -3
  527. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +207 -3
  528. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDeleteVerb.test.tsx +367 -0
  529. package/Tests/UI/Components/ModelTable/BaseModelTableCreateButtonTitle.test.tsx +275 -0
  530. package/Tests/UI/Components/ModelTable/BaseModelTableDeleteConfirmation.test.tsx +521 -0
  531. package/Tests/UI/Components/MonitorGraphs/Uptime.test.tsx +406 -2
  532. package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +169 -2
  533. package/Tests/UI/Components/TableHeaderTooltip.test.tsx +662 -0
  534. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +266 -0
  535. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerSmallScreens.test.tsx +439 -0
  536. package/Tests/UI/Components/TimezoneDropdownLegacyValues.test.tsx +704 -0
  537. package/Tests/UI/Components/UseHistogramZoom.test.tsx +89 -1
  538. package/Tests/UI/Components/UseLogsHistogram.test.tsx +175 -0
  539. package/Tests/UI/Monitor/MonitorSummarySnapshotRender.test.tsx +5 -5
  540. package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +166 -9
  541. package/Tests/UI/Rum/RecordingHealthTooltips.test.tsx +447 -0
  542. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +164 -0
  543. package/Tests/UI/Rum/ReplayFrameCapture.test.ts +6750 -0
  544. package/Tests/UI/Rum/ReplayRail.test.tsx +723 -12
  545. package/Tests/UI/Rum/ReplayRailDetail.test.tsx +86 -0
  546. package/Tests/UI/Rum/ReplayScreenshot.test.ts +2124 -0
  547. package/Tests/UI/Rum/ReplayScreenshotActions.test.tsx +3288 -0
  548. package/Tests/UI/Rum/ReplayStage.test.tsx +62 -0
  549. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +983 -2
  550. package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +149 -0
  551. package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +107 -6
  552. package/Tests/UI/Rum/SessionReplayUsersTableTooltips.test.tsx +330 -0
  553. package/Tests/UI/Rum/UserFlowTooltips.test.tsx +886 -0
  554. package/Tests/UI/Telemetry/TelemetryDetailPanel.test.tsx +28 -0
  555. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +10 -0
  556. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
  557. package/Tests/UI/Utils/PermissionGate.test.ts +76 -0
  558. package/Tests/UI/Utils/ProjectUsersModelAPI.test.ts +51 -0
  559. package/Tests/UI/Utils/Timezone.test.ts +747 -33
  560. package/Tests/UI/Workspace/SendTestNotificationButton.test.tsx +1854 -0
  561. package/Tests/UI/Workspace/WorkspaceCardsSendTestNotification.test.tsx +1864 -0
  562. package/Tests/Utils/AI/InvestigationReport.test.ts +435 -7
  563. package/Tests/Utils/AiRemediation/KubectlAllowlistValidatorParity.test.ts +1084 -0
  564. package/Tests/Utils/AiRemediation/KubectlOutputRedactor.test.ts +2531 -0
  565. package/Tests/Utils/AiRemediation/KubectlPolicy.test.ts +1895 -0
  566. package/Tests/Utils/AiRemediation/KubectlPolicyAllowlist.test.ts +428 -0
  567. package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +828 -0
  568. package/Tests/Utils/AiRemediation/KubectlPolicyCustomResourceScope.test.ts +573 -0
  569. package/Tests/Utils/AiRemediation/KubectlPolicyDenials.test.ts +1525 -0
  570. package/Tests/Utils/AiRemediation/KubectlPolicyExposeOverrides.test.ts +275 -0
  571. package/Tests/Utils/AiRemediation/KubectlPolicyNodePatch.test.ts +428 -0
  572. package/Tests/Utils/AiRemediation/KubectlPolicyObjectWords.test.ts +195 -0
  573. package/Tests/Utils/AiRemediation/KubectlPolicyPatchParents.test.ts +637 -0
  574. package/Tests/Utils/AiRemediation/KubectlPolicyPodSecurityBaseline.test.ts +322 -0
  575. package/Tests/Utils/AiRemediation/KubectlPolicySafeWriteScope.test.ts +1026 -0
  576. package/Tests/Utils/AiRemediation/KubectlWaitBudget.test.ts +267 -0
  577. package/Tests/Utils/AiRemediation/KubectlWriteScope.test.ts +390 -0
  578. package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +777 -0
  579. package/Tests/Utils/AiRemediation/KubectlWriteScopeClusterScoped.test.ts +613 -0
  580. package/Tests/Utils/AiRemediation/KubectlWriteScopeEntryPoint.test.ts +576 -0
  581. package/Tests/Utils/AiRemediation/KubectlWriteScopeKubectlSpellings.test.ts +752 -0
  582. package/Tests/Utils/AiRemediation/KubectlWriteScopeObjectWords.test.ts +358 -0
  583. package/Tests/Utils/AiRemediation/KubectlWriteScopeOverrides.test.ts +293 -0
  584. package/Tests/Utils/AiRemediation/KubectlWriteScopeParityCases.ts +598 -0
  585. package/Tests/Utils/AiRemediation/KubectlWriteScopePolicyParity.test.ts +403 -0
  586. package/Tests/Utils/Dashboard/DashboardClockComponent.test.ts +154 -5
  587. package/Tests/Utils/Incident/IncidentFromAlerts.test.ts +696 -0
  588. package/Tests/Utils/Monitor/IncomingEmailMonitorAddress.test.ts +478 -0
  589. package/Tests/Utils/Monitor/MonitorCheckScheduleUtil.test.ts +646 -0
  590. package/Tests/Utils/Monitor/MonitorOverviewCriteriaUtil.test.ts +292 -0
  591. package/Tests/Utils/Monitor/MonitorOverviewFamily.test.ts +274 -0
  592. package/Tests/Utils/Monitor/MonitorOverviewPresentationUtil.test.ts +3100 -0
  593. package/Tests/Utils/Monitor/MonitorOverviewProbeUtil.test.ts +1412 -0
  594. package/Tests/Utils/Monitor/MonitorOverviewTargetUtil.test.ts +374 -0
  595. package/Tests/Utils/Monitor/MonitorStatusHistoryUtil.test.ts +332 -0
  596. package/Tests/Utils/Monitor/MonitorUptimeSummaryUtil.test.ts +946 -0
  597. package/Tests/Utils/Rum/SessionIdentity.test.ts +94 -0
  598. package/Tests/Utils/Rum/SessionReplayWafCompatibility.test.ts +840 -0
  599. package/Tests/Utils/Rum/SessionReplayWireEncoding.test.ts +208 -0
  600. package/Tests/Utils/Rum/SessionTraceState.test.ts +239 -0
  601. package/Tests/Utils/Rum/UserFlow.test.ts +1010 -0
  602. package/Tests/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.test.ts +217 -0
  603. package/Tests/Utils/StatusPage/ResourceUptime.test.ts +1272 -1
  604. package/Tests/Utils/StatusPage/UptimeDailyAggregateTotals.test.ts +298 -0
  605. package/Tests/Utils/StatusPage/UptimeDailyAggregateUtil.test.ts +649 -1
  606. package/Tests/Utils/StatusPage/UptimeDailyAggregateWindow.test.ts +314 -0
  607. package/Tests/Utils/Telemetry/AttributesJSON.test.ts +454 -0
  608. package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +418 -2
  609. package/Tests/Utils/Uptime/DayUptimeGraphUtilMidnightDst.test.ts +160 -0
  610. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Auckland.test.ts +45 -0
  611. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Kolkata.test.ts +40 -0
  612. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.London.test.ts +147 -0
  613. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.NewYork.test.ts +48 -0
  614. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezone.Tokyo.test.ts +39 -0
  615. package/Tests/Utils/Uptime/DayUptimeGraphUtilTimezoneCases.ts +1015 -0
  616. package/Tests/Utils/Uptime/UptimeUtil.test.ts +75 -0
  617. package/Tests/Utils/Uptime/UptimeUtilChronologicalOrder.test.ts +1279 -0
  618. package/Types/AutoRemediation/AiRemediationCommandPlan.ts +203 -5
  619. package/Types/Date.ts +121 -7
  620. package/Types/Email/EmailMessage.ts +8 -0
  621. package/Types/Email/EmailTemplateType.ts +1 -0
  622. package/Types/Exception/ExceptionMessages.ts +1 -0
  623. package/Types/Incident/IncidentAlertLink.ts +38 -0
  624. package/Types/Kubernetes/KubernetesClusterAiAccess.ts +488 -0
  625. package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +54 -0
  626. package/Types/Kubernetes/KubernetesClusterAiAccessToolNames.ts +17 -0
  627. package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +9 -0
  628. package/Types/Monitor/DatabaseMonitor/SqlServerPlatform.ts +117 -0
  629. package/Types/Monitor/KubernetesAlertTemplates.ts +6 -5
  630. package/Types/Monitor/MonitorStepExceptionMonitor.ts +56 -0
  631. package/Types/Monitor/MonitorUptimeSummary.ts +113 -0
  632. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +11 -0
  633. package/Types/Permission.ts +48 -0
  634. package/Types/Rum/SessionReplay.ts +80 -8
  635. package/Types/Rum/SessionReplayApi.ts +44 -1
  636. package/Types/Rum/UserFlow.ts +187 -0
  637. package/Types/Rum/WebVitals.ts +52 -0
  638. package/Types/Runbook/RunbookStepType.ts +10 -0
  639. package/Types/Runbook/RunnerJobOrigin.ts +15 -0
  640. package/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.ts +6 -2
  641. package/Types/StatusPage/MergedDowntimeTotals.ts +17 -0
  642. package/Types/StatusPage/PublicNoteSubscriberNotificationDefault.ts +148 -0
  643. package/Types/StatusPage/UptimeDailyAggregate.ts +15 -0
  644. package/Types/Telemetry/TelemetryIngestSurface.ts +9 -0
  645. package/Types/Timezone.ts +5 -0
  646. package/Types/TimezoneAlias.ts +385 -0
  647. package/Types/Workflow/Templates.ts +3041 -2
  648. package/Types/Workflow/WorkflowVariableOAuth.ts +476 -0
  649. package/Types/Workspace/WorkspaceNoteReaction.ts +132 -0
  650. package/Typings/Index.d.ts +24 -0
  651. package/UI/Components/AttributesJSON/AttributesJSONPreferences.ts +175 -0
  652. package/UI/Components/AttributesJSON/AttributesJSONView.tsx +138 -0
  653. package/UI/Components/AttributesJSON/AttributesViewToggle.tsx +79 -0
  654. package/UI/Components/AttributesJSON/BracesGlyph.tsx +30 -0
  655. package/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.tsx +491 -0
  656. package/UI/Components/AttributesJSON/JSONHighlight.ts +77 -0
  657. package/UI/Components/Calendar/Calendar.css +83 -0
  658. package/UI/Components/Calendar/Calendar.tsx +136 -7
  659. package/UI/Components/Calendar/CalendarDayLayout.ts +236 -0
  660. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +23 -1
  661. package/UI/Components/Charts/Utils/HistogramSelection.ts +117 -0
  662. package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +269 -0
  663. package/UI/Components/Charts/Utils/useHistogramZoom.ts +26 -2
  664. package/UI/Components/Date/CustomTimeRangeModal.tsx +26 -3
  665. package/UI/Components/Detail/FieldLabel.tsx +8 -0
  666. package/UI/Components/Dropdown/Dropdown.tsx +58 -9
  667. package/UI/Components/Forms/Fields/FormField.tsx +49 -14
  668. package/UI/Components/Graphs/DayUptimeGraph.tsx +166 -25
  669. package/UI/Components/Graphs/UptimeBarTooltip.tsx +10 -2
  670. package/UI/Components/Graphs/UptimeDaySummary.tsx +8 -0
  671. package/UI/Components/InfoCard/InfoCard.tsx +47 -1
  672. package/UI/Components/LogsViewer/LogsViewer.tsx +52 -5
  673. package/UI/Components/LogsViewer/components/ColumnSelector.tsx +13 -2
  674. package/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.tsx +13 -1
  675. package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +91 -76
  676. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +15 -1
  677. package/UI/Components/LogsViewer/components/LogsHistogram.tsx +28 -106
  678. package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +54 -6
  679. package/UI/Components/LogsViewer/components/SavedViewsDropdown.tsx +8 -2
  680. package/UI/Components/LogsViewer/useLogsHistogram.ts +39 -6
  681. package/UI/Components/ModelTable/BaseModelTable.tsx +161 -31
  682. package/UI/Components/ModelTable/Column.ts +5 -0
  683. package/UI/Components/MonitorGraphs/Uptime.tsx +12 -0
  684. package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +10 -2
  685. package/UI/Components/Page/ModelPage.tsx +59 -3
  686. package/UI/Components/Table/TableHeader.tsx +47 -2
  687. package/UI/Components/Table/Types/Column.ts +7 -0
  688. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +69 -5
  689. package/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.tsx +12 -1
  690. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +15 -1
  691. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +36 -104
  692. package/UI/Components/TelemetryViewer/components/TelemetrySearchBar.tsx +9 -1
  693. package/UI/Components/Tooltip/InfoTooltip.tsx +78 -0
  694. package/UI/Utils/ModelAPI/ProjectUsersModelAPI.ts +19 -1
  695. package/UI/Utils/PermissionGate.ts +11 -2
  696. package/UI/Utils/Timezone.ts +69 -28
  697. package/Utils/AI/InvestigationReport.ts +195 -25
  698. package/Utils/AiRemediation/KubectlOutputRedactor.ts +1724 -0
  699. package/Utils/AiRemediation/KubectlPolicy.ts +4136 -0
  700. package/Utils/AiRemediation/KubectlWaitBudget.ts +156 -0
  701. package/Utils/AiRemediation/KubectlWriteScope.ts +1964 -0
  702. package/Utils/Dashboard/Components/DashboardClockComponent.ts +7 -6
  703. package/Utils/Incident/IncidentFromAlerts.ts +516 -0
  704. package/Utils/Monitor/IncomingEmailMonitorAddress.ts +292 -0
  705. package/Utils/Monitor/MonitorCheckScheduleUtil.ts +654 -0
  706. package/Utils/Monitor/MonitorOverviewCriteriaUtil.ts +188 -0
  707. package/Utils/Monitor/MonitorOverviewFamily.ts +263 -0
  708. package/Utils/Monitor/MonitorOverviewPresentationUtil.ts +1958 -0
  709. package/Utils/Monitor/MonitorOverviewProbeUtil.ts +979 -0
  710. package/Utils/Monitor/MonitorOverviewTargetUtil.ts +299 -0
  711. package/Utils/Monitor/MonitorStatusHistoryUtil.ts +201 -0
  712. package/Utils/Monitor/MonitorUptimeSummaryUtil.ts +638 -0
  713. package/Utils/Rum/SessionIdentity.ts +44 -0
  714. package/Utils/Rum/SessionReplayWireEncoding.ts +137 -0
  715. package/Utils/Rum/SessionTraceState.ts +212 -0
  716. package/Utils/Rum/UserFlow.ts +1527 -0
  717. package/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.ts +107 -0
  718. package/Utils/StatusPage/ResourceUptime.ts +99 -0
  719. package/Utils/StatusPage/UptimeDailyAggregateUtil.ts +197 -0
  720. package/Utils/Telemetry/AttributesJSON.ts +367 -0
  721. package/Utils/Uptime/DayUptimeGraphUtil.ts +165 -0
  722. package/Utils/Uptime/UptimeUtil.ts +122 -38
  723. package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +8 -1
  724. package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -1
  725. package/build/dist/Models/DatabaseModels/AlertFeed.js +2 -0
  726. package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
  727. package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js +62 -0
  728. package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js.map +1 -1
  729. package/build/dist/Models/DatabaseModels/IncidentAlert.js +553 -0
  730. package/build/dist/Models/DatabaseModels/IncidentAlert.js.map +1 -0
  731. package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js +8 -1
  732. package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js.map +1 -1
  733. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +10 -3
  734. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
  735. package/build/dist/Models/DatabaseModels/IncidentFeed.js +2 -0
  736. package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
  737. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +10 -3
  738. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  739. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  740. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  741. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +434 -0
  742. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  743. package/build/dist/Models/DatabaseModels/Monitor.js +49 -0
  744. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  745. package/build/dist/Models/DatabaseModels/Project.js +62 -0
  746. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  747. package/build/dist/Models/DatabaseModels/RumApplication.js +53 -1
  748. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  749. package/build/dist/Models/DatabaseModels/Runner.js +4 -4
  750. package/build/dist/Models/DatabaseModels/Runner.js.map +1 -1
  751. package/build/dist/Models/DatabaseModels/RunnerJob.js +66 -0
  752. package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
  753. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +11 -3
  754. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  755. package/build/dist/Models/DatabaseModels/WorkflowVariable.js +487 -3
  756. package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
  757. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js +64 -16
  758. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  759. package/build/dist/Server/API/AIInvestigationAPI.js +205 -0
  760. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  761. package/build/dist/Server/API/AutoRemediationAPI.js +115 -2
  762. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  763. package/build/dist/Server/API/CommonAPI.js +49 -0
  764. package/build/dist/Server/API/CommonAPI.js.map +1 -1
  765. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +564 -0
  766. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -0
  767. package/build/dist/Server/API/MicrosoftTeamsAPI.js +465 -176
  768. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  769. package/build/dist/Server/API/MonitorAPI.js +107 -1
  770. package/build/dist/Server/API/MonitorAPI.js.map +1 -1
  771. package/build/dist/Server/API/OnCallScheduleTimelineAPI.js +5 -16
  772. package/build/dist/Server/API/OnCallScheduleTimelineAPI.js.map +1 -1
  773. package/build/dist/Server/API/SlackAPI.js +322 -78
  774. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  775. package/build/dist/Server/API/StatusPageAPI.js +123 -17
  776. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  777. package/build/dist/Server/API/TelemetryAPI.js +144 -5
  778. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  779. package/build/dist/Server/API/UserTwoFactorBackupCodeAPI.js +1 -0
  780. package/build/dist/Server/API/UserTwoFactorBackupCodeAPI.js.map +1 -1
  781. package/build/dist/Server/API/WorkflowVariableAPI.js +109 -0
  782. package/build/dist/Server/API/WorkflowVariableAPI.js.map +1 -0
  783. package/build/dist/Server/Infrastructure/GlobalCache.js +29 -0
  784. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  785. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.js +38 -0
  786. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794300000000-AddOAuth2WorkflowVariables.js.map +1 -0
  787. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.js +54 -0
  788. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794400000000-AddKubernetesClusterAiAccess.js.map +1 -0
  789. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.js +14 -0
  790. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794500000000-AddIncomingEmailCustomAddressToMonitor.js.map +1 -0
  791. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.js +12 -0
  792. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794600000000-AddAuthTokenExpiresAtToWorkspaceProjectAuthToken.js.map +1 -0
  793. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.js +32 -0
  794. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794700000000-RemoveAppAccessTokenFromWorkspaceProjectAuthTokenMiscData.js.map +1 -0
  795. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js +20 -0
  796. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js.map +1 -0
  797. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js +42 -0
  798. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js.map +1 -0
  799. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +14 -0
  800. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  801. package/build/dist/Server/Middleware/MasterAdminAuthorization.js +21 -0
  802. package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
  803. package/build/dist/Server/Middleware/TelemetryIngest.js +32 -2
  804. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  805. package/build/dist/Server/Middleware/UserAuthorization.js +39 -6
  806. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  807. package/build/dist/Server/Services/AIAgentService.js +1 -0
  808. package/build/dist/Server/Services/AIAgentService.js.map +1 -1
  809. package/build/dist/Server/Services/AccessTokenService.js +87 -42
  810. package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
  811. package/build/dist/Server/Services/AlertEpisodeMemberService.js +4 -0
  812. package/build/dist/Server/Services/AlertEpisodeMemberService.js.map +1 -1
  813. package/build/dist/Server/Services/AlertEpisodeService.js +12 -1
  814. package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
  815. package/build/dist/Server/Services/AlertService.js +110 -23
  816. package/build/dist/Server/Services/AlertService.js.map +1 -1
  817. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +716 -30
  818. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
  819. package/build/dist/Server/Services/AutoRemediationRuleService.js +100 -0
  820. package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
  821. package/build/dist/Server/Services/BillingService.js +1 -0
  822. package/build/dist/Server/Services/BillingService.js.map +1 -1
  823. package/build/dist/Server/Services/InboundEmail/Providers/SendGridInboundProvider.js +11 -16
  824. package/build/dist/Server/Services/InboundEmail/Providers/SendGridInboundProvider.js.map +1 -1
  825. package/build/dist/Server/Services/IncidentAlertService.js +1370 -0
  826. package/build/dist/Server/Services/IncidentAlertService.js.map +1 -0
  827. package/build/dist/Server/Services/IncidentEpisodeMemberService.js +4 -0
  828. package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
  829. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +48 -0
  830. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
  831. package/build/dist/Server/Services/IncidentEpisodeRoleMemberService.js +21 -0
  832. package/build/dist/Server/Services/IncidentEpisodeRoleMemberService.js.map +1 -1
  833. package/build/dist/Server/Services/IncidentEpisodeService.js +12 -1
  834. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  835. package/build/dist/Server/Services/IncidentGroupingEngineService.js +8 -0
  836. package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
  837. package/build/dist/Server/Services/IncidentMemberService.js +14 -0
  838. package/build/dist/Server/Services/IncidentMemberService.js.map +1 -1
  839. package/build/dist/Server/Services/IncidentPublicNoteService.js +48 -0
  840. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  841. package/build/dist/Server/Services/IncidentService.js +263 -33
  842. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  843. package/build/dist/Server/Services/IncidentStateTimelineService.js +33 -0
  844. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  845. package/build/dist/Server/Services/IncidentTemplateService.js +68 -4
  846. package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
  847. package/build/dist/Server/Services/Index.js +2 -0
  848. package/build/dist/Server/Services/Index.js.map +1 -1
  849. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +1470 -0
  850. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -0
  851. package/build/dist/Server/Services/KubernetesClusterService.js +1097 -0
  852. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  853. package/build/dist/Server/Services/LogAggregationService.js +14 -6
  854. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  855. package/build/dist/Server/Services/MonitorService.js +487 -48
  856. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  857. package/build/dist/Server/Services/MonitorStatusTimelineService.js +540 -3
  858. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  859. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +2 -0
  860. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  861. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js +2 -0
  862. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js.map +1 -1
  863. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +2 -0
  864. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
  865. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +3 -0
  866. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
  867. package/build/dist/Server/Services/OnCallNotificationAlertingService.js +29 -7
  868. package/build/dist/Server/Services/OnCallNotificationAlertingService.js.map +1 -1
  869. package/build/dist/Server/Services/OnCallSetupReminderService.js +1 -0
  870. package/build/dist/Server/Services/OnCallSetupReminderService.js.map +1 -1
  871. package/build/dist/Server/Services/ProbeService.js +7 -1
  872. package/build/dist/Server/Services/ProbeService.js.map +1 -1
  873. package/build/dist/Server/Services/ProjectService.js +11 -1
  874. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  875. package/build/dist/Server/Services/RunbookCredentialService.js +24 -0
  876. package/build/dist/Server/Services/RunbookCredentialService.js.map +1 -1
  877. package/build/dist/Server/Services/RunbookSecretService.js +44 -0
  878. package/build/dist/Server/Services/RunbookSecretService.js.map +1 -1
  879. package/build/dist/Server/Services/RunnerJobService.js +641 -21
  880. package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
  881. package/build/dist/Server/Services/RunnerService.js +344 -5
  882. package/build/dist/Server/Services/RunnerService.js.map +1 -1
  883. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +48 -0
  884. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  885. package/build/dist/Server/Services/ScheduledMaintenanceService.js +102 -20
  886. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  887. package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js +67 -4
  888. package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js.map +1 -1
  889. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +12 -1
  890. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
  891. package/build/dist/Server/Services/StatusPagePrivateUserService.js +1 -0
  892. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  893. package/build/dist/Server/Services/StatusPageService.js +230 -32
  894. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  895. package/build/dist/Server/Services/StatusPageSubscriberService.js +4 -0
  896. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  897. package/build/dist/Server/Services/TeamMemberService.js +270 -11
  898. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  899. package/build/dist/Server/Services/TraceAggregationService.js +10 -6
  900. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  901. package/build/dist/Server/Services/UserEmailService.js +1 -0
  902. package/build/dist/Server/Services/UserEmailService.js.map +1 -1
  903. package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1 -0
  904. package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -1
  905. package/build/dist/Server/Services/UserNotificationRuleAdminService.js +1 -0
  906. package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -1
  907. package/build/dist/Server/Services/UserNotificationRuleService.js +4 -0
  908. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  909. package/build/dist/Server/Services/UserService.js +107 -1
  910. package/build/dist/Server/Services/UserService.js.map +1 -1
  911. package/build/dist/Server/Services/WorkflowVariableService.js +396 -7
  912. package/build/dist/Server/Services/WorkflowVariableService.js.map +1 -1
  913. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +463 -7
  914. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  915. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +144 -2
  916. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
  917. package/build/dist/Server/Types/Database/QueryHelper.js +20 -0
  918. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  919. package/build/dist/Server/Types/Markdown.js +394 -27
  920. package/build/dist/Server/Types/Markdown.js.map +1 -1
  921. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +123 -0
  922. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -0
  923. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +344 -0
  924. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -0
  925. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +587 -0
  926. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -0
  927. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentAuth.js +18 -2
  928. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentAuth.js.map +1 -1
  929. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +1380 -239
  930. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
  931. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +1099 -68
  932. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  933. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +88 -6
  934. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  935. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +45 -11
  936. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  937. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +41 -11
  938. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  939. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js +11 -4
  940. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -1
  941. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js +4 -2
  942. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js.map +1 -1
  943. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +997 -141
  944. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
  945. package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js +299 -4
  946. package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js.map +1 -1
  947. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js +120 -0
  948. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js.map +1 -0
  949. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +160 -1
  950. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
  951. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +1 -0
  952. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
  953. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +59 -12
  954. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  955. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +5 -1
  956. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  957. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +84 -22
  958. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  959. package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js +70 -5
  960. package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js.map +1 -1
  961. package/build/dist/Server/Utils/Monitor/ProbeMonitorsNotification.js +249 -0
  962. package/build/dist/Server/Utils/Monitor/ProbeMonitorsNotification.js.map +1 -0
  963. package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js +1 -0
  964. package/build/dist/Server/Utils/OnCall/OnCallShiftReminderRunner.js.map +1 -1
  965. package/build/dist/Server/Utils/PushNotificationUtil.js +27 -0
  966. package/build/dist/Server/Utils/PushNotificationUtil.js.map +1 -1
  967. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js +26 -3
  968. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js.map +1 -1
  969. package/build/dist/Server/Utils/Runbook/RunbookExecutePermission.js +38 -3
  970. package/build/dist/Server/Utils/Runbook/RunbookExecutePermission.js.map +1 -1
  971. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +8 -0
  972. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
  973. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +143 -23
  974. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  975. package/build/dist/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.js +406 -0
  976. package/build/dist/Server/Utils/SessionReplay/SessionReplayUserFlowReadService.js.map +1 -0
  977. package/build/dist/Server/Utils/StartServer.js +4 -3
  978. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  979. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +382 -0
  980. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -0
  981. package/build/dist/Server/Utils/TwoFactorBackupCodeNotification.js +1 -0
  982. package/build/dist/Server/Utils/TwoFactorBackupCodeNotification.js.map +1 -1
  983. package/build/dist/Server/Utils/UserPermission/UserPermission.js +10 -0
  984. package/build/dist/Server/Utils/UserPermission/UserPermission.js.map +1 -1
  985. package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js +447 -0
  986. package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js.map +1 -0
  987. package/build/dist/Server/Utils/Workflow/WorkflowVariableOAuthToken.js +202 -0
  988. package/build/dist/Server/Utils/Workflow/WorkflowVariableOAuthToken.js.map +1 -0
  989. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +39 -1
  990. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
  991. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +44 -4
  992. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
  993. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +150 -191
  994. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
  995. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +44 -4
  996. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
  997. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.js +39 -17
  998. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Monitor.js.map +1 -1
  999. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js +151 -145
  1000. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js.map +1 -1
  1001. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +221 -127
  1002. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  1003. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.js +91 -0
  1004. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsServiceUrl.js.map +1 -0
  1005. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.js +673 -0
  1006. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/ReactionNoteSync.js.map +1 -0
  1007. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js +3 -9
  1008. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js.map +1 -1
  1009. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +65 -166
  1010. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -1
  1011. package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js +63 -157
  1012. package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js.map +1 -1
  1013. package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js +23 -3
  1014. package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js.map +1 -1
  1015. package/build/dist/Server/Utils/Workspace/Slack/Actions/Authorization.js +92 -0
  1016. package/build/dist/Server/Utils/Workspace/Slack/Actions/Authorization.js.map +1 -0
  1017. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +81 -210
  1018. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
  1019. package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js +68 -138
  1020. package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js.map +1 -1
  1021. package/build/dist/Server/Utils/Workspace/Slack/Actions/ReactionNote.js +240 -0
  1022. package/build/dist/Server/Utils/Workspace/Slack/Actions/ReactionNote.js.map +1 -0
  1023. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js +85 -212
  1024. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js.map +1 -1
  1025. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +60 -17
  1026. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  1027. package/build/dist/Server/Utils/Workspace/Slack/app-manifest.json +2 -0
  1028. package/build/dist/Server/Utils/Workspace/Workspace.js +134 -41
  1029. package/build/dist/Server/Utils/Workspace/Workspace.js.map +1 -1
  1030. package/build/dist/Server/Utils/Workspace/WorkspaceActionAuthorization.js +197 -0
  1031. package/build/dist/Server/Utils/Workspace/WorkspaceActionAuthorization.js.map +1 -0
  1032. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js +32 -0
  1033. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
  1034. package/build/dist/Server/Utils/Workspace/WorkspaceOAuthState.js +199 -0
  1035. package/build/dist/Server/Utils/Workspace/WorkspaceOAuthState.js.map +1 -0
  1036. package/build/dist/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.js +91 -0
  1037. package/build/dist/Server/Utils/Workspace/WorkspaceProjectReferenceValidator.js.map +1 -0
  1038. package/build/dist/Server/Utils/Workspace/WorkspaceReactionNote.js +450 -0
  1039. package/build/dist/Server/Utils/Workspace/WorkspaceReactionNote.js.map +1 -0
  1040. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +103 -5
  1041. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
  1042. package/build/dist/Types/Date.js +97 -7
  1043. package/build/dist/Types/Date.js.map +1 -1
  1044. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  1045. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  1046. package/build/dist/Types/Exception/ExceptionMessages.js +1 -0
  1047. package/build/dist/Types/Exception/ExceptionMessages.js.map +1 -1
  1048. package/build/dist/Types/Incident/IncidentAlertLink.js +34 -0
  1049. package/build/dist/Types/Incident/IncidentAlertLink.js.map +1 -0
  1050. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +245 -0
  1051. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -0
  1052. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +49 -0
  1053. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -0
  1054. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessToolNames.js +16 -0
  1055. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessToolNames.js.map +1 -0
  1056. package/build/dist/Types/Monitor/DatabaseMonitor/SqlServerPlatform.js +104 -0
  1057. package/build/dist/Types/Monitor/DatabaseMonitor/SqlServerPlatform.js.map +1 -0
  1058. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +6 -5
  1059. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  1060. package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js +32 -0
  1061. package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js.map +1 -1
  1062. package/build/dist/Types/Monitor/MonitorUptimeSummary.js +52 -0
  1063. package/build/dist/Types/Monitor/MonitorUptimeSummary.js.map +1 -0
  1064. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +9 -1
  1065. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  1066. package/build/dist/Types/Permission.js +42 -0
  1067. package/build/dist/Types/Permission.js.map +1 -1
  1068. package/build/dist/Types/Rum/SessionReplay.js +52 -2
  1069. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  1070. package/build/dist/Types/Rum/SessionReplayApi.js +11 -0
  1071. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
  1072. package/build/dist/Types/Rum/UserFlow.js +115 -0
  1073. package/build/dist/Types/Rum/UserFlow.js.map +1 -0
  1074. package/build/dist/Types/Rum/WebVitals.js +25 -0
  1075. package/build/dist/Types/Rum/WebVitals.js.map +1 -1
  1076. package/build/dist/Types/Runbook/RunbookStepType.js +10 -0
  1077. package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
  1078. package/build/dist/Types/Runbook/RunnerJobOrigin.js +14 -0
  1079. package/build/dist/Types/Runbook/RunnerJobOrigin.js.map +1 -1
  1080. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js +2 -2
  1081. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js.map +1 -1
  1082. package/build/dist/Types/StatusPage/MergedDowntimeTotals.js +2 -0
  1083. package/build/dist/Types/StatusPage/MergedDowntimeTotals.js.map +1 -0
  1084. package/build/dist/Types/StatusPage/PublicNoteSubscriberNotificationDefault.js +65 -0
  1085. package/build/dist/Types/StatusPage/PublicNoteSubscriberNotificationDefault.js.map +1 -0
  1086. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +8 -0
  1087. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
  1088. package/build/dist/Types/Timezone.js +5 -0
  1089. package/build/dist/Types/Timezone.js.map +1 -1
  1090. package/build/dist/Types/TimezoneAlias.js +340 -0
  1091. package/build/dist/Types/TimezoneAlias.js.map +1 -0
  1092. package/build/dist/Types/Workflow/Templates.js +2694 -2
  1093. package/build/dist/Types/Workflow/Templates.js.map +1 -1
  1094. package/build/dist/Types/Workflow/WorkflowVariableOAuth.js +314 -0
  1095. package/build/dist/Types/Workflow/WorkflowVariableOAuth.js.map +1 -0
  1096. package/build/dist/Types/Workspace/WorkspaceNoteReaction.js +98 -0
  1097. package/build/dist/Types/Workspace/WorkspaceNoteReaction.js.map +1 -0
  1098. package/build/dist/UI/Components/AttributesJSON/AttributesJSONPreferences.js +95 -0
  1099. package/build/dist/UI/Components/AttributesJSON/AttributesJSONPreferences.js.map +1 -0
  1100. package/build/dist/UI/Components/AttributesJSON/AttributesJSONView.js +44 -0
  1101. package/build/dist/UI/Components/AttributesJSON/AttributesJSONView.js.map +1 -0
  1102. package/build/dist/UI/Components/AttributesJSON/AttributesViewToggle.js +27 -0
  1103. package/build/dist/UI/Components/AttributesJSON/AttributesViewToggle.js.map +1 -0
  1104. package/build/dist/UI/Components/AttributesJSON/BracesGlyph.js +9 -0
  1105. package/build/dist/UI/Components/AttributesJSON/BracesGlyph.js.map +1 -0
  1106. package/build/dist/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.js +260 -0
  1107. package/build/dist/UI/Components/AttributesJSON/CopyAttributesAsJSONButton.js.map +1 -0
  1108. package/build/dist/UI/Components/AttributesJSON/JSONHighlight.js +56 -0
  1109. package/build/dist/UI/Components/AttributesJSON/JSONHighlight.js.map +1 -0
  1110. package/build/dist/UI/Components/Calendar/Calendar.js +94 -7
  1111. package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
  1112. package/build/dist/UI/Components/Calendar/CalendarDayLayout.js +136 -0
  1113. package/build/dist/UI/Components/Calendar/CalendarDayLayout.js.map +1 -0
  1114. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +1 -1
  1115. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  1116. package/build/dist/UI/Components/Charts/Utils/HistogramSelection.js +72 -0
  1117. package/build/dist/UI/Components/Charts/Utils/HistogramSelection.js.map +1 -0
  1118. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +178 -0
  1119. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -0
  1120. package/build/dist/UI/Components/Charts/Utils/useHistogramZoom.js +13 -1
  1121. package/build/dist/UI/Components/Charts/Utils/useHistogramZoom.js.map +1 -1
  1122. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +20 -4
  1123. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -1
  1124. package/build/dist/UI/Components/Detail/FieldLabel.js +2 -0
  1125. package/build/dist/UI/Components/Detail/FieldLabel.js.map +1 -1
  1126. package/build/dist/UI/Components/Dropdown/Dropdown.js +33 -9
  1127. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  1128. package/build/dist/UI/Components/Forms/Fields/FormField.js +36 -13
  1129. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  1130. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +117 -11
  1131. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
  1132. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -1
  1133. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
  1134. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -1
  1135. package/build/dist/UI/Components/InfoCard/InfoCard.js +22 -1
  1136. package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
  1137. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +36 -8
  1138. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  1139. package/build/dist/UI/Components/LogsViewer/components/ColumnSelector.js +10 -2
  1140. package/build/dist/UI/Components/LogsViewer/components/ColumnSelector.js.map +1 -1
  1141. package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js +9 -1
  1142. package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js.map +1 -1
  1143. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +16 -15
  1144. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
  1145. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +1 -1
  1146. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  1147. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +14 -74
  1148. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
  1149. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +22 -5
  1150. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
  1151. package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js +9 -2
  1152. package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js.map +1 -1
  1153. package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js +16 -5
  1154. package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js.map +1 -1
  1155. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +89 -22
  1156. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  1157. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +7 -1
  1158. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  1159. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +5 -1
  1160. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
  1161. package/build/dist/UI/Components/Page/ModelPage.js +37 -3
  1162. package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
  1163. package/build/dist/UI/Components/Table/TableHeader.js +18 -2
  1164. package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
  1165. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +27 -6
  1166. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  1167. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js +7 -1
  1168. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js.map +1 -1
  1169. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +1 -1
  1170. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  1171. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +17 -77
  1172. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  1173. package/build/dist/UI/Components/TelemetryViewer/components/TelemetrySearchBar.js +10 -1
  1174. package/build/dist/UI/Components/TelemetryViewer/components/TelemetrySearchBar.js.map +1 -1
  1175. package/build/dist/UI/Components/Tooltip/InfoTooltip.js +28 -0
  1176. package/build/dist/UI/Components/Tooltip/InfoTooltip.js.map +1 -0
  1177. package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js +15 -1
  1178. package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js.map +1 -1
  1179. package/build/dist/UI/Utils/PermissionGate.js +4 -2
  1180. package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
  1181. package/build/dist/UI/Utils/Timezone.js +52 -17
  1182. package/build/dist/UI/Utils/Timezone.js.map +1 -1
  1183. package/build/dist/Utils/AI/InvestigationReport.js +116 -21
  1184. package/build/dist/Utils/AI/InvestigationReport.js.map +1 -1
  1185. package/build/dist/Utils/AiRemediation/KubectlOutputRedactor.js +1209 -0
  1186. package/build/dist/Utils/AiRemediation/KubectlOutputRedactor.js.map +1 -0
  1187. package/build/dist/Utils/AiRemediation/KubectlPolicy.js +2973 -0
  1188. package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -0
  1189. package/build/dist/Utils/AiRemediation/KubectlWaitBudget.js +99 -0
  1190. package/build/dist/Utils/AiRemediation/KubectlWaitBudget.js.map +1 -0
  1191. package/build/dist/Utils/AiRemediation/KubectlWriteScope.js +1429 -0
  1192. package/build/dist/Utils/AiRemediation/KubectlWriteScope.js.map +1 -0
  1193. package/build/dist/Utils/Dashboard/Components/DashboardClockComponent.js +7 -6
  1194. package/build/dist/Utils/Dashboard/Components/DashboardClockComponent.js.map +1 -1
  1195. package/build/dist/Utils/Incident/IncidentFromAlerts.js +306 -0
  1196. package/build/dist/Utils/Incident/IncidentFromAlerts.js.map +1 -0
  1197. package/build/dist/Utils/Monitor/IncomingEmailMonitorAddress.js +214 -0
  1198. package/build/dist/Utils/Monitor/IncomingEmailMonitorAddress.js.map +1 -0
  1199. package/build/dist/Utils/Monitor/MonitorCheckScheduleUtil.js +471 -0
  1200. package/build/dist/Utils/Monitor/MonitorCheckScheduleUtil.js.map +1 -0
  1201. package/build/dist/Utils/Monitor/MonitorOverviewCriteriaUtil.js +107 -0
  1202. package/build/dist/Utils/Monitor/MonitorOverviewCriteriaUtil.js.map +1 -0
  1203. package/build/dist/Utils/Monitor/MonitorOverviewFamily.js +191 -0
  1204. package/build/dist/Utils/Monitor/MonitorOverviewFamily.js.map +1 -0
  1205. package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js +1259 -0
  1206. package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js.map +1 -0
  1207. package/build/dist/Utils/Monitor/MonitorOverviewProbeUtil.js +593 -0
  1208. package/build/dist/Utils/Monitor/MonitorOverviewProbeUtil.js.map +1 -0
  1209. package/build/dist/Utils/Monitor/MonitorOverviewTargetUtil.js +195 -0
  1210. package/build/dist/Utils/Monitor/MonitorOverviewTargetUtil.js.map +1 -0
  1211. package/build/dist/Utils/Monitor/MonitorStatusHistoryUtil.js +127 -0
  1212. package/build/dist/Utils/Monitor/MonitorStatusHistoryUtil.js.map +1 -0
  1213. package/build/dist/Utils/Monitor/MonitorUptimeSummaryUtil.js +464 -0
  1214. package/build/dist/Utils/Monitor/MonitorUptimeSummaryUtil.js.map +1 -0
  1215. package/build/dist/Utils/Rum/SessionIdentity.js +31 -1
  1216. package/build/dist/Utils/Rum/SessionIdentity.js.map +1 -1
  1217. package/build/dist/Utils/Rum/SessionReplayWireEncoding.js +128 -0
  1218. package/build/dist/Utils/Rum/SessionReplayWireEncoding.js.map +1 -0
  1219. package/build/dist/Utils/Rum/SessionTraceState.js +154 -0
  1220. package/build/dist/Utils/Rum/SessionTraceState.js.map +1 -0
  1221. package/build/dist/Utils/Rum/UserFlow.js +941 -0
  1222. package/build/dist/Utils/Rum/UserFlow.js.map +1 -0
  1223. package/build/dist/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.js +82 -0
  1224. package/build/dist/Utils/StatusPage/MonitorGroupMergedDowntimeUtil.js.map +1 -0
  1225. package/build/dist/Utils/StatusPage/ResourceUptime.js +46 -0
  1226. package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
  1227. package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js +148 -0
  1228. package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js.map +1 -1
  1229. package/build/dist/Utils/Telemetry/AttributesJSON.js +245 -0
  1230. package/build/dist/Utils/Telemetry/AttributesJSON.js.map +1 -0
  1231. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +103 -0
  1232. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -1
  1233. package/build/dist/Utils/Uptime/UptimeUtil.js +91 -27
  1234. package/build/dist/Utils/Uptime/UptimeUtil.js.map +1 -1
  1235. package/jest.config.json +2 -1
  1236. package/package.json +2 -1
  1237. package/tsconfig.tests.json +36 -0
  1238. package/Tests/UI/Components/EmptyState/EmptyStateGuideLinks.test.tsx +0 -337
  1239. package/UI/Components/EmptyState/EmptyStateGuideLinks.tsx +0 -124
  1240. package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js +0 -47
  1241. package/build/dist/UI/Components/EmptyState/EmptyStateGuideLinks.js.map +0 -1
@@ -0,0 +1,1389 @@
1
+ /** @timezone Asia/Kolkata */
2
+
3
+ import "@testing-library/jest-dom";
4
+ import {
5
+ afterEach,
6
+ beforeEach,
7
+ describe,
8
+ expect,
9
+ jest,
10
+ test,
11
+ } from "@jest/globals";
12
+ import {
13
+ RenderResult,
14
+ act,
15
+ cleanup,
16
+ fireEvent,
17
+ render,
18
+ screen,
19
+ waitFor,
20
+ } from "@testing-library/react";
21
+ import React from "react";
22
+ import getJestMockFunction, { MockFunction } from "../../MockType";
23
+
24
+ /*
25
+ * What the schedule preview hands its calendar grid, as seen by someone whose
26
+ * browser is in India looking at a schedule that runs in Singapore - the setup
27
+ * the on-call calendar display bugs were reported from.
28
+ *
29
+ * The grid is react-big-calendar, which has no timezone concept: it draws
30
+ * every Date at its BROWSER-LOCAL wall clock. So the preview shifts each
31
+ * instant into the schedule's zone before handing it over ("display-local"
32
+ * Dates). Everything the grid is given has to be shifted the same way, and has
33
+ * to describe the visible week honestly:
34
+ *
35
+ * - the red current-time line and the highlighted "today" column come from
36
+ * the grid's own idea of now, which used to be the browser clock, so the
37
+ * line sat two and a half hours early on a grid showing Singapore time;
38
+ * - shifts were computed for the visible week only, so the week's first
39
+ * block "started" at 12:00 AM and its last "ended" at 11:59 PM - hand-offs
40
+ * that never happen;
41
+ * - before any navigation, that week was the BROWSER's week, not the one
42
+ * the grid opens on, and after "View as" changed it was still converted
43
+ * with the zone that was current at the last navigation;
44
+ * - the hatched "uncovered" bands must cover every uncovered stretch of the
45
+ * visible range, including the one after its last shift (a whole Saturday
46
+ * in Day view after a weekday-only rotation), stay inside it, and not
47
+ * include hairline slivers.
48
+ *
49
+ * The calendar is replaced by a stub that records the props of its latest
50
+ * render, so these tests assert on exactly what react-big-calendar would be
51
+ * given. The CSS/layout half of the fix (how the grid draws those blocks) is
52
+ * covered by the Calendar component's own tests.
53
+ */
54
+
55
+ const getListMock: MockFunction = getJestMockFunction();
56
+
57
+ interface CapturedCalendarProps {
58
+ events: Array<CalendarEvent>;
59
+ backgroundEvents?: Array<CalendarEvent> | undefined;
60
+ defaultDate?: Date | undefined;
61
+ getNow?: (() => Date) | undefined;
62
+ onRangeChange: (startAndEndTime: StartAndEndTime) => void;
63
+ }
64
+
65
+ // The props of the calendar's most recent render. Reset before every test.
66
+ let latestCalendarProps: CapturedCalendarProps | null = null;
67
+
68
+ /*
69
+ * The arrow wrappers matter: jest.mock is hoisted above the compiled requires,
70
+ * so the bindings above are still in their temporal dead zone when the factory
71
+ * body runs. Dereferencing lazily, at call time, is what works.
72
+ */
73
+ jest.mock("../../../UI/Utils/ModelAPI/ModelAPI", () => {
74
+ return {
75
+ __esModule: true,
76
+ default: {
77
+ getList: (...args: Array<any>) => {
78
+ return getListMock(...args);
79
+ },
80
+ },
81
+ };
82
+ });
83
+
84
+ jest.mock("../../../UI/Utils/Project", () => {
85
+ return {
86
+ __esModule: true,
87
+ default: {
88
+ getCurrentProjectId: () => {
89
+ return {
90
+ toString: (): string => {
91
+ return PROJECT_ID;
92
+ },
93
+ };
94
+ },
95
+ },
96
+ };
97
+ });
98
+
99
+ jest.mock("../../../UI/Components/Calendar/Calendar", () => {
100
+ return {
101
+ __esModule: true,
102
+ default: (props: any) => {
103
+ latestCalendarProps = props;
104
+ return (
105
+ <ul data-testid="calendar-events">
106
+ {(props.events || []).map((event: any, index: number) => {
107
+ return (
108
+ <li key={index} data-testid="calendar-event">
109
+ {event.title}
110
+ </li>
111
+ );
112
+ })}
113
+ </ul>
114
+ );
115
+ },
116
+ DefaultCalendarView: {
117
+ Month: "month",
118
+ Week: "week",
119
+ Day: "day",
120
+ Agenda: "agenda",
121
+ },
122
+ };
123
+ });
124
+
125
+ /*
126
+ * The real "View as" picker opens a modal with a searchable dropdown; these
127
+ * tests only care about the zone it hands back, so they click straight to it.
128
+ */
129
+ jest.mock(
130
+ "../../../../App/FeatureSet/Dashboard/src/Components/OnCallPolicy/OnCallScheduleLayer/TimezoneSelectButton",
131
+ () => {
132
+ return {
133
+ __esModule: true,
134
+ default: (props: {
135
+ value?: string;
136
+ onChange: (value: string | undefined) => void;
137
+ }) => {
138
+ return (
139
+ <button
140
+ type="button"
141
+ data-testid="view-as-new-york"
142
+ data-value={props.value}
143
+ onClick={() => {
144
+ props.onChange("America/New_York");
145
+ }}
146
+ >
147
+ {props.value}
148
+ </button>
149
+ );
150
+ },
151
+ };
152
+ },
153
+ );
154
+
155
+ import LayersPreview from "../../../../App/FeatureSet/Dashboard/src/Components/OnCallPolicy/OnCallScheduleLayer/LayersPreview";
156
+ import { OVERRIDE_EVENT_CLASS_NAME } from "../../../../App/FeatureSet/Dashboard/src/Components/OnCallPolicy/OnCallScheduleLayer/OverridePresentation";
157
+ import OnCallDutyPolicyEscalationRuleSchedule from "../../../Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule";
158
+ import OnCallDutyPolicyScheduleLayer from "../../../Models/DatabaseModels/OnCallDutyPolicyScheduleLayer";
159
+ import OnCallDutyPolicyScheduleLayerUser from "../../../Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser";
160
+ import OnCallDutyPolicyUserOverride from "../../../Models/DatabaseModels/OnCallDutyPolicyUserOverride";
161
+ import User from "../../../Models/DatabaseModels/User";
162
+ import CalendarEvent from "../../../Types/Calendar/CalendarEvent";
163
+ import OneUptimeDate, { Moment } from "../../../Types/Date";
164
+ import DayOfWeek from "../../../Types/Day/DayOfWeek";
165
+ import Dictionary from "../../../Types/Dictionary";
166
+ import EventInterval from "../../../Types/Events/EventInterval";
167
+ import Recurring from "../../../Types/Events/Recurring";
168
+ import ObjectID from "../../../Types/ObjectID";
169
+ import RestrictionTimes, {
170
+ RestrictionType,
171
+ } from "../../../Types/OnCallDutyPolicy/RestrictionTimes";
172
+ import StartAndEndTime from "../../../Types/Time/StartAndEndTime";
173
+ import Timezone from "../../../Types/Timezone";
174
+
175
+ const PROJECT_ID: string = "11111111-1111-4111-8111-111111111111";
176
+ const SCHEDULE_ID: string = "22222222-2222-4222-8222-222222222222";
177
+ const LAYER_ID: string = "33333333-3333-4333-8333-333333333333";
178
+ const POLICY_ID: string = "44444444-4444-4444-8444-444444444444";
179
+
180
+ const USER_A_ID: string = "aaaaaaaa-1111-4111-8111-111111111111";
181
+ const USER_B_ID: string = "bbbbbbbb-2222-4222-8222-222222222222";
182
+ const USER_C_ID: string = "cccccccc-3333-4333-8333-333333333333";
183
+
184
+ const USER_NAMES: Dictionary<string> = {
185
+ [USER_A_ID]: "Alice Scheduled",
186
+ [USER_B_ID]: "Bob Rotating",
187
+ [USER_C_ID]: "Carol Covering",
188
+ };
189
+
190
+ // The zone the schedule runs in. The browser (see the docblock) is in India.
191
+ const SCHEDULE_TIMEZONE: string = "Asia/Singapore";
192
+
193
+ /*
194
+ * A Wednesday morning. 09:18 in Singapore, 06:48 in India: two and a half
195
+ * hours apart, which is how far off the current-time line used to be.
196
+ */
197
+ const NOW: Date = new Date("2026-09-23T01:18:00.000Z");
198
+
199
+ /*
200
+ * The week the grid shows (Sun 20 - Sat 26 Sep), reported the way the
201
+ * Calendar component reports it for the week view: browser-local Dates
202
+ * standing for the schedule zone's wall clock, from the first day's midnight
203
+ * to the END of the last day.
204
+ */
205
+ const VISIBLE_WEEK_START: Date = new Date(2026, 8, 20, 0, 0, 0, 0);
206
+ const VISIBLE_WEEK_END: Date = OneUptimeDate.getEndOfDay(
207
+ new Date(2026, 8, 26, 0, 0, 0, 0),
208
+ );
209
+
210
+ const TIMEOUT_MS: number = 10000;
211
+
212
+ function objectId(id: string): ObjectID {
213
+ return new ObjectID(id);
214
+ }
215
+
216
+ // An instant given as a wall clock in the schedule's zone, e.g. "2026-09-22 17:02".
217
+ function inSchedule(wallClock: string): Date {
218
+ return Moment.tz(wallClock, "YYYY-MM-DD HH:mm", SCHEDULE_TIMEZONE).toDate();
219
+ }
220
+
221
+ function pad(value: number): string {
222
+ return String(value).padStart(2, "0");
223
+ }
224
+
225
+ /*
226
+ * Where the grid draws a display-local Date: its browser-local wall clock,
227
+ * read straight off the Date the way react-big-calendar reads it.
228
+ */
229
+ function onGrid(date: Date): string {
230
+ return (
231
+ `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ` +
232
+ `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
233
+ );
234
+ }
235
+
236
+ // The same, to the minute - the grid lays blocks out in whole minutes.
237
+ function onGridMinute(date: Date): string {
238
+ return onGrid(date).slice(0, 16);
239
+ }
240
+
241
+ function makeUser(id: string): User {
242
+ const user: User = new User();
243
+ user.id = objectId(id);
244
+ user.name = USER_NAMES[id] as any;
245
+ user.email = `${id}@example.com` as any;
246
+ return user;
247
+ }
248
+
249
+ function noRestrictions(): RestrictionTimes {
250
+ const restrictionTimes: RestrictionTimes = new RestrictionTimes();
251
+ restrictionTimes.restictionType = RestrictionType.None;
252
+ restrictionTimes.dayRestrictionTimes = null;
253
+ return restrictionTimes;
254
+ }
255
+
256
+ // On call only between `from` and `to` (schedule-zone wall clock) every day.
257
+ function dailyRestriction(from: string, to: string): RestrictionTimes {
258
+ const restrictionTimes: RestrictionTimes = new RestrictionTimes();
259
+ restrictionTimes.restictionType = RestrictionType.Daily;
260
+ restrictionTimes.dayRestrictionTimes = {
261
+ startTime: inSchedule(`2026-09-01 ${from}`),
262
+ endTime: inSchedule(`2026-09-01 ${to}`),
263
+ };
264
+ restrictionTimes.weeklyRestrictionTimes = [];
265
+ return restrictionTimes;
266
+ }
267
+
268
+ /*
269
+ * On call from Monday 09:00 straight through to Friday 17:00 (schedule-zone
270
+ * wall clock), nobody at the weekend. The engine reads the weekday off the
271
+ * timestamps, so they are a real Monday and Friday.
272
+ */
273
+ function weekdaysOnlyRestriction(): RestrictionTimes {
274
+ const restrictionTimes: RestrictionTimes = new RestrictionTimes();
275
+ restrictionTimes.restictionType = RestrictionType.Weekly;
276
+ restrictionTimes.dayRestrictionTimes = null;
277
+ restrictionTimes.weeklyRestrictionTimes = [
278
+ {
279
+ startDay: DayOfWeek.Monday,
280
+ endDay: DayOfWeek.Friday,
281
+ startTime: inSchedule("2026-09-21 09:00"),
282
+ endTime: inSchedule("2026-09-25 17:00"),
283
+ },
284
+ ];
285
+ return restrictionTimes;
286
+ }
287
+
288
+ /*
289
+ * A daily rotation that hands off at `handOff` in the schedule's zone. The
290
+ * default, 5:02 PM, is the hand-off from the report: a time that is neither
291
+ * midnight nor on the hour, so a block that starts or ends at a day boundary
292
+ * can only be an artefact of the computation window. By default the rotation
293
+ * started a month ago; `startsAt` (schedule-zone wall clock) moves that.
294
+ */
295
+ function makeLayer(
296
+ restrictionTimes: RestrictionTimes,
297
+ handOff: string = "17:02",
298
+ startsAt: string = "2026-08-20 00:00",
299
+ ): OnCallDutyPolicyScheduleLayer {
300
+ const layer: OnCallDutyPolicyScheduleLayer =
301
+ new OnCallDutyPolicyScheduleLayer();
302
+ layer.id = objectId(LAYER_ID);
303
+ layer.projectId = objectId(PROJECT_ID);
304
+ layer.onCallDutyPolicyScheduleId = objectId(SCHEDULE_ID);
305
+ layer.order = 1;
306
+ layer.name = "Primary" as any;
307
+ layer.startsAt = inSchedule(startsAt);
308
+ layer.handOffTime = inSchedule(`${startsAt.slice(0, 10)} ${handOff}`);
309
+ layer.rotation = Recurring.fromJSON({
310
+ _type: "Recurring",
311
+ value: {
312
+ intervalType: EventInterval.Day,
313
+ intervalCount: { _type: "PositiveNumber", value: 1 },
314
+ },
315
+ } as any) as any;
316
+ layer.restrictionTimes = restrictionTimes as any;
317
+ return layer;
318
+ }
319
+
320
+ function makeLayerUsers(
321
+ userIds: Array<string>,
322
+ ): Dictionary<Array<OnCallDutyPolicyScheduleLayerUser>> {
323
+ return {
324
+ [LAYER_ID]: userIds.map(
325
+ (userId: string, index: number): OnCallDutyPolicyScheduleLayerUser => {
326
+ const layerUser: OnCallDutyPolicyScheduleLayerUser =
327
+ new OnCallDutyPolicyScheduleLayerUser();
328
+ layerUser.id = objectId(
329
+ `6666666${index}-6666-4666-8666-666666666666`.slice(0, 36),
330
+ );
331
+ layerUser.onCallDutyPolicyScheduleLayerId = objectId(LAYER_ID);
332
+ layerUser.onCallDutyPolicyScheduleId = objectId(SCHEDULE_ID);
333
+ layerUser.projectId = objectId(PROJECT_ID);
334
+ layerUser.order = index + 1;
335
+ layerUser.userId = objectId(userId);
336
+ layerUser.user = makeUser(userId);
337
+ return layerUser;
338
+ },
339
+ ),
340
+ };
341
+ }
342
+
343
+ interface OverrideFixture {
344
+ overrideUserId: string;
345
+ routeAlertsToUserId: string;
346
+ startsAt: Date;
347
+ endsAt: Date;
348
+ }
349
+
350
+ function toModel(fixture: OverrideFixture): OnCallDutyPolicyUserOverride {
351
+ const model: OnCallDutyPolicyUserOverride =
352
+ new OnCallDutyPolicyUserOverride();
353
+ model.id = objectId("77777777-7777-4777-8777-777777777777");
354
+ model.projectId = objectId(PROJECT_ID);
355
+ model.overrideUserId = objectId(fixture.overrideUserId);
356
+ model.routeAlertsToUserId = objectId(fixture.routeAlertsToUserId);
357
+ model.startsAt = fixture.startsAt;
358
+ model.endsAt = fixture.endsAt;
359
+ // Global overrides only: they apply whatever the policy context resolves to.
360
+ model.onCallDutyPolicyId = null as any;
361
+ model.overrideUser = makeUser(fixture.overrideUserId);
362
+ model.routeAlertsToUser = makeUser(fixture.routeAlertsToUserId);
363
+ return model;
364
+ }
365
+
366
+ interface OverrideQueryWindow {
367
+ start: Date;
368
+ end: Date;
369
+ }
370
+
371
+ /*
372
+ * The window of every override fetch, in call order. The preview asks for
373
+ * overrides with `endsAt >= start AND startsAt <= end`.
374
+ */
375
+ function getOverrideQueryWindows(): Array<OverrideQueryWindow> {
376
+ return getListMock.mock.calls
377
+ .map((call: Array<any>): any => {
378
+ return call[0];
379
+ })
380
+ .filter((args: any): boolean => {
381
+ return args?.modelType?.name === "OnCallDutyPolicyUserOverride";
382
+ })
383
+ .map((args: any): OverrideQueryWindow => {
384
+ return {
385
+ start: args.query.endsAt.value as Date,
386
+ end: args.query.startsAt.value as Date,
387
+ };
388
+ });
389
+ }
390
+
391
+ function setupApi(overrides: Array<OverrideFixture>): void {
392
+ getListMock.mockImplementation((args: any) => {
393
+ const modelName: string = args?.modelType?.name || "";
394
+
395
+ if (modelName === "OnCallDutyPolicyUserOverride") {
396
+ // Mirrors the server's WHERE clause on the time window.
397
+ const windowStart: Date = args.query.endsAt.value;
398
+ const windowEnd: Date = args.query.startsAt.value;
399
+ const matched: Array<OverrideFixture> = overrides.filter(
400
+ (fixture: OverrideFixture): boolean => {
401
+ return (
402
+ fixture.startsAt.getTime() <= windowEnd.getTime() &&
403
+ fixture.endsAt.getTime() >= windowStart.getTime()
404
+ );
405
+ },
406
+ );
407
+ return Promise.resolve({
408
+ data: matched.map(toModel),
409
+ count: matched.length,
410
+ skip: 0,
411
+ limit: matched.length,
412
+ });
413
+ }
414
+
415
+ if (modelName === "OnCallDutyPolicyEscalationRuleSchedule") {
416
+ const join: OnCallDutyPolicyEscalationRuleSchedule =
417
+ new OnCallDutyPolicyEscalationRuleSchedule();
418
+ join.id = objectId("88888888-8888-4888-8888-888888888888");
419
+ join.projectId = objectId(PROJECT_ID);
420
+ join.onCallDutyPolicyScheduleId = objectId(SCHEDULE_ID);
421
+ join.onCallDutyPolicyId = objectId(POLICY_ID);
422
+ return Promise.resolve({ data: [join], count: 1, skip: 0, limit: 1 });
423
+ }
424
+
425
+ return Promise.resolve({ data: [], count: 0, skip: 0, limit: 0 });
426
+ });
427
+ }
428
+
429
+ function renderPreview(
430
+ layer: OnCallDutyPolicyScheduleLayer,
431
+ userIds: Array<string>,
432
+ ): RenderResult {
433
+ return render(
434
+ <LayersPreview
435
+ layers={[layer]}
436
+ allLayerUsers={makeLayerUsers(userIds)}
437
+ timezone={SCHEDULE_TIMEZONE}
438
+ onCallDutyPolicyScheduleId={objectId(SCHEDULE_ID)}
439
+ />,
440
+ );
441
+ }
442
+
443
+ function getCalendarProps(): CapturedCalendarProps {
444
+ if (!latestCalendarProps) {
445
+ throw new Error("The calendar has not rendered yet");
446
+ }
447
+ return latestCalendarProps;
448
+ }
449
+
450
+ /*
451
+ * The override resolution has landed: the note under the legend is only
452
+ * rendered once the policy context and the overrides are known, and is
453
+ * withdrawn again while a new window is being fetched.
454
+ */
455
+ async function waitForOverridesResolved(): Promise<void> {
456
+ await waitFor(
457
+ () => {
458
+ expect(
459
+ screen.getByText(/the same set used to route alerts/),
460
+ ).toBeInTheDocument();
461
+ },
462
+ { timeout: TIMEOUT_MS },
463
+ );
464
+ }
465
+
466
+ /*
467
+ * Navigate the grid to a range (a week, or a single day in Day view), the way
468
+ * the Calendar component reports a navigation: display-local Dates from the
469
+ * first day's midnight to the END of the last day. Then let the preview
470
+ * recompute and refetch for it. When the override window moves, the note under
471
+ * the legend is withdrawn until the refetch lands, so the second wait waits
472
+ * for it.
473
+ */
474
+ async function showRange(rangeStart: Date, rangeEnd: Date): Promise<void> {
475
+ await waitForOverridesResolved();
476
+
477
+ act(() => {
478
+ getCalendarProps().onRangeChange({
479
+ startTime: rangeStart,
480
+ endTime: rangeEnd,
481
+ });
482
+ });
483
+
484
+ await waitForOverridesResolved();
485
+ }
486
+
487
+ async function showVisibleWeek(): Promise<void> {
488
+ await showRange(VISIBLE_WEEK_START, VISIBLE_WEEK_END);
489
+ }
490
+
491
+ // An instant written as its wall clock in the schedule's zone, to the second.
492
+ function wallClockInSchedule(date: Date): string {
493
+ return Moment.tz(date, SCHEDULE_TIMEZONE).format("YYYY-MM-DD HH:mm:ss");
494
+ }
495
+
496
+ function sortByStart(events: Array<CalendarEvent>): Array<CalendarEvent> {
497
+ return [...events].sort((a: CalendarEvent, b: CalendarEvent): number => {
498
+ return a.start.getTime() - b.start.getTime();
499
+ });
500
+ }
501
+
502
+ function getGapBands(): Array<Array<string>> {
503
+ return sortByStart(getCalendarProps().backgroundEvents || []).map(
504
+ (gap: CalendarEvent): Array<string> => {
505
+ return [onGrid(gap.start), onGrid(gap.end)];
506
+ },
507
+ );
508
+ }
509
+
510
+ /*
511
+ * Every hatched band lies inside the range the grid shows (display-local
512
+ * Dates, as reported through onRangeChange) and is longer than a minute.
513
+ */
514
+ function expectBandsInsideRange(rangeStart: Date, rangeEnd: Date): void {
515
+ const gaps: Array<CalendarEvent> = getCalendarProps().backgroundEvents || [];
516
+ expect(gaps.length).toBeGreaterThan(0);
517
+
518
+ for (const gap of gaps) {
519
+ expect(gap.start.getTime()).toBeGreaterThanOrEqual(rangeStart.getTime());
520
+ expect(gap.end.getTime()).toBeLessThanOrEqual(rangeEnd.getTime());
521
+ /*
522
+ * Clipping to the range can shorten a band to a sliver, which the grid
523
+ * would draw as a hairline. The preview drops anything of 60 seconds or
524
+ * less, after clipping as well as before.
525
+ */
526
+ expect(gap.end.getTime() - gap.start.getTime()).toBeGreaterThan(60 * 1000);
527
+ /*
528
+ * No title and no colour: the Calendar paints a background event only
529
+ * with a colour its caller asks for, and otherwise leaves it to the
530
+ * stylesheet's hatching. A colour here would draw the band as a block
531
+ * that looks like somebody's shift.
532
+ */
533
+ expect(gap.title).toBe("");
534
+ expect(gap.color).toBeUndefined();
535
+ }
536
+ }
537
+
538
+ beforeEach(() => {
539
+ /*
540
+ * Only Date is faked: the clock is pinned, while timers, microtasks and
541
+ * waitFor's polling stay real.
542
+ */
543
+ jest.useFakeTimers({
544
+ now: NOW,
545
+ doNotFake: [
546
+ "hrtime",
547
+ "nextTick",
548
+ "performance",
549
+ "queueMicrotask",
550
+ "requestAnimationFrame",
551
+ "cancelAnimationFrame",
552
+ "requestIdleCallback",
553
+ "cancelIdleCallback",
554
+ "setImmediate",
555
+ "clearImmediate",
556
+ "setInterval",
557
+ "clearInterval",
558
+ "setTimeout",
559
+ "clearTimeout",
560
+ ],
561
+ });
562
+ getListMock.mockReset();
563
+ latestCalendarProps = null;
564
+ });
565
+
566
+ afterEach(() => {
567
+ cleanup();
568
+ jest.useRealTimers();
569
+ });
570
+
571
+ describe("The grid's clock is the schedule zone's clock", () => {
572
+ test("the test really does run in a browser zone that differs from the schedule's", () => {
573
+ /*
574
+ * Everything below depends on the two zones disagreeing. If the docblock
575
+ * pin stopped working, the assertions would pass for the wrong reason.
576
+ */
577
+ expect(new Date().getHours()).toBe(6);
578
+ expect(new Date().getMinutes()).toBe(48);
579
+ });
580
+
581
+ test("getNow places the current-time line at the schedule zone's wall clock, not the browser's", async () => {
582
+ setupApi([]);
583
+ renderPreview(makeLayer(noRestrictions()), [USER_A_ID, USER_B_ID]);
584
+ await waitForOverridesResolved();
585
+
586
+ const getNow: (() => Date) | undefined = getCalendarProps().getNow;
587
+ expect(typeof getNow).toBe("function");
588
+
589
+ /*
590
+ * The grid shows 09:18 in Singapore at the browser-local 09:18 row, so
591
+ * that is where the red line has to be - not at the browser's own 06:48,
592
+ * two and a half hours up the column.
593
+ */
594
+ const displayNow: Date = getNow!();
595
+ expect(onGrid(displayNow)).toBe("2026-09-23 09:18:00");
596
+ expect(displayNow.getHours()).toBe(9);
597
+ expect(displayNow.getMinutes()).toBe(18);
598
+ });
599
+
600
+ test("getNow re-reads the clock on every call, so the line keeps moving", async () => {
601
+ setupApi([]);
602
+ renderPreview(makeLayer(noRestrictions()), [USER_A_ID, USER_B_ID]);
603
+ await waitForOverridesResolved();
604
+
605
+ /*
606
+ * react-big-calendar keeps the function it was given and calls it again
607
+ * every minute to move the line. One that returned a Date captured at
608
+ * render would freeze the line where the page was opened.
609
+ */
610
+ const getNow: () => Date = getCalendarProps().getNow!;
611
+ expect(onGrid(getNow())).toBe("2026-09-23 09:18:00");
612
+
613
+ jest.setSystemTime(new Date("2026-09-23T03:48:00.000Z"));
614
+
615
+ expect(onGrid(getNow())).toBe("2026-09-23 11:48:00");
616
+ });
617
+
618
+ test("getNow follows the zone the grid is shown in when that zone changes", async () => {
619
+ setupApi([]);
620
+ const layer: OnCallDutyPolicyScheduleLayer = makeLayer(noRestrictions());
621
+ const layerUsers: Dictionary<Array<OnCallDutyPolicyScheduleLayerUser>> =
622
+ makeLayerUsers([USER_A_ID, USER_B_ID]);
623
+
624
+ const { rerender }: RenderResult = render(
625
+ <LayersPreview
626
+ layers={[layer]}
627
+ allLayerUsers={layerUsers}
628
+ timezone={SCHEDULE_TIMEZONE}
629
+ onCallDutyPolicyScheduleId={objectId(SCHEDULE_ID)}
630
+ />,
631
+ );
632
+ await waitForOverridesResolved();
633
+ expect(onGrid(getCalendarProps().getNow!())).toBe("2026-09-23 09:18:00");
634
+
635
+ /*
636
+ * The events are re-shifted into the new zone, so the line has to move
637
+ * with them. A getNow that kept the zone it was first created with would
638
+ * leave the line at Singapore's 09:18 on a grid now showing New York,
639
+ * where it is still 21:18 the evening before.
640
+ */
641
+ rerender(
642
+ <LayersPreview
643
+ layers={[layer]}
644
+ allLayerUsers={layerUsers}
645
+ timezone="America/New_York"
646
+ onCallDutyPolicyScheduleId={objectId(SCHEDULE_ID)}
647
+ />,
648
+ );
649
+
650
+ await waitFor(
651
+ () => {
652
+ expect(onGrid(getCalendarProps().getNow!())).toBe(
653
+ "2026-09-22 21:18:00",
654
+ );
655
+ },
656
+ { timeout: TIMEOUT_MS },
657
+ );
658
+ });
659
+
660
+ test("after midnight in Singapore, 'today' is already the next day even though the browser is still on the previous one", async () => {
661
+ // Thu 24 Sep 01:00 in Singapore; still Wed 23 Sep 22:30 in India.
662
+ jest.setSystemTime(new Date("2026-09-23T17:00:00.000Z"));
663
+
664
+ setupApi([]);
665
+ renderPreview(makeLayer(noRestrictions()), [USER_A_ID, USER_B_ID]);
666
+ await waitForOverridesResolved();
667
+
668
+ const displayNow: Date = getCalendarProps().getNow!();
669
+
670
+ /*
671
+ * getNow also picks the highlighted "today" column. Left to the browser
672
+ * clock it would highlight Wednesday on a grid whose Thursday has already
673
+ * begun - and the line would be drawn in the wrong column entirely.
674
+ */
675
+ expect(onGrid(displayNow)).toBe("2026-09-24 01:00:00");
676
+ expect(displayNow.getDay()).toBe(4);
677
+
678
+ // The grid opens on the same day it highlights as today.
679
+ const defaultDate: Date = getCalendarProps().defaultDate!;
680
+ expect(onGrid(defaultDate).slice(0, 10)).toBe("2026-09-24");
681
+ });
682
+ });
683
+
684
+ describe("The grid is given shifts and bands for the range it draws", () => {
685
+ test("before any navigation, a schedule with nobody on it is hatched over exactly the week the grid draws, not the browser's week", async () => {
686
+ setupApi([]);
687
+ renderPreview(makeLayer(noRestrictions()), []);
688
+
689
+ /*
690
+ * The week the grid opens on is the schedule zone's current week, drawn
691
+ * as browser-local Dates: Sun 20 Sep 00:00 to Sat 26 Sep 23:59:59.
692
+ */
693
+ const displayNow: Date =
694
+ OneUptimeDate.getBrowserLocalDateFromWallClockInTimezone(
695
+ OneUptimeDate.getCurrentDate(),
696
+ SCHEDULE_TIMEZONE,
697
+ );
698
+ const displayWeekStart: Date = OneUptimeDate.getStartOfTheWeek(displayNow);
699
+ const displayWeekEnd: Date = OneUptimeDate.getEndOfTheWeek(displayNow);
700
+ expect(onGrid(displayWeekStart)).toBe("2026-09-20 00:00:00");
701
+ expect(onGrid(displayWeekEnd)).toBe("2026-09-26 23:59:59");
702
+
703
+ /*
704
+ * The range used to be seeded from the BROWSER's week: Sun 20 00:00 in
705
+ * India, which is 02:30 on the Singapore grid, through Sun 27 02:29:59.
706
+ * With nobody on call the whole range is one band, so the grid's first
707
+ * two and a half hours were left unhatched and the band ran on into the
708
+ * next week.
709
+ */
710
+ expect(
711
+ onGrid(
712
+ OneUptimeDate.getBrowserLocalDateFromWallClockInTimezone(
713
+ OneUptimeDate.getStartOfTheWeek(OneUptimeDate.getCurrentDate()),
714
+ SCHEDULE_TIMEZONE,
715
+ ),
716
+ ),
717
+ ).toBe("2026-09-20 02:30:00");
718
+
719
+ await waitFor(
720
+ () => {
721
+ expect(getGapBands()).toEqual([
722
+ ["2026-09-20 00:00:00", "2026-09-26 23:59:59"],
723
+ ]);
724
+ },
725
+ { timeout: TIMEOUT_MS },
726
+ );
727
+ expect(getCalendarProps().backgroundEvents![0]!.start.getTime()).toBe(
728
+ displayWeekStart.getTime(),
729
+ );
730
+ expectBandsInsideRange(displayWeekStart, displayWeekEnd);
731
+ });
732
+
733
+ test("a rotation starting mid-week leaves the week hatched from the grid's first instant, before and after 'View as' changes", async () => {
734
+ setupApi([]);
735
+ // Starts Wed 23 Sep 09:00 in Singapore, i.e. Tue 22 Sep 21:00 in New York.
736
+ renderPreview(makeLayer(noRestrictions(), "17:02", "2026-09-23 09:00"), [
737
+ USER_A_ID,
738
+ USER_B_ID,
739
+ ]);
740
+ await waitForOverridesResolved();
741
+
742
+ /*
743
+ * Nobody is on call until the rotation starts. Computed over the browser's
744
+ * week, this band started at 02:30 on the grid instead of at midnight.
745
+ */
746
+ expect(getGapBands()).toEqual([
747
+ ["2026-09-20 00:00:00", "2026-09-23 09:00:00"],
748
+ ]);
749
+ expectBandsInsideRange(VISIBLE_WEEK_START, VISIBLE_WEEK_END);
750
+
751
+ // Navigating to the same week reports it, and changes nothing.
752
+ await showVisibleWeek();
753
+ expect(getGapBands()).toEqual([
754
+ ["2026-09-20 00:00:00", "2026-09-23 09:00:00"],
755
+ ]);
756
+
757
+ fireEvent.click(screen.getByTestId("view-as-new-york"));
758
+
759
+ /*
760
+ * The grid keeps showing Sun 20 - Sat 26, now as New York's wall clock,
761
+ * so the band must still open at its first instant and end where the
762
+ * rotation starts on New York's clock. The reported range used to be
763
+ * converted to instants once, with the zone current at that navigation,
764
+ * so a "View as" change left it at Singapore's week: on New York's grid
765
+ * that starts on Saturday 19 at 12:00, and the week the shifts and bands
766
+ * were computed for no longer matched the week drawn.
767
+ */
768
+ await waitFor(
769
+ () => {
770
+ expect(getGapBands()).toEqual([
771
+ ["2026-09-20 00:00:00", "2026-09-22 21:00:00"],
772
+ ]);
773
+ },
774
+ { timeout: TIMEOUT_MS },
775
+ );
776
+ expectBandsInsideRange(VISIBLE_WEEK_START, VISIBLE_WEEK_END);
777
+ });
778
+
779
+ test("before any navigation, the grid is given the shifts and bands of the week it opens on, not the browser's week", async () => {
780
+ // Sun 27 Sep 01:00 in Singapore; still Sat 26 Sep 22:30 in India.
781
+ jest.setSystemTime(new Date("2026-09-26T17:00:00.000Z"));
782
+
783
+ setupApi([]);
784
+ renderPreview(makeLayer(dailyRestriction("09:00", "17:00")), [
785
+ USER_A_ID,
786
+ USER_B_ID,
787
+ ]);
788
+ await waitForOverridesResolved();
789
+
790
+ /*
791
+ * react-big-calendar does not report its range on mount, so the preview
792
+ * seeds one. Seeded from the browser's week (Sun 20 - Sat 26 in India),
793
+ * the grid opened on Singapore's new week (Sun 27 Sep - Sat 3 Oct) with
794
+ * shifts only up to Mon 28 02:29 and no hatching at all, until the user
795
+ * happened to navigate.
796
+ */
797
+ expect(onGrid(getCalendarProps().defaultDate!).slice(0, 10)).toBe(
798
+ "2026-09-27",
799
+ );
800
+ expect(getGapBands()).toEqual([
801
+ ["2026-09-27 00:00:00", "2026-09-27 09:00:00"],
802
+ ["2026-09-27 17:00:00", "2026-09-28 09:00:00"],
803
+ ["2026-09-28 17:00:00", "2026-09-29 09:00:00"],
804
+ ["2026-09-29 17:00:00", "2026-09-30 09:00:00"],
805
+ ["2026-09-30 17:00:00", "2026-10-01 09:00:00"],
806
+ ["2026-10-01 17:00:00", "2026-10-02 09:00:00"],
807
+ ["2026-10-02 17:00:00", "2026-10-03 09:00:00"],
808
+ ["2026-10-03 17:00:00", "2026-10-03 23:59:59"],
809
+ ]);
810
+ expectBandsInsideRange(
811
+ new Date(2026, 8, 27, 0, 0, 0, 0),
812
+ OneUptimeDate.getEndOfDay(new Date(2026, 9, 3, 0, 0, 0, 0)),
813
+ );
814
+
815
+ // Saturday's shift, the last of the week the grid shows, is there too.
816
+ expect(
817
+ getCalendarProps().events.some((event: CalendarEvent): boolean => {
818
+ return onGridMinute(event.start) === "2026-10-03 09:00";
819
+ }),
820
+ ).toBe(true);
821
+ });
822
+ });
823
+
824
+ describe("The grid is given the real start and end of the shifts at the week's edges", () => {
825
+ test("the first and last blocks of the week run on past its edges to the real 5:02 PM hand-offs", async () => {
826
+ setupApi([]);
827
+ renderPreview(makeLayer(noRestrictions()), [USER_A_ID, USER_B_ID]);
828
+ await showVisibleWeek();
829
+
830
+ const events: Array<CalendarEvent> = getCalendarProps().events;
831
+
832
+ /*
833
+ * The shift on call at the first moment of the week began the previous
834
+ * afternoon. Computed for the visible week only, it was cut to start at
835
+ * Sunday 12:00 AM, which the grid then drew as a hand-off at midnight.
836
+ */
837
+ const coveringWeekStart: CalendarEvent | undefined = events.find(
838
+ (event: CalendarEvent): boolean => {
839
+ return (
840
+ event.start.getTime() < VISIBLE_WEEK_START.getTime() &&
841
+ event.end.getTime() > VISIBLE_WEEK_START.getTime()
842
+ );
843
+ },
844
+ );
845
+ expect(coveringWeekStart).toBeDefined();
846
+ expect(onGridMinute(coveringWeekStart!.start)).toBe("2026-09-19 17:02");
847
+ expect(onGridMinute(coveringWeekStart!.end)).toBe("2026-09-20 17:02");
848
+
849
+ // Likewise the last one, which used to "end" at Saturday 11:59:59 PM.
850
+ const coveringWeekEnd: CalendarEvent | undefined = events.find(
851
+ (event: CalendarEvent): boolean => {
852
+ return (
853
+ event.start.getTime() < VISIBLE_WEEK_END.getTime() &&
854
+ event.end.getTime() > VISIBLE_WEEK_END.getTime()
855
+ );
856
+ },
857
+ );
858
+ expect(coveringWeekEnd).toBeDefined();
859
+ expect(onGridMinute(coveringWeekEnd!.start)).toBe("2026-09-26 17:02");
860
+ expect(onGridMinute(coveringWeekEnd!.end)).toBe("2026-09-27 17:02");
861
+
862
+ // And nothing else is cut at the week's first or last second either.
863
+ for (const event of events) {
864
+ expect(onGrid(event.start)).not.toBe("2026-09-20 00:00:00");
865
+ expect(onGrid(event.end)).not.toBe("2026-09-26 23:59:59");
866
+ }
867
+ });
868
+
869
+ test("consecutive shifts meet at the 5:02 PM hand-off, in the same minute", async () => {
870
+ setupApi([]);
871
+ renderPreview(makeLayer(noRestrictions()), [USER_A_ID, USER_B_ID]);
872
+ await showVisibleWeek();
873
+
874
+ /*
875
+ * The reported gap between a shift ending at 5:02 and the next starting
876
+ * at 5:02 was drawn by the grid, not present in the data: the engine's
877
+ * one-second seam (17:02:00 -> 17:02:01) falls inside one minute, and the
878
+ * grid lays blocks out in whole minutes. This pins the data half of that.
879
+ */
880
+ const events: Array<CalendarEvent> = sortByStart(getCalendarProps().events);
881
+ expect(events.length).toBeGreaterThan(7);
882
+
883
+ for (let i: number = 1; i < events.length; i++) {
884
+ expect(onGridMinute(events[i]!.start)).toBe(
885
+ onGridMinute(events[i - 1]!.end),
886
+ );
887
+ }
888
+
889
+ const handOffs: Array<string> = events
890
+ .slice(1)
891
+ .map((event: CalendarEvent): string => {
892
+ return onGridMinute(event.start).slice(11);
893
+ });
894
+ expect(new Set<string>(handOffs)).toEqual(new Set<string>(["17:02"]));
895
+ });
896
+
897
+ test("a midnight hand-off gives back-to-back midnight-to-midnight blocks, none flagged all-day", async () => {
898
+ setupApi([]);
899
+ renderPreview(makeLayer(noRestrictions(), "00:00"), [USER_A_ID, USER_B_ID]);
900
+ await showVisibleWeek();
901
+
902
+ const events: Array<CalendarEvent> = sortByStart(getCalendarProps().events);
903
+
904
+ /*
905
+ * The 26 Sep report: a shift ending at 12:00 AM and the next starting at
906
+ * 12:00 AM looked like they overlapped. In the data they meet at midnight
907
+ * - one ends at 00:00:00, the next starts in the same minute - and none is
908
+ * all-day, so it is up to the grid to draw them back to back rather than
909
+ * lifting them into the all-day strip (see Calendar.tsx).
910
+ */
911
+ const endingAtSaturdayMidnight: CalendarEvent | undefined = events.find(
912
+ (event: CalendarEvent): boolean => {
913
+ return onGrid(event.end) === "2026-09-26 00:00:00";
914
+ },
915
+ );
916
+ expect(endingAtSaturdayMidnight).toBeDefined();
917
+
918
+ for (let i: number = 1; i < events.length; i++) {
919
+ expect(onGridMinute(events[i]!.start)).toBe(
920
+ onGridMinute(events[i - 1]!.end),
921
+ );
922
+ }
923
+
924
+ for (const event of events) {
925
+ expect(event.allDay).not.toBe(true);
926
+ expect(onGridMinute(event.start).slice(11)).toBe("00:00");
927
+ }
928
+ });
929
+
930
+ test("an override in the day before the week still shapes the block that runs into it", async () => {
931
+ /*
932
+ * The blocks now run a day past each edge of the week, so the overrides
933
+ * in that margin have to be fetched and applied too. Here Carol covers
934
+ * Alice on the Saturday evening before the week, ending an hour before it
935
+ * starts. The block crossing into Sunday is Alice's from 11:00 PM, which
936
+ * its tooltip reports. Fetched from the week's first instant only, as
937
+ * before, this override was never loaded, and the block claimed Alice had
938
+ * been on call since 5:02 PM.
939
+ */
940
+ setupApi([
941
+ {
942
+ overrideUserId: USER_A_ID,
943
+ routeAlertsToUserId: USER_C_ID,
944
+ startsAt: inSchedule("2026-09-19 18:00"),
945
+ endsAt: inSchedule("2026-09-19 23:00"),
946
+ },
947
+ ]);
948
+ renderPreview(makeLayer(noRestrictions()), [USER_A_ID]);
949
+ await showVisibleWeek();
950
+
951
+ const windows: Array<OverrideQueryWindow> = getOverrideQueryWindows();
952
+ expect(wallClockInSchedule(windows[windows.length - 1]!.start)).toBe(
953
+ "2026-09-19 00:00:00",
954
+ );
955
+
956
+ await waitFor(
957
+ () => {
958
+ const coveringWeekStart: CalendarEvent | undefined =
959
+ getCalendarProps().events.find((event: CalendarEvent): boolean => {
960
+ return (
961
+ event.start.getTime() < VISIBLE_WEEK_START.getTime() &&
962
+ event.end.getTime() > VISIBLE_WEEK_START.getTime()
963
+ );
964
+ });
965
+ expect(coveringWeekStart).toBeDefined();
966
+ expect(onGridMinute(coveringWeekStart!.start)).toBe("2026-09-19 23:00");
967
+ expect(onGridMinute(coveringWeekStart!.end)).toBe("2026-09-20 17:02");
968
+ expect(coveringWeekStart!.title).toContain(USER_NAMES[USER_A_ID]);
969
+ expect(coveringWeekStart!.className).toBeUndefined();
970
+ },
971
+ { timeout: TIMEOUT_MS },
972
+ );
973
+ });
974
+
975
+ test("for a week past the summary's window, the override fetch reaches into the day after it", async () => {
976
+ setupApi([]);
977
+ renderPreview(makeLayer(noRestrictions()), [USER_A_ID, USER_B_ID]);
978
+
979
+ /*
980
+ * The fetch window also spans the summary's three months ahead, which
981
+ * hides its end for any week close to today. A January week lies past
982
+ * that, so the fetch has to end a full day after the week (Sun 10 Jan)
983
+ * rather than at its last second (Sat 9 Jan 23:59:59), or an override in
984
+ * the margin after the week would be missing from the last block.
985
+ */
986
+ await showRange(
987
+ new Date(2027, 0, 3, 0, 0, 0, 0),
988
+ OneUptimeDate.getEndOfDay(new Date(2027, 0, 9, 0, 0, 0, 0)),
989
+ );
990
+
991
+ const windows: Array<OverrideQueryWindow> = getOverrideQueryWindows();
992
+ expect(wallClockInSchedule(windows[windows.length - 1]!.end)).toBe(
993
+ "2027-01-10 23:59:59",
994
+ );
995
+ });
996
+
997
+ test("an override is still relabelled, and meets the shift after it at its 5:02 PM end", async () => {
998
+ setupApi([
999
+ {
1000
+ overrideUserId: USER_A_ID,
1001
+ routeAlertsToUserId: USER_C_ID,
1002
+ startsAt: inSchedule("2026-09-22 12:00"),
1003
+ endsAt: inSchedule("2026-09-22 17:02"),
1004
+ },
1005
+ ]);
1006
+ renderPreview(makeLayer(noRestrictions()), [USER_A_ID]);
1007
+ await showVisibleWeek();
1008
+
1009
+ await waitFor(
1010
+ () => {
1011
+ expect(
1012
+ getCalendarProps().events.some((event: CalendarEvent): boolean => {
1013
+ return event.className === OVERRIDE_EVENT_CLASS_NAME;
1014
+ }),
1015
+ ).toBe(true);
1016
+ },
1017
+ { timeout: TIMEOUT_MS },
1018
+ );
1019
+
1020
+ const events: Array<CalendarEvent> = sortByStart(getCalendarProps().events);
1021
+ const overrideIndex: number = events.findIndex(
1022
+ (event: CalendarEvent): boolean => {
1023
+ return event.className === OVERRIDE_EVENT_CLASS_NAME;
1024
+ },
1025
+ );
1026
+ const overrideEvent: CalendarEvent = events[overrideIndex]!;
1027
+
1028
+ expect(overrideEvent.title).toContain(USER_NAMES[USER_C_ID]);
1029
+ expect(overrideEvent.title).toContain(`covering ${USER_NAMES[USER_A_ID]}`);
1030
+ expect(onGridMinute(overrideEvent.start)).toBe("2026-09-22 12:00");
1031
+ expect(onGridMinute(overrideEvent.end)).toBe("2026-09-22 17:02");
1032
+
1033
+ /*
1034
+ * The 12 Sep report: an override ending at 5:02 and the shift after it
1035
+ * starting at 5:02 were drawn with a gap between them. The data meets in
1036
+ * the same minute on both sides; the gap came from the override block's
1037
+ * CSS (see Calendar.css).
1038
+ */
1039
+ expect(onGridMinute(events[overrideIndex - 1]!.end)).toBe(
1040
+ "2026-09-22 12:00",
1041
+ );
1042
+ expect(onGridMinute(events[overrideIndex + 1]!.start)).toBe(
1043
+ "2026-09-22 17:02",
1044
+ );
1045
+ expect(events[overrideIndex + 1]!.className).toBeUndefined();
1046
+
1047
+ const titles: Array<string> = screen
1048
+ .getAllByTestId("calendar-event")
1049
+ .map((node: HTMLElement): string => {
1050
+ return node.textContent || "";
1051
+ });
1052
+ expect(
1053
+ titles.some((title: string): boolean => {
1054
+ return title.includes(`covering ${USER_NAMES[USER_A_ID]}`);
1055
+ }),
1056
+ ).toBe(true);
1057
+ });
1058
+ });
1059
+
1060
+ describe("Uncovered bands cover the visible range and stay inside it", () => {
1061
+ function expectBandsInsideVisibleWeek(): void {
1062
+ expectBandsInsideRange(VISIBLE_WEEK_START, VISIBLE_WEEK_END);
1063
+ }
1064
+
1065
+ test("an office-hours rotation shades every evening and night of the week, including the last evening", async () => {
1066
+ setupApi([]);
1067
+ renderPreview(makeLayer(dailyRestriction("09:00", "17:00")), [
1068
+ USER_A_ID,
1069
+ USER_B_ID,
1070
+ ]);
1071
+ await showVisibleWeek();
1072
+
1073
+ /*
1074
+ * The first band opens in the margin day (Saturday 17:00) and is clipped
1075
+ * to the week's first instant. The last one runs into the margin day after
1076
+ * the week and is clipped to its last second. That last band used to be
1077
+ * missing altogether: with shifts computed for the visible week only,
1078
+ * nothing followed Saturday's 17:00 end, so Saturday evening - nobody on
1079
+ * call - was drawn as an ordinary empty grid.
1080
+ */
1081
+ expect(getGapBands()).toEqual([
1082
+ ["2026-09-20 00:00:00", "2026-09-20 09:00:00"],
1083
+ ["2026-09-20 17:00:00", "2026-09-21 09:00:00"],
1084
+ ["2026-09-21 17:00:00", "2026-09-22 09:00:00"],
1085
+ ["2026-09-22 17:00:00", "2026-09-23 09:00:00"],
1086
+ ["2026-09-23 17:00:00", "2026-09-24 09:00:00"],
1087
+ ["2026-09-24 17:00:00", "2026-09-25 09:00:00"],
1088
+ ["2026-09-25 17:00:00", "2026-09-26 09:00:00"],
1089
+ ["2026-09-26 17:00:00", "2026-09-26 23:59:59"],
1090
+ ]);
1091
+ expectBandsInsideVisibleWeek();
1092
+ });
1093
+
1094
+ test("a weekday-only rotation shades the weekend at the end of the week, not just the one at its start", async () => {
1095
+ setupApi([]);
1096
+ renderPreview(makeLayer(weekdaysOnlyRestriction()), [USER_A_ID, USER_B_ID]);
1097
+ await showVisibleWeek();
1098
+
1099
+ /*
1100
+ * Nobody is on call from Friday 17:00 until Monday 09:00. The coverage
1101
+ * gap finder never reports a hole after the last shift (for the summary,
1102
+ * that is just where its data stops), and the next shift after Friday is
1103
+ * Monday, beyond even the margin day. So Friday evening and Saturday used
1104
+ * to be drawn as an ordinary empty grid, while the same stretch at the
1105
+ * start of the week was hatched.
1106
+ */
1107
+ expect(getGapBands()).toEqual([
1108
+ ["2026-09-20 00:00:00", "2026-09-21 09:00:00"],
1109
+ ["2026-09-25 17:00:00", "2026-09-26 23:59:59"],
1110
+ ]);
1111
+ expectBandsInsideVisibleWeek();
1112
+ });
1113
+
1114
+ test("in Day view, the evening after a weekday-only rotation's Friday 17:00 end, and the whole Saturday after it, are hatched", async () => {
1115
+ setupApi([]);
1116
+ renderPreview(makeLayer(weekdaysOnlyRestriction()), [USER_A_ID, USER_B_ID]);
1117
+
1118
+ // Day view reports a single day: its midnight to the end of that day.
1119
+ const friday: Date = new Date(2026, 8, 25, 0, 0, 0, 0);
1120
+ const fridayEnd: Date = OneUptimeDate.getEndOfDay(friday);
1121
+ await showRange(friday, fridayEnd);
1122
+
1123
+ expect(getGapBands()).toEqual([
1124
+ ["2026-09-25 17:00:00", "2026-09-25 23:59:59"],
1125
+ ]);
1126
+ expectBandsInsideRange(friday, fridayEnd);
1127
+
1128
+ const saturday: Date = new Date(2026, 8, 26, 0, 0, 0, 0);
1129
+ const saturdayEnd: Date = OneUptimeDate.getEndOfDay(saturday);
1130
+ await showRange(saturday, saturdayEnd);
1131
+
1132
+ /*
1133
+ * Saturday is computed with a day of margin either side, so Friday's
1134
+ * shift is known, but it ends before Saturday begins and the next one
1135
+ * (Monday 09:00) lies beyond even the margin. The coverage gap finder
1136
+ * only reports holes before or between shifts, so with Friday's shift in
1137
+ * the margin it found nothing, and a day with nobody on call at all was
1138
+ * drawn as an ordinary empty grid. It is one band, midnight to midnight.
1139
+ */
1140
+ const bands: Array<CalendarEvent> =
1141
+ getCalendarProps().backgroundEvents || [];
1142
+ expect(bands).toHaveLength(1);
1143
+ expect(onGridMinute(bands[0]!.start)).toBe("2026-09-26 00:00");
1144
+ expect(onGridMinute(bands[0]!.end)).toBe("2026-09-26 23:59");
1145
+ expect(getGapBands()).toEqual([
1146
+ ["2026-09-26 00:00:00", "2026-09-26 23:59:59"],
1147
+ ]);
1148
+ expectBandsInsideRange(saturday, saturdayEnd);
1149
+
1150
+ // Friday's shift is there, in the margin, and nobody's block is in Saturday.
1151
+ const events: Array<CalendarEvent> = getCalendarProps().events;
1152
+ expect(
1153
+ events.some((event: CalendarEvent): boolean => {
1154
+ return onGridMinute(event.end) === "2026-09-25 17:00";
1155
+ }),
1156
+ ).toBe(true);
1157
+ for (const event of events) {
1158
+ expect(
1159
+ event.start.getTime() < saturdayEnd.getTime() &&
1160
+ event.end.getTime() > saturday.getTime(),
1161
+ ).toBe(false);
1162
+ }
1163
+ });
1164
+
1165
+ test("an uncovered stretch lying wholly in the margin days is not drawn", async () => {
1166
+ setupApi([]);
1167
+ renderPreview(makeLayer(dailyRestriction("20:00", "04:00")), [
1168
+ USER_A_ID,
1169
+ USER_B_ID,
1170
+ ]);
1171
+ await showVisibleWeek();
1172
+
1173
+ /*
1174
+ * An overnight rotation (20:00 - 04:00) is uncovered 04:00 - 20:00 every
1175
+ * day, including Saturday 19 and Sunday 27 - the margin days either side
1176
+ * of the week, which are computed but not shown. Those two must not come
1177
+ * back as bands (or as an "Uncovered" legend entry for a band nobody can
1178
+ * see).
1179
+ */
1180
+ expect(getGapBands()).toEqual([
1181
+ ["2026-09-20 04:00:00", "2026-09-20 20:00:00"],
1182
+ ["2026-09-21 04:00:00", "2026-09-21 20:00:00"],
1183
+ ["2026-09-22 04:00:00", "2026-09-22 20:00:00"],
1184
+ ["2026-09-23 04:00:00", "2026-09-23 20:00:00"],
1185
+ ["2026-09-24 04:00:00", "2026-09-24 20:00:00"],
1186
+ ["2026-09-25 04:00:00", "2026-09-25 20:00:00"],
1187
+ ["2026-09-26 04:00:00", "2026-09-26 20:00:00"],
1188
+ ]);
1189
+ expectBandsInsideVisibleWeek();
1190
+ });
1191
+
1192
+ test("clipping at the week's end does not leave a sub-minute hairline band", async () => {
1193
+ setupApi([]);
1194
+ renderPreview(makeLayer(dailyRestriction("09:00", "23:59")), [
1195
+ USER_A_ID,
1196
+ USER_B_ID,
1197
+ ]);
1198
+ await showVisibleWeek();
1199
+
1200
+ /*
1201
+ * On call 09:00 - 23:59, so each night's hole is 23:59 -> 09:00. The one
1202
+ * after Saturday is clipped to the week's last second, leaving 59 seconds:
1203
+ * a hairline, not a band. It must be dropped after clipping, not only
1204
+ * before it.
1205
+ */
1206
+ expect(getGapBands()).toEqual([
1207
+ ["2026-09-20 00:00:00", "2026-09-20 09:00:00"],
1208
+ ["2026-09-20 23:59:00", "2026-09-21 09:00:00"],
1209
+ ["2026-09-21 23:59:00", "2026-09-22 09:00:00"],
1210
+ ["2026-09-22 23:59:00", "2026-09-23 09:00:00"],
1211
+ ["2026-09-23 23:59:00", "2026-09-24 09:00:00"],
1212
+ ["2026-09-24 23:59:00", "2026-09-25 09:00:00"],
1213
+ ["2026-09-25 23:59:00", "2026-09-26 09:00:00"],
1214
+ ]);
1215
+ expectBandsInsideVisibleWeek();
1216
+ });
1217
+ });
1218
+
1219
+ /*
1220
+ * The same grid for a user whose User Settings zone is New York while the
1221
+ * browser is still in India: a VPN, a travelling laptop, an OS set to the
1222
+ * wrong zone. OneUptimeDate's "current timezone" is then New York, but
1223
+ * react-big-calendar still draws in the browser's zone. The display shift
1224
+ * built its wall clocks in the settings zone, so every block, band and the
1225
+ * current-time line was drawn nine and a half hours late against the hour
1226
+ * gutter. They all moved together, so the grid still looked self-consistent.
1227
+ */
1228
+ describe("A User Settings zone that differs from the browser's does not move the grid", () => {
1229
+ const SETTINGS_ZONE: Timezone = Timezone.AmericaNew_York;
1230
+
1231
+ beforeEach(() => {
1232
+ OneUptimeDate.setUserTimezone(SETTINGS_ZONE);
1233
+ });
1234
+
1235
+ afterEach(() => {
1236
+ OneUptimeDate.setUserTimezone(null);
1237
+ });
1238
+
1239
+ test("the test really does run with a settings zone that is neither the browser's nor the schedule's", () => {
1240
+ expect(OneUptimeDate.getCurrentTimezone()).toBe(SETTINGS_ZONE);
1241
+ expect(new Date().getHours()).toBe(6);
1242
+ expect(new Date().getMinutes()).toBe(48);
1243
+ });
1244
+
1245
+ test("the current-time line and today's column are at the schedule zone's clock", async () => {
1246
+ setupApi([]);
1247
+ renderPreview(makeLayer(noRestrictions()), [USER_A_ID, USER_B_ID]);
1248
+ await waitForOverridesResolved();
1249
+
1250
+ /*
1251
+ * 09:18 in Singapore. Built on New York's clock, the line was drawn at
1252
+ * the browser-local 18:48 instead.
1253
+ */
1254
+ expect(onGrid(getCalendarProps().getNow!())).toBe("2026-09-23 09:18:00");
1255
+ expect(onGrid(getCalendarProps().defaultDate!).slice(0, 10)).toBe(
1256
+ "2026-09-23",
1257
+ );
1258
+ });
1259
+
1260
+ test("blocks hand off at 5:02 PM on the grid, including the ones crossing the week's edges", async () => {
1261
+ setupApi([]);
1262
+ renderPreview(makeLayer(noRestrictions()), [USER_A_ID, USER_B_ID]);
1263
+ await showVisibleWeek();
1264
+
1265
+ // Each hand-off used to sit at 2:32 AM the next morning.
1266
+ const events: Array<CalendarEvent> = sortByStart(getCalendarProps().events);
1267
+ expect(events.length).toBeGreaterThan(7);
1268
+ expect(
1269
+ new Set<string>(
1270
+ events.slice(1).map((event: CalendarEvent): string => {
1271
+ return onGridMinute(event.start).slice(11);
1272
+ }),
1273
+ ),
1274
+ ).toEqual(new Set<string>(["17:02"]));
1275
+
1276
+ const coveringWeekStart: CalendarEvent | undefined = events.find(
1277
+ (event: CalendarEvent): boolean => {
1278
+ return (
1279
+ event.start.getTime() < VISIBLE_WEEK_START.getTime() &&
1280
+ event.end.getTime() > VISIBLE_WEEK_START.getTime()
1281
+ );
1282
+ },
1283
+ );
1284
+ expect(coveringWeekStart).toBeDefined();
1285
+ expect(onGridMinute(coveringWeekStart!.start)).toBe("2026-09-19 17:02");
1286
+ expect(onGridMinute(coveringWeekStart!.end)).toBe("2026-09-20 17:02");
1287
+ });
1288
+
1289
+ test("the week the grid reports is read at the schedule zone's clock", async () => {
1290
+ setupApi([]);
1291
+ renderPreview(makeLayer(noRestrictions()), [USER_A_ID, USER_B_ID]);
1292
+ await showVisibleWeek();
1293
+
1294
+ /*
1295
+ * The grid reports its first instant as a browser-local Sun 20 00:00.
1296
+ * Read on New York's clock that was Sat 19 14:30, so the shifts and the
1297
+ * override fetch (a day of margin before the week) started on Friday
1298
+ * afternoon rather than at Saturday midnight.
1299
+ */
1300
+ const windows: Array<OverrideQueryWindow> = getOverrideQueryWindows();
1301
+ expect(wallClockInSchedule(windows[windows.length - 1]!.start)).toBe(
1302
+ "2026-09-19 00:00:00",
1303
+ );
1304
+ });
1305
+
1306
+ test("before any navigation, office hours are hatched over exactly the week the grid draws", async () => {
1307
+ setupApi([]);
1308
+ renderPreview(makeLayer(dailyRestriction("09:00", "17:00")), [
1309
+ USER_A_ID,
1310
+ USER_B_ID,
1311
+ ]);
1312
+ await waitForOverridesResolved();
1313
+
1314
+ /*
1315
+ * The range is seeded from "now" before the grid reports one, so this
1316
+ * covers the seed as well as the bands. Each band used to open at
1317
+ * 18:30 and close at 02:30 the next morning.
1318
+ */
1319
+ expect(getGapBands()).toEqual([
1320
+ ["2026-09-20 00:00:00", "2026-09-20 09:00:00"],
1321
+ ["2026-09-20 17:00:00", "2026-09-21 09:00:00"],
1322
+ ["2026-09-21 17:00:00", "2026-09-22 09:00:00"],
1323
+ ["2026-09-22 17:00:00", "2026-09-23 09:00:00"],
1324
+ ["2026-09-23 17:00:00", "2026-09-24 09:00:00"],
1325
+ ["2026-09-24 17:00:00", "2026-09-25 09:00:00"],
1326
+ ["2026-09-25 17:00:00", "2026-09-26 09:00:00"],
1327
+ ["2026-09-26 17:00:00", "2026-09-26 23:59:59"],
1328
+ ]);
1329
+ expectBandsInsideRange(VISIBLE_WEEK_START, VISIBLE_WEEK_END);
1330
+ });
1331
+
1332
+ test("'View as' the settings zone itself draws that zone's clock", async () => {
1333
+ setupApi([]);
1334
+ // Starts Wed 23 Sep 09:00 in Singapore, i.e. Tue 22 Sep 21:00 in New York.
1335
+ renderPreview(makeLayer(noRestrictions(), "17:02", "2026-09-23 09:00"), [
1336
+ USER_A_ID,
1337
+ USER_B_ID,
1338
+ ]);
1339
+ await showVisibleWeek();
1340
+ expect(getGapBands()).toEqual([
1341
+ ["2026-09-20 00:00:00", "2026-09-23 09:00:00"],
1342
+ ]);
1343
+
1344
+ fireEvent.click(screen.getByTestId("view-as-new-york"));
1345
+
1346
+ /*
1347
+ * Viewing in the settings zone left the instants unshifted, so the grid
1348
+ * showed them at the BROWSER's clock: the line at India's 06:48 and the
1349
+ * rotation starting at 06:30 on Wednesday rather than 21:00 on Tuesday.
1350
+ */
1351
+ await waitFor(
1352
+ () => {
1353
+ expect(onGrid(getCalendarProps().getNow!())).toBe(
1354
+ "2026-09-22 21:18:00",
1355
+ );
1356
+ expect(getGapBands()).toEqual([
1357
+ ["2026-09-20 00:00:00", "2026-09-22 21:00:00"],
1358
+ ]);
1359
+ },
1360
+ { timeout: TIMEOUT_MS },
1361
+ );
1362
+ expectBandsInsideRange(VISIBLE_WEEK_START, VISIBLE_WEEK_END);
1363
+ });
1364
+
1365
+ test("a schedule with no timezone is viewed on the settings zone's clock", async () => {
1366
+ setupApi([]);
1367
+ render(
1368
+ <LayersPreview
1369
+ layers={[makeLayer(noRestrictions())]}
1370
+ allLayerUsers={makeLayerUsers([USER_A_ID, USER_B_ID])}
1371
+ onCallDutyPolicyScheduleId={objectId(SCHEDULE_ID)}
1372
+ />,
1373
+ );
1374
+ await waitForOverridesResolved();
1375
+
1376
+ /*
1377
+ * With no schedule zone, "View as" falls back to the user's own zone. The
1378
+ * grid has to show New York's 21:18 the evening before, not India's 06:48.
1379
+ */
1380
+ expect(screen.getByTestId("view-as-new-york")).toHaveAttribute(
1381
+ "data-value",
1382
+ "America/New_York",
1383
+ );
1384
+ expect(onGrid(getCalendarProps().getNow!())).toBe("2026-09-22 21:18:00");
1385
+ expect(onGrid(getCalendarProps().defaultDate!).slice(0, 10)).toBe(
1386
+ "2026-09-22",
1387
+ );
1388
+ });
1389
+ });