@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,1611 @@
1
+ /** @timezone Asia/Singapore */
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
+ act,
14
+ cleanup,
15
+ fireEvent,
16
+ render,
17
+ RenderResult,
18
+ } from "@testing-library/react";
19
+ import fs from "fs";
20
+ import moment from "moment-timezone";
21
+ import path from "path";
22
+ import React from "react";
23
+ import { DateLocalizer, DateRange, momentLocalizer } from "react-big-calendar";
24
+ import CalendarElement, {
25
+ ComponentProps,
26
+ DefaultCalendarView,
27
+ calendarLocalizer,
28
+ formatEventTimeRangeStart,
29
+ } from "../../../../UI/Components/Calendar/Calendar";
30
+ import CalendarEvent from "../../../../Types/Calendar/CalendarEvent";
31
+ import { StyleRule, parseTopLevelRules } from "../../Styles/ThemeStylesheet";
32
+
33
+ /*
34
+ * The on-call schedule preview draws its shifts with this calendar, and the
35
+ * week view is where people read "who is on call, and when does it hand off".
36
+ * Every test here renders the REAL component (react-big-calendar included) and
37
+ * reads what it put in the DOM, because each bug it pins was a gap between the
38
+ * data being right and the grid drawing it wrong:
39
+ *
40
+ * - a shift ending at midnight was drawn a second time on the next day as a
41
+ * thin "– 12:00 AM" sliver that squeezed the real midnight shift into half
42
+ * the column, and the first fix for that made a shift from 11:59 PM to
43
+ * midnight vanish from both days;
44
+ * - a 5:02 PM hand-off was drawn with a gap, because override blocks were
45
+ * taken out of react-big-calendar's absolute positioning;
46
+ * - a rotation handing off at midnight left the grid entirely and became bars
47
+ * in the all-day strip;
48
+ * - uncovered hours were painted as solid blue blocks, like a real shift;
49
+ * - the red "now" line used the browser clock on a grid shown in another zone
50
+ * and disappeared into red shifts;
51
+ * - the day did not fit without scrolling, and the clip that kept it that way
52
+ * let a focused block scroll its column's blocks off the hour lines.
53
+ *
54
+ * The timezone is pinned to the one the report came from. Singapore has no
55
+ * DST, so every day in these tests is exactly 1440 minutes long.
56
+ */
57
+
58
+ const SEPTEMBER: number = 8; // Date months are zero-based.
59
+
60
+ // A local (Asia/Singapore) wall-clock time in September 2026.
61
+ const sep: (
62
+ day: number,
63
+ hour: number,
64
+ minute?: number,
65
+ second?: number,
66
+ ) => Date = (
67
+ day: number,
68
+ hour: number,
69
+ minute?: number,
70
+ second?: number,
71
+ ): Date => {
72
+ return new Date(2026, SEPTEMBER, day, hour, minute || 0, second || 0);
73
+ };
74
+
75
+ /*
76
+ * September 2026: Sunday 20 to Saturday 26 is the week of 26 Sep, the second
77
+ * date in the report, and Saturday 12 is the first.
78
+ */
79
+ const FRIDAY_25: number = 25;
80
+ const SATURDAY_26: number = 26;
81
+ const SATURDAY_12: number = 12;
82
+
83
+ const MINUTES_PER_DAY: number = 24 * 60;
84
+
85
+ // Where react-big-calendar puts a wall-clock minute, as a percent of the column.
86
+ const percentOfDay: (hour: number, minute: number) => number = (
87
+ hour: number,
88
+ minute: number,
89
+ ): number => {
90
+ return ((hour * 60 + minute) / MINUTES_PER_DAY) * 100;
91
+ };
92
+
93
+ const OVERRIDE_CLASS: string = "oneuptime-calendar-event--override";
94
+
95
+ let nextEventId: number = 1;
96
+
97
+ const makeEvent: (
98
+ title: string,
99
+ start: Date,
100
+ end: Date,
101
+ extra?: Partial<CalendarEvent>,
102
+ ) => CalendarEvent = (
103
+ title: string,
104
+ start: Date,
105
+ end: Date,
106
+ extra?: Partial<CalendarEvent>,
107
+ ): CalendarEvent => {
108
+ return {
109
+ id: nextEventId++,
110
+ title,
111
+ start,
112
+ end,
113
+ ...(extra || {}),
114
+ };
115
+ };
116
+
117
+ const renderWeek: (
118
+ props: Partial<ComponentProps> & { events: Array<CalendarEvent> },
119
+ ) => RenderResult = (
120
+ props: Partial<ComponentProps> & { events: Array<CalendarEvent> },
121
+ ): RenderResult => {
122
+ return render(
123
+ <CalendarElement
124
+ defaultCalendarView={DefaultCalendarView.Week}
125
+ defaultDate={sep(SATURDAY_26, 12)}
126
+ onRangeChange={(): void => {
127
+ // The tests never navigate.
128
+ }}
129
+ {...props}
130
+ />,
131
+ );
132
+ };
133
+
134
+ const getWrapper: (container: HTMLElement) => HTMLElement = (
135
+ container: HTMLElement,
136
+ ): HTMLElement => {
137
+ const wrapper: HTMLElement | null = container.querySelector<HTMLElement>(
138
+ ".oneuptime-calendar",
139
+ );
140
+
141
+ if (!wrapper) {
142
+ throw new Error("The calendar wrapper was not rendered");
143
+ }
144
+
145
+ return wrapper;
146
+ };
147
+
148
+ const getDayColumns: (container: HTMLElement) => Array<HTMLElement> = (
149
+ container: HTMLElement,
150
+ ): Array<HTMLElement> => {
151
+ return Array.from(
152
+ container.querySelectorAll<HTMLElement>(".rbc-time-content .rbc-day-slot"),
153
+ );
154
+ };
155
+
156
+ const getDayHeaders: (container: HTMLElement) => Array<HTMLElement> = (
157
+ container: HTMLElement,
158
+ ): Array<HTMLElement> => {
159
+ return Array.from(
160
+ container.querySelectorAll<HTMLElement>(
161
+ ".rbc-time-header-cell .rbc-header",
162
+ ),
163
+ );
164
+ };
165
+
166
+ /*
167
+ * Where a date sits in the week, found through its header ("26 Sat") rather
168
+ * than assumed, so the tests do not depend on which weekday the locale starts on.
169
+ */
170
+ const getDayIndex: (container: HTMLElement, date: Date) => number = (
171
+ container: HTMLElement,
172
+ date: Date,
173
+ ): number => {
174
+ const headers: Array<HTMLElement> = getDayHeaders(container);
175
+
176
+ expect(headers).toHaveLength(7);
177
+ expect(getDayColumns(container)).toHaveLength(7);
178
+
179
+ const label: string = moment(date).format("DD ddd");
180
+ const index: number = headers.findIndex((header: HTMLElement): boolean => {
181
+ return header.textContent === label;
182
+ });
183
+
184
+ if (index === -1) {
185
+ throw new Error(`No day column headed "${label}"`);
186
+ }
187
+
188
+ return index;
189
+ };
190
+
191
+ const getDayColumn: (container: HTMLElement, date: Date) => HTMLElement = (
192
+ container: HTMLElement,
193
+ date: Date,
194
+ ): HTMLElement => {
195
+ return getDayColumns(container)[getDayIndex(container, date)]!;
196
+ };
197
+
198
+ const getDayHeader: (container: HTMLElement, date: Date) => HTMLElement = (
199
+ container: HTMLElement,
200
+ date: Date,
201
+ ): HTMLElement => {
202
+ return getDayHeaders(container)[getDayIndex(container, date)]!;
203
+ };
204
+
205
+ const getBlocks: (scope: Element) => Array<HTMLElement> = (
206
+ scope: Element,
207
+ ): Array<HTMLElement> => {
208
+ return Array.from(scope.querySelectorAll<HTMLElement>(".rbc-event"));
209
+ };
210
+
211
+ const titleOf: (block: Element) => string = (block: Element): string => {
212
+ return block.querySelector(".rbc-event-content")?.textContent || "";
213
+ };
214
+
215
+ const labelOf: (block: Element) => string = (block: Element): string => {
216
+ return block.querySelector(".rbc-event-label")?.textContent || "";
217
+ };
218
+
219
+ const getBlock: (scope: Element, title: string) => HTMLElement = (
220
+ scope: Element,
221
+ title: string,
222
+ ): HTMLElement => {
223
+ const block: HTMLElement | undefined = getBlocks(scope).find(
224
+ (candidate: HTMLElement): boolean => {
225
+ return titleOf(candidate) === title;
226
+ },
227
+ );
228
+
229
+ if (!block) {
230
+ throw new Error(`No block titled "${title}"`);
231
+ }
232
+
233
+ return block;
234
+ };
235
+
236
+ // react-big-calendar writes top/height/left/width as "<number>%".
237
+ const percent: (value: string) => number = (value: string): number => {
238
+ expect(value).toMatch(/%$/);
239
+ return parseFloat(value);
240
+ };
241
+
242
+ interface BlockBox {
243
+ top: number;
244
+ height: number;
245
+ left: number;
246
+ width: number;
247
+ }
248
+
249
+ const boxOf: (block: HTMLElement) => BlockBox = (
250
+ block: HTMLElement,
251
+ ): BlockBox => {
252
+ return {
253
+ top: percent(block.style.top),
254
+ height: percent(block.style.height),
255
+ left: percent(block.style.left),
256
+ width: percent(block.style.width),
257
+ };
258
+ };
259
+
260
+ /*
261
+ * 12 Sep: Alex's shift ends at 5:02 PM and two overrides follow it, back to
262
+ * back. Overrides carry the override class and the overridden person's accent.
263
+ */
264
+ const buildSaturday12: () => Array<CalendarEvent> =
265
+ (): Array<CalendarEvent> => {
266
+ return [
267
+ makeEvent("Alex", sep(SATURDAY_12, 0), sep(SATURDAY_12, 17, 2)),
268
+ makeEvent(
269
+ "Blair (covering Alex)",
270
+ sep(SATURDAY_12, 17, 2),
271
+ sep(SATURDAY_12, 21, 26),
272
+ {
273
+ color: "#dc2626",
274
+ accentColor: "#16a34a",
275
+ className: OVERRIDE_CLASS,
276
+ },
277
+ ),
278
+ makeEvent(
279
+ "Casey (covering Alex)",
280
+ sep(SATURDAY_12, 21, 26),
281
+ sep(SATURDAY_12, 23, 30),
282
+ {
283
+ color: "#7c3aed",
284
+ accentColor: "#16a34a",
285
+ className: OVERRIDE_CLASS,
286
+ },
287
+ ),
288
+ ];
289
+ };
290
+
291
+ /*
292
+ * rbc's DayColumn arms a 60s timer for the "now" line and reads the clock for
293
+ * the highlighted day, so every test runs on a fixed clock: Wednesday 23
294
+ * September 2026, 10:00 in Singapore, inside the week most tests show.
295
+ */
296
+ beforeEach(() => {
297
+ jest.useFakeTimers();
298
+ jest.setSystemTime(sep(23, 10));
299
+ });
300
+
301
+ afterEach(() => {
302
+ cleanup();
303
+ jest.clearAllTimers();
304
+ jest.useRealTimers();
305
+ });
306
+
307
+ describe("Calendar week view: a shift that ends at midnight (26 Sep)", () => {
308
+ /*
309
+ * The report: Friday's last shift runs 7:26 PM to midnight and Saturday's
310
+ * first starts at midnight. react-big-calendar handed the Friday shift to
311
+ * Saturday's column too (its day filter is inclusive), drew it as a 20px
312
+ * "– 12:00 AM" sliver at the top, and put it side by side with the real
313
+ * midnight shift, so the two looked like they overlapped.
314
+ */
315
+ const buildHandOff: (handOff: Date) => Array<CalendarEvent> = (
316
+ handOff: Date,
317
+ ): Array<CalendarEvent> => {
318
+ return [
319
+ makeEvent("Alex", sep(FRIDAY_25, 19, 26), handOff),
320
+ makeEvent("Blair", handOff, sep(SATURDAY_26, 9, 52)),
321
+ makeEvent("Casey", sep(SATURDAY_26, 9, 52), sep(SATURDAY_26, 19, 26)),
322
+ ];
323
+ };
324
+
325
+ test("the shift ending at midnight is drawn only on Friday, to the bottom of the column, with its end time", () => {
326
+ const { container } = renderWeek({
327
+ events: buildHandOff(sep(SATURDAY_26, 0)),
328
+ });
329
+
330
+ const friday: HTMLElement = getDayColumn(container, sep(FRIDAY_25, 0));
331
+ const fridayBlocks: Array<HTMLElement> = getBlocks(friday);
332
+
333
+ expect(fridayBlocks.map(titleOf)).toEqual(["Alex"]);
334
+
335
+ const alex: HTMLElement = fridayBlocks[0]!;
336
+ const box: BlockBox = boxOf(alex);
337
+
338
+ expect(box.top).toBeCloseTo(percentOfDay(19, 26), 6);
339
+ // The column ends at 23:59, so the block reaches the last minute of the day.
340
+ expect(box.top + box.height).toBeCloseTo(percentOfDay(23, 59), 6);
341
+ expect(box.left).toBe(0);
342
+ expect(box.width).toBe(100);
343
+
344
+ // Not "7:26 PM –", which reads as "continues tomorrow".
345
+ expect(labelOf(alex)).toBe("7:26 PM – 12:00 AM");
346
+ });
347
+
348
+ test("Saturday shows only its own shifts, the midnight one at full width from the top", () => {
349
+ const { container } = renderWeek({
350
+ events: buildHandOff(sep(SATURDAY_26, 0)),
351
+ });
352
+
353
+ const saturday: HTMLElement = getDayColumn(container, sep(SATURDAY_26, 0));
354
+
355
+ // No sliver of Friday's shift in Saturday's column.
356
+ expect(getBlocks(saturday).map(titleOf)).toEqual(["Blair", "Casey"]);
357
+
358
+ const blair: BlockBox = boxOf(getBlock(saturday, "Blair"));
359
+ const casey: BlockBox = boxOf(getBlock(saturday, "Casey"));
360
+
361
+ expect(blair.top).toBe(0);
362
+ expect(blair.left).toBe(0);
363
+ expect(blair.width).toBe(100);
364
+ expect(blair.height).toBeCloseTo(percentOfDay(9, 52), 6);
365
+ expect(labelOf(getBlock(saturday, "Blair"))).toBe("12:00 AM – 9:52 AM");
366
+
367
+ // The 9:52 AM hand-off is back to back too.
368
+ expect(casey.top).toBeCloseTo(blair.top + blair.height, 6);
369
+ expect(casey.width).toBe(100);
370
+ });
371
+
372
+ test("no block anywhere in the week carries a bare '– 12:00 AM' label", () => {
373
+ const { container } = renderWeek({
374
+ events: buildHandOff(sep(SATURDAY_26, 0)),
375
+ });
376
+
377
+ const labels: Array<string> = getBlocks(container).map(labelOf);
378
+
379
+ expect(labels.length).toBeGreaterThan(0);
380
+
381
+ // A label that starts with the dash is a block that only ends in its column.
382
+ for (const label of labels) {
383
+ expect(label.trim().startsWith("–")).toBe(false);
384
+ }
385
+ });
386
+
387
+ test("a hand-off a few seconds after midnight is still treated as one at midnight", () => {
388
+ /*
389
+ * The grid works in whole minutes. A rotation computed to the second can
390
+ * hand off at 00:00:30, which must not bring the Saturday sliver back.
391
+ */
392
+ const { container } = renderWeek({
393
+ events: buildHandOff(sep(SATURDAY_26, 0, 0, 30)),
394
+ });
395
+
396
+ const friday: HTMLElement = getDayColumn(container, sep(FRIDAY_25, 0));
397
+ const saturday: HTMLElement = getDayColumn(container, sep(SATURDAY_26, 0));
398
+
399
+ expect(getBlocks(friday).map(titleOf)).toEqual(["Alex"]);
400
+ expect(labelOf(getBlock(friday, "Alex"))).toBe("7:26 PM – 12:00 AM");
401
+
402
+ expect(getBlocks(saturday).map(titleOf)).toEqual(["Blair", "Casey"]);
403
+ expect(boxOf(getBlock(saturday, "Blair")).width).toBe(100);
404
+ expect(boxOf(getBlock(saturday, "Blair")).left).toBe(0);
405
+ });
406
+
407
+ test("a shift that really runs past midnight is still drawn on both days", () => {
408
+ // Dropping slivers must not drop the next-day part of an overnight shift.
409
+ const { container } = renderWeek({
410
+ events: [makeEvent("Night", sep(FRIDAY_25, 22), sep(SATURDAY_26, 6))],
411
+ });
412
+
413
+ const friday: HTMLElement = getDayColumn(container, sep(FRIDAY_25, 0));
414
+ const saturday: HTMLElement = getDayColumn(container, sep(SATURDAY_26, 0));
415
+
416
+ expect(labelOf(getBlock(friday, "Night"))).toBe("10:00 PM – ");
417
+ expect(labelOf(getBlock(saturday, "Night"))).toBe(" – 6:00 AM");
418
+
419
+ const morning: BlockBox = boxOf(getBlock(saturday, "Night"));
420
+
421
+ expect(morning.top).toBe(0);
422
+ expect(morning.height).toBeCloseTo(percentOfDay(6, 0), 6);
423
+ });
424
+
425
+ /*
426
+ * Dropping the sliver must not drop a block from the day it starts in. A
427
+ * block with less than a minute left before midnight has no height in its
428
+ * own column either, and the first version of the fix dropped it there
429
+ * too, so an 11:59 PM hand-off to midnight was drawn on neither day.
430
+ */
431
+ test.each([
432
+ { name: "11:59 PM", second: 0 },
433
+ { name: "11:59:30 PM", second: 30 },
434
+ ])(
435
+ "a block from $name to midnight is drawn exactly once, at the bottom of the day it starts in",
436
+ ({ second }: { second: number }) => {
437
+ const { container } = renderWeek({
438
+ events: [
439
+ makeEvent(
440
+ "Last minute",
441
+ sep(FRIDAY_25, 23, 59, second),
442
+ sep(SATURDAY_26, 0),
443
+ ),
444
+ ],
445
+ });
446
+
447
+ // Once in the whole week, all-day strip included.
448
+ const drawn: Array<HTMLElement> = getBlocks(container).filter(
449
+ (block: HTMLElement): boolean => {
450
+ return titleOf(block) === "Last minute";
451
+ },
452
+ );
453
+
454
+ expect(drawn).toHaveLength(1);
455
+
456
+ const friday: HTMLElement = getDayColumn(container, sep(FRIDAY_25, 0));
457
+ const saturday: HTMLElement = getDayColumn(
458
+ container,
459
+ sep(SATURDAY_26, 0),
460
+ );
461
+
462
+ expect(getBlocks(friday)).toEqual(drawn);
463
+ expect(getBlocks(saturday)).toHaveLength(0);
464
+
465
+ expect(boxOf(drawn[0]!).top).toBeCloseTo(percentOfDay(23, 59), 6);
466
+ expect(labelOf(drawn[0]!)).toBe("11:59 PM – 12:00 AM");
467
+ },
468
+ );
469
+ });
470
+
471
+ describe("Calendar week view: a hand-off at 5:02 PM (12 Sep)", () => {
472
+ /*
473
+ * The report: one shift ends at 5:02 PM, the next begins at 5:02 PM, but the
474
+ * grid showed a gap between them. The later blocks were overrides, whose
475
+ * stylesheet rule took them out of rbc's absolute positioning (see the
476
+ * stylesheet tests below, which place the blocks the way a browser would).
477
+ * Here the inline geometry rbc receives from the layout is pinned: full
478
+ * width, and each block starts exactly where the one before it ends.
479
+ */
480
+ test("consecutive shifts are full width and meet at the hand-off minute", () => {
481
+ const { container } = renderWeek({
482
+ defaultDate: sep(SATURDAY_12, 12),
483
+ events: buildSaturday12(),
484
+ });
485
+
486
+ const saturday: HTMLElement = getDayColumn(container, sep(SATURDAY_12, 0));
487
+
488
+ expect(getBlocks(saturday).map(titleOf)).toEqual([
489
+ "Alex",
490
+ "Blair (covering Alex)",
491
+ "Casey (covering Alex)",
492
+ ]);
493
+
494
+ const alex: BlockBox = boxOf(getBlock(saturday, "Alex"));
495
+ const blair: BlockBox = boxOf(getBlock(saturday, "Blair (covering Alex)"));
496
+ const casey: BlockBox = boxOf(getBlock(saturday, "Casey (covering Alex)"));
497
+
498
+ for (const box of [alex, blair, casey]) {
499
+ expect(box.left).toBe(0);
500
+ expect(box.width).toBe(100);
501
+ }
502
+
503
+ expect(alex.top).toBe(0);
504
+ expect(blair.top).toBeCloseTo(percentOfDay(17, 2), 6);
505
+ expect(blair.top).toBeCloseTo(alex.top + alex.height, 6);
506
+ expect(casey.top).toBeCloseTo(percentOfDay(21, 26), 6);
507
+ expect(casey.top).toBeCloseTo(blair.top + blair.height, 6);
508
+ });
509
+
510
+ test("the override block carries its class and the overridden person's colour as a custom property", () => {
511
+ /*
512
+ * The stripe on an override is drawn by the stylesheet from
513
+ * --oneuptime-event-accent; if the property or the class stops reaching
514
+ * the grid block, an override looks like an ordinary shift.
515
+ */
516
+ const { container } = renderWeek({
517
+ defaultDate: sep(SATURDAY_12, 12),
518
+ events: buildSaturday12(),
519
+ });
520
+
521
+ const saturday: HTMLElement = getDayColumn(container, sep(SATURDAY_12, 0));
522
+ const blair: HTMLElement = getBlock(saturday, "Blair (covering Alex)");
523
+ const alex: HTMLElement = getBlock(saturday, "Alex");
524
+
525
+ expect(blair).toHaveClass("rbc-event");
526
+ expect(blair).toHaveClass(OVERRIDE_CLASS);
527
+ expect(blair.style.getPropertyValue("--oneuptime-event-accent")).toBe(
528
+ "#16a34a",
529
+ );
530
+ // The block itself is in the substitute's colour.
531
+ expect(blair.style.backgroundColor).toBe("rgb(220, 38, 38)");
532
+
533
+ expect(alex).not.toHaveClass(OVERRIDE_CLASS);
534
+ expect(alex.style.getPropertyValue("--oneuptime-event-accent")).toBe("");
535
+ });
536
+
537
+ test("blocks that really overlap still share the column side by side", () => {
538
+ /*
539
+ * The layout keeps back-to-back shifts at full width, but two people who
540
+ * really are on call at once must stay visible as two lanes.
541
+ */
542
+ const { container } = renderWeek({
543
+ events: [
544
+ makeEvent("Long", sep(23, 9), sep(23, 12)),
545
+ makeEvent("Short", sep(23, 10), sep(23, 11)),
546
+ makeEvent("Evening", sep(23, 18), sep(23, 20)),
547
+ ],
548
+ });
549
+
550
+ const wednesday: HTMLElement = getDayColumn(container, sep(23, 0));
551
+ const long: BlockBox = boxOf(getBlock(wednesday, "Long"));
552
+ const short: BlockBox = boxOf(getBlock(wednesday, "Short"));
553
+ const evening: BlockBox = boxOf(getBlock(wednesday, "Evening"));
554
+
555
+ expect(long.left).toBe(0);
556
+ expect(long.width).toBe(50);
557
+ expect(short.left).toBe(50);
558
+ expect(short.width).toBe(50);
559
+
560
+ // An overlap in the morning does not narrow the evening.
561
+ expect(evening.left).toBe(0);
562
+ expect(evening.width).toBe(100);
563
+ });
564
+ });
565
+
566
+ describe("Calendar week view: a rotation that hands off at midnight", () => {
567
+ /*
568
+ * A daily rotation handing off at 00:00 gives blocks whose start and end are
569
+ * both exactly midnight. react-big-calendar calls that shape all-day and
570
+ * moved every such shift out of the grid into the strip above it, leaving
571
+ * the week looking empty.
572
+ */
573
+ const PEOPLE: Array<string> = [
574
+ "Sun person",
575
+ "Mon person",
576
+ "Tue person",
577
+ "Wed person",
578
+ "Thu person",
579
+ "Fri person",
580
+ "Sat person",
581
+ ];
582
+
583
+ const buildRotation: () => Array<CalendarEvent> =
584
+ (): Array<CalendarEvent> => {
585
+ return PEOPLE.map((person: string, index: number): CalendarEvent => {
586
+ return makeEvent(person, sep(20 + index, 0), sep(21 + index, 0));
587
+ });
588
+ };
589
+
590
+ test("every shift is drawn in its own day column, none in the all-day strip", () => {
591
+ const { container } = renderWeek({ events: buildRotation() });
592
+
593
+ expect(
594
+ container.querySelectorAll(".rbc-allday-cell .rbc-event"),
595
+ ).toHaveLength(0);
596
+
597
+ PEOPLE.forEach((person: string, index: number) => {
598
+ const column: HTMLElement = getDayColumn(container, sep(20 + index, 0));
599
+ const blocks: Array<HTMLElement> = getBlocks(column);
600
+
601
+ // Only that day's person: yesterday's shift ends at this midnight.
602
+ expect(blocks.map(titleOf)).toEqual([person]);
603
+
604
+ const box: BlockBox = boxOf(blocks[0]!);
605
+
606
+ expect(box.top).toBe(0);
607
+ expect(box.top + box.height).toBeCloseTo(percentOfDay(23, 59), 6);
608
+ expect(box.left).toBe(0);
609
+ expect(box.width).toBe(100);
610
+ expect(labelOf(blocks[0]!)).toBe("12:00 AM – 12:00 AM");
611
+ });
612
+ });
613
+
614
+ test("the calendar's localizer never calls a midnight-to-midnight block date-only", () => {
615
+ // react-big-calendar's own moment localizer does: that is the all-day test it applies.
616
+ expect(
617
+ momentLocalizer(moment).startAndEndAreDateOnly(sep(23, 0), sep(24, 0)),
618
+ ).toBe(true);
619
+
620
+ expect(
621
+ calendarLocalizer.startAndEndAreDateOnly(sep(23, 0), sep(24, 0)),
622
+ ).toBe(false);
623
+ // Nor a block spanning several whole days.
624
+ expect(
625
+ calendarLocalizer.startAndEndAreDateOnly(sep(20, 0), sep(27, 0)),
626
+ ).toBe(false);
627
+ });
628
+
629
+ test("without all-day events the wrapper asks the stylesheet to hide the empty strip", () => {
630
+ const { container } = renderWeek({ events: buildRotation() });
631
+
632
+ expect(getWrapper(container)).toHaveClass("oneuptime-calendar");
633
+ expect(getWrapper(container)).toHaveClass("oneuptime-calendar--no-all-day");
634
+ });
635
+
636
+ test("an event marked allDay still goes to the all-day strip, which then stays visible", () => {
637
+ const { container } = renderWeek({
638
+ events: [
639
+ ...buildRotation(),
640
+ makeEvent("Company holiday", sep(23, 0), sep(24, 0), { allDay: true }),
641
+ ],
642
+ });
643
+
644
+ expect(getWrapper(container)).not.toHaveClass(
645
+ "oneuptime-calendar--no-all-day",
646
+ );
647
+
648
+ const allDayBlocks: Array<HTMLElement> = getBlocks(
649
+ container.querySelector(".rbc-allday-cell")!,
650
+ );
651
+
652
+ expect(allDayBlocks.map(titleOf)).toEqual(["Company holiday"]);
653
+
654
+ // The rotation itself stays in the grid.
655
+ const wednesday: HTMLElement = getDayColumn(container, sep(23, 0));
656
+
657
+ expect(getBlocks(wednesday).map(titleOf)).toEqual(["Wed person"]);
658
+ });
659
+ });
660
+
661
+ describe("Calendar colours: shifts and uncovered hours", () => {
662
+ /*
663
+ * Uncovered hours are passed as background events and drawn by the
664
+ * stylesheet as a pale hatch. The block styling used to run over them too
665
+ * and paint them solid Blue500, which is one of the colours a real person's
666
+ * shift can have.
667
+ */
668
+ const BLUE_500: string = "rgb(59, 130, 246)";
669
+
670
+ test("background events get no block colour unless the caller gave one", () => {
671
+ const uncovered: CalendarEvent = makeEvent(
672
+ "No one on call",
673
+ sep(23, 0),
674
+ sep(23, 9),
675
+ );
676
+ const colouredGap: CalendarEvent = makeEvent(
677
+ "Tinted gap",
678
+ sep(23, 21),
679
+ sep(23, 23),
680
+ { color: "#fbbf24", className: "custom-gap" },
681
+ );
682
+
683
+ const { container } = renderWeek({
684
+ events: [
685
+ makeEvent("Alex", sep(23, 9), sep(23, 21), { color: "#1e3a8a" }),
686
+ ],
687
+ backgroundEvents: [uncovered, colouredGap],
688
+ });
689
+
690
+ const wednesday: HTMLElement = getDayColumn(container, sep(23, 0));
691
+ const backgrounds: Array<HTMLElement> = Array.from(
692
+ wednesday.querySelectorAll<HTMLElement>(".rbc-background-event"),
693
+ );
694
+
695
+ expect(backgrounds.map(titleOf)).toEqual(["No one on call", "Tinted gap"]);
696
+
697
+ const plain: HTMLElement = backgrounds[0]!;
698
+
699
+ expect(plain.style.backgroundColor).not.toBe(BLUE_500);
700
+ expect(plain.style.backgroundColor).toBe("");
701
+ expect(plain.style.color).toBe("");
702
+ /*
703
+ * No block styling at all: an inline border-radius or display: block
704
+ * would beat the stylesheet's flat band. Only rbc's own geometry is left.
705
+ */
706
+ expect(Array.from(plain.style).sort()).toEqual([
707
+ "height",
708
+ "left",
709
+ "top",
710
+ "width",
711
+ ]);
712
+ // Still a background band, not a block: the hatch comes from this class.
713
+ expect(plain).toHaveClass("rbc-background-event");
714
+ expect(plain).not.toHaveClass("rbc-event");
715
+
716
+ const tinted: HTMLElement = backgrounds[1]!;
717
+
718
+ expect(tinted.style.backgroundColor).toBe("rgb(251, 191, 36)");
719
+ expect(tinted.style.color).toBe("");
720
+ expect(tinted).toHaveClass("rbc-background-event");
721
+ expect(tinted).toHaveClass("custom-gap");
722
+ });
723
+
724
+ test("shifts keep their colour and a readable text colour", () => {
725
+ // A background event is passed too: telling bands apart must not unstyle shifts.
726
+ const { container } = renderWeek({
727
+ events: [
728
+ makeEvent("Dark", sep(23, 0), sep(23, 6), { color: "#1e3a8a" }),
729
+ makeEvent("Light", sep(23, 6), sep(23, 12), { color: "#fde047" }),
730
+ makeEvent("Default", sep(23, 12), sep(23, 18)),
731
+ makeEvent("Explicit text", sep(23, 18), sep(23, 23), {
732
+ color: "#1e3a8a",
733
+ textColor: "#000000",
734
+ }),
735
+ ],
736
+ backgroundEvents: [makeEvent("Gap", sep(23, 23), sep(23, 23, 30))],
737
+ });
738
+
739
+ const wednesday: HTMLElement = getDayColumn(container, sep(23, 0));
740
+
741
+ const dark: HTMLElement = getBlock(wednesday, "Dark");
742
+ expect(dark.style.backgroundColor).toBe("rgb(30, 58, 138)");
743
+ expect(dark.style.color).toBe("rgb(255, 255, 255)");
744
+
745
+ const light: HTMLElement = getBlock(wednesday, "Light");
746
+ expect(light.style.backgroundColor).toBe("rgb(253, 224, 71)");
747
+ expect(light.style.color).toBe("rgb(17, 24, 39)");
748
+
749
+ // A shift without a colour still gets the default block colour.
750
+ const fallback: HTMLElement = getBlock(wednesday, "Default");
751
+ expect(fallback.style.backgroundColor).toBe(BLUE_500);
752
+ expect(fallback.style.color).toBe("rgb(255, 255, 255)");
753
+
754
+ const explicit: HTMLElement = getBlock(wednesday, "Explicit text");
755
+ expect(explicit.style.color).toBe("rgb(0, 0, 0)");
756
+ });
757
+ });
758
+
759
+ describe("Calendar current time: getNow", () => {
760
+ /*
761
+ * The schedule preview shifts every event into the schedule's display zone.
762
+ * The grid's "now" came from the browser clock, so with the browser in
763
+ * another zone the red line and the highlighted day were drawn at the
764
+ * browser's time on a grid showing the schedule's. getNow lets the caller
765
+ * shift "now" the same way as the events.
766
+ */
767
+ const MONDAY_21_0900: Date = sep(21, 9);
768
+ const WEDNESDAY_23_1430: Date = sep(23, 14, 30);
769
+
770
+ const indicatorTop: (column: HTMLElement) => number = (
771
+ column: HTMLElement,
772
+ ): number => {
773
+ const indicator: HTMLElement | null = column.querySelector<HTMLElement>(
774
+ ".rbc-current-time-indicator",
775
+ );
776
+
777
+ if (!indicator) {
778
+ throw new Error("The current-time line was not drawn in this column");
779
+ }
780
+
781
+ return percent(indicator.style.top);
782
+ };
783
+
784
+ test("the day and line come from getNow, not from the system clock", () => {
785
+ jest.setSystemTime(MONDAY_21_0900);
786
+
787
+ // Reads the clock on every call, shifted, the way the schedule preview does.
788
+ const offset: number =
789
+ WEDNESDAY_23_1430.getTime() - MONDAY_21_0900.getTime();
790
+
791
+ const { container } = renderWeek({
792
+ defaultDate: sep(23, 12),
793
+ events: [],
794
+ getNow: (): Date => {
795
+ return new Date(Date.now() + offset);
796
+ },
797
+ });
798
+
799
+ const monday: HTMLElement = getDayColumn(container, sep(21, 0));
800
+ const wednesday: HTMLElement = getDayColumn(container, sep(23, 0));
801
+
802
+ expect(wednesday).toHaveClass("rbc-today");
803
+ expect(wednesday).toHaveClass("rbc-now");
804
+ expect(monday).not.toHaveClass("rbc-today");
805
+
806
+ // The day header is highlighted from the same "now".
807
+ expect(getDayHeader(container, sep(23, 0))).toHaveClass("rbc-today");
808
+ expect(getDayHeader(container, sep(21, 0))).not.toHaveClass("rbc-today");
809
+
810
+ expect(
811
+ container.querySelectorAll(".rbc-current-time-indicator"),
812
+ ).toHaveLength(1);
813
+ expect(indicatorTop(wednesday)).toBeCloseTo(percentOfDay(14, 30), 6);
814
+
815
+ // A minute later the line has moved with getNow's clock.
816
+ act(() => {
817
+ jest.advanceTimersByTime(60 * 1000);
818
+ });
819
+
820
+ expect(indicatorTop(wednesday)).toBeCloseTo(percentOfDay(14, 31), 6);
821
+ });
822
+
823
+ test("without getNow the system clock decides", () => {
824
+ jest.setSystemTime(MONDAY_21_0900);
825
+
826
+ const { container } = renderWeek({
827
+ defaultDate: sep(23, 12),
828
+ events: [],
829
+ });
830
+
831
+ const monday: HTMLElement = getDayColumn(container, sep(21, 0));
832
+ const wednesday: HTMLElement = getDayColumn(container, sep(23, 0));
833
+
834
+ expect(monday).toHaveClass("rbc-today");
835
+ expect(wednesday).not.toHaveClass("rbc-today");
836
+ expect(getDayHeader(container, sep(21, 0))).toHaveClass("rbc-today");
837
+ expect(indicatorTop(monday)).toBeCloseTo(percentOfDay(9, 0), 6);
838
+ });
839
+ });
840
+
841
+ describe("formatEventTimeRangeStart", () => {
842
+ /*
843
+ * The label of a block that starts in a column and runs past its end.
844
+ * react-big-calendar writes "7:26 PM – ", meaning "continues tomorrow". A
845
+ * block that ends exactly at the midnight closing its column does not
846
+ * continue (tomorrow has nothing of it to show), so it gets its end time.
847
+ */
848
+ const FRIDAY_1926: Date = sep(FRIDAY_25, 19, 26);
849
+ const localizer: DateLocalizer = momentLocalizer(moment);
850
+
851
+ interface FormatCase {
852
+ name: string;
853
+ end: Date;
854
+ expected: string;
855
+ }
856
+
857
+ const CASES: Array<FormatCase> = [
858
+ {
859
+ name: "ends exactly at the following midnight",
860
+ end: sep(SATURDAY_26, 0),
861
+ expected: "7:26 PM – 12:00 AM",
862
+ },
863
+ {
864
+ name: "ends 30 seconds after the following midnight (same minute)",
865
+ end: sep(SATURDAY_26, 0, 0, 30),
866
+ expected: "7:26 PM – 12:00 AM",
867
+ },
868
+ {
869
+ name: "ends one minute after the following midnight",
870
+ end: sep(SATURDAY_26, 0, 1),
871
+ expected: "7:26 PM – ",
872
+ },
873
+ {
874
+ name: "ends in the middle of the next day",
875
+ end: sep(SATURDAY_26, 9, 52),
876
+ expected: "7:26 PM – ",
877
+ },
878
+ {
879
+ name: "ends at the midnight two days later",
880
+ end: sep(27, 0),
881
+ expected: "7:26 PM – ",
882
+ },
883
+ ];
884
+
885
+ test.each(CASES)(
886
+ "without a localizer: $name",
887
+ ({ end, expected }: FormatCase) => {
888
+ expect(formatEventTimeRangeStart({ start: FRIDAY_1926, end })).toBe(
889
+ expected,
890
+ );
891
+ },
892
+ );
893
+
894
+ test.each(CASES)(
895
+ "with react-big-calendar's moment localizer: $name",
896
+ ({ end, expected }: FormatCase) => {
897
+ expect(
898
+ formatEventTimeRangeStart({ start: FRIDAY_1926, end }, "en", localizer),
899
+ ).toBe(expected);
900
+ },
901
+ );
902
+
903
+ test("a whole day from midnight to midnight is labelled with both ends", () => {
904
+ expect(
905
+ formatEventTimeRangeStart({
906
+ start: sep(FRIDAY_25, 0),
907
+ end: sep(SATURDAY_26, 0),
908
+ }),
909
+ ).toBe("12:00 AM – 12:00 AM");
910
+ });
911
+
912
+ test("times are formatted through the localizer and culture it is given", () => {
913
+ const calls: Array<{
914
+ value: Date;
915
+ format: string;
916
+ culture?: string | undefined;
917
+ }> = [];
918
+
919
+ const recordingLocalizer: DateLocalizer = {
920
+ format: (value: Date, format: string, culture?: string): string => {
921
+ calls.push({ value, format, culture });
922
+ return `<${moment(value).format("HH:mm")}>`;
923
+ },
924
+ } as unknown as DateLocalizer;
925
+
926
+ const range: DateRange = { start: FRIDAY_1926, end: sep(SATURDAY_26, 0) };
927
+
928
+ expect(formatEventTimeRangeStart(range, "en-GB", recordingLocalizer)).toBe(
929
+ "<19:26> – <00:00>",
930
+ );
931
+ expect(calls).toEqual([
932
+ { value: range.start, format: "LT", culture: "en-GB" },
933
+ { value: range.end, format: "LT", culture: "en-GB" },
934
+ ]);
935
+
936
+ expect(
937
+ formatEventTimeRangeStart(
938
+ { start: FRIDAY_1926, end: sep(SATURDAY_26, 9, 52) },
939
+ "en-GB",
940
+ recordingLocalizer,
941
+ ),
942
+ ).toBe("<19:26> – ");
943
+ });
944
+ });
945
+
946
+ describe("Calendar.css", () => {
947
+ /*
948
+ * Three of the reported problems were stylesheet problems, which jsdom does
949
+ * not apply. These tests read the real Calendar.css (and react-big-calendar's
950
+ * own sheet, which it overrides) and check two things: the rule says what it
951
+ * should, and it actually wins the cascade on the elements the component
952
+ * renders, with selectors matched by the DOM and ranked by specificity.
953
+ */
954
+ const CALENDAR_CSS_PATH: string = path.resolve(
955
+ __dirname,
956
+ "../../../../UI/Components/Calendar/Calendar.css",
957
+ );
958
+ const RBC_CSS_PATH: string = path.resolve(
959
+ __dirname,
960
+ "../../../../node_modules/react-big-calendar/lib/css/react-big-calendar.css",
961
+ );
962
+
963
+ const readRules: (file: string) => Array<StyleRule> = (
964
+ file: string,
965
+ ): Array<StyleRule> => {
966
+ // @charset is a statement, not a block; the shared parser expects blocks only.
967
+ return parseTopLevelRules(
968
+ fs.readFileSync(file, "utf8").replace(/@charset[^;]*;/g, ""),
969
+ );
970
+ };
971
+
972
+ const CALENDAR_RULES: Array<StyleRule> = readRules(CALENDAR_CSS_PATH);
973
+ // Calendar.tsx imports rbc's sheet first, then its own.
974
+ const CASCADE: Array<StyleRule> = [
975
+ ...readRules(RBC_CSS_PATH),
976
+ ...CALENDAR_RULES,
977
+ ];
978
+
979
+ const normalizeSelector: (selector: string) => string = (
980
+ selector: string,
981
+ ): string => {
982
+ return selector
983
+ .replace(/\s*>\s*/g, " > ")
984
+ .replace(/\s+/g, " ")
985
+ .trim();
986
+ };
987
+
988
+ // Every declaration Calendar.css makes for exactly this selector, later rules winning.
989
+ const declarationsFor: (selector: string) => Record<string, string> = (
990
+ selector: string,
991
+ ): Record<string, string> => {
992
+ const wanted: string = normalizeSelector(selector);
993
+ const merged: Record<string, string> = {};
994
+
995
+ for (const rule of CALENDAR_RULES) {
996
+ if (rule.selectors.map(normalizeSelector).includes(wanted)) {
997
+ Object.assign(merged, rule.declarations);
998
+ }
999
+ }
1000
+
1001
+ return merged;
1002
+ };
1003
+
1004
+ /*
1005
+ * Every declaration Calendar.css makes for an element carrying `className`,
1006
+ * whatever the rest of the selector says: the rules whose last compound
1007
+ * selector (the element the rule styles) has that class.
1008
+ */
1009
+ const declarationsForSubject: (
1010
+ className: string,
1011
+ ) => Record<string, string> = (className: string): Record<string, string> => {
1012
+ const hasClass: RegExp = new RegExp(`\\.${className}(?![\\w-])`);
1013
+ const merged: Record<string, string> = {};
1014
+
1015
+ for (const rule of CALENDAR_RULES) {
1016
+ const stylesSubject: boolean = rule.selectors.some(
1017
+ (selector: string): boolean => {
1018
+ const compounds: Array<string> =
1019
+ normalizeSelector(selector).split(" ");
1020
+ return hasClass.test(compounds[compounds.length - 1] || "");
1021
+ },
1022
+ );
1023
+
1024
+ if (stylesSubject) {
1025
+ Object.assign(merged, rule.declarations);
1026
+ }
1027
+ }
1028
+
1029
+ return merged;
1030
+ };
1031
+
1032
+ const OVERFLOW_PROPERTIES: Array<string> = [
1033
+ "overflow",
1034
+ "overflow-x",
1035
+ "overflow-y",
1036
+ ];
1037
+
1038
+ // Any of these makes the element a scroll container.
1039
+ const SCROLLING_OVERFLOW: Array<string> = ["hidden", "auto", "scroll"];
1040
+
1041
+ type Specificity = [number, number, number];
1042
+
1043
+ // Enough of the CSS specificity rules for the plain selectors in these sheets.
1044
+ const specificityOf: (selector: string) => Specificity = (
1045
+ selector: string,
1046
+ ): Specificity => {
1047
+ const count: (pattern: RegExp) => number = (pattern: RegExp): number => {
1048
+ return (selector.match(pattern) || []).length;
1049
+ };
1050
+
1051
+ const typesOnly: string = selector
1052
+ .replace(/\[[^\]]*\]/g, " ")
1053
+ .replace(/[.#:][\w-]+/g, " ")
1054
+ .replace(/[()*]/g, " ");
1055
+
1056
+ return [
1057
+ count(/#[\w-]+/g),
1058
+ count(/\.[\w-]+/g) + count(/\[[^\]]*\]/g) + count(/:(?!not\()[\w-]+/g),
1059
+ (typesOnly.match(/[a-zA-Z][\w-]*/g) || []).length,
1060
+ ];
1061
+ };
1062
+
1063
+ const compareSpecificity: (a: Specificity, b: Specificity) => number = (
1064
+ a: Specificity,
1065
+ b: Specificity,
1066
+ ): number => {
1067
+ return a[0] - b[0] || a[1] - b[1] || a[2] - b[2];
1068
+ };
1069
+
1070
+ /*
1071
+ * The value a browser would use for `property` on `element`: an inline style
1072
+ * first, otherwise the matching rule with the highest specificity, ties going
1073
+ * to the later rule. Neither sheet uses !important.
1074
+ */
1075
+ const cascadedValue: (
1076
+ element: HTMLElement,
1077
+ property: string,
1078
+ ) => string | undefined = (
1079
+ element: HTMLElement,
1080
+ property: string,
1081
+ ): string | undefined => {
1082
+ const inline: string = element.style.getPropertyValue(property);
1083
+
1084
+ if (inline) {
1085
+ return inline;
1086
+ }
1087
+
1088
+ let winner: { value: string; specificity: Specificity } | undefined =
1089
+ undefined;
1090
+
1091
+ for (const rule of CASCADE) {
1092
+ const value: string | undefined = rule.declarations[property];
1093
+
1094
+ if (value === undefined) {
1095
+ continue;
1096
+ }
1097
+
1098
+ for (const selector of rule.selectors) {
1099
+ // A pseudo-element styles a generated box, not the element itself.
1100
+ if (selector.includes("::")) {
1101
+ continue;
1102
+ }
1103
+
1104
+ let matches: boolean = false;
1105
+
1106
+ try {
1107
+ matches = element.matches(selector);
1108
+ } catch {
1109
+ // Vendor-prefixed pseudo-classes jsdom cannot parse never match here.
1110
+ matches = false;
1111
+ }
1112
+
1113
+ if (!matches) {
1114
+ continue;
1115
+ }
1116
+
1117
+ const specificity: Specificity = specificityOf(selector);
1118
+
1119
+ if (
1120
+ !winner ||
1121
+ compareSpecificity(specificity, winner.specificity) >= 0
1122
+ ) {
1123
+ winner = { value, specificity };
1124
+ }
1125
+ }
1126
+ }
1127
+
1128
+ return winner?.value;
1129
+ };
1130
+
1131
+ const remToPx: (value: string) => number = (value: string): number => {
1132
+ const match: RegExpMatchArray | null = value.match(/^(-?[\d.]+)(rem|px)$/);
1133
+
1134
+ if (!match) {
1135
+ throw new Error(`Cannot convert "${value}" to pixels`);
1136
+ }
1137
+
1138
+ return match[2] === "rem"
1139
+ ? parseFloat(match[1]!) * 16
1140
+ : parseFloat(match[1]!);
1141
+ };
1142
+
1143
+ describe("rules", () => {
1144
+ test("override blocks in the day grid are positioned absolutely again", () => {
1145
+ /*
1146
+ * The generic override rule sets position: relative (for month rows and
1147
+ * the all-day strip). In the grid that made each override block flow
1148
+ * below the earlier ones, so a 5:02 PM hand-off was drawn hours late.
1149
+ */
1150
+ expect(
1151
+ declarationsFor(
1152
+ `.oneuptime-calendar .rbc-day-slot .rbc-event.${OVERRIDE_CLASS}`,
1153
+ )["position"],
1154
+ ).toBe("absolute");
1155
+
1156
+ // And it outranks the generic rule instead of relying on source order.
1157
+ expect(
1158
+ compareSpecificity(
1159
+ specificityOf(
1160
+ `.oneuptime-calendar .rbc-day-slot .rbc-event.${OVERRIDE_CLASS}`,
1161
+ ),
1162
+ specificityOf(`.oneuptime-calendar .rbc-event.${OVERRIDE_CLASS}`),
1163
+ ),
1164
+ ).toBeGreaterThan(0);
1165
+ });
1166
+
1167
+ test("hours are allowed to be much shorter than rbc's 40px, so a whole day fits", () => {
1168
+ const minHeight: string | undefined = declarationsFor(
1169
+ ".oneuptime-calendar .rbc-time-view .rbc-timeslot-group",
1170
+ )["min-height"];
1171
+
1172
+ expect(minHeight).toBeDefined();
1173
+ expect(remToPx(minHeight!)).toBeGreaterThan(0);
1174
+ expect(remToPx(minHeight!)).toBeLessThanOrEqual(24);
1175
+ });
1176
+
1177
+ test("the current-time line has a white halo so it shows on a red shift", () => {
1178
+ const boxShadow: string | undefined = declarationsFor(
1179
+ ".oneuptime-calendar .rbc-current-time-indicator",
1180
+ )["box-shadow"];
1181
+
1182
+ expect(boxShadow).toBeDefined();
1183
+ expect(boxShadow!.toLowerCase()).toMatch(/#ffffff|#fff\b|white/);
1184
+
1185
+ // The dot at the start of the line is ringed the same way.
1186
+ const dotShadow: string | undefined = declarationsFor(
1187
+ ".oneuptime-calendar .rbc-current-time-indicator::before",
1188
+ )["box-shadow"];
1189
+
1190
+ expect(dotShadow).toBeDefined();
1191
+ expect(dotShadow!.toLowerCase()).toMatch(/#ffffff|#fff\b|white/);
1192
+ });
1193
+
1194
+ test("day columns clip what hangs below midnight without becoming scroll containers", () => {
1195
+ /*
1196
+ * A block at rbc's 20px minimum height late in the day, or the
1197
+ * current-time dot near midnight, hung below the column and brought the
1198
+ * scrollbar back, so the column clips vertically. It must be `clip`:
1199
+ * `hidden`, `auto` or `scroll` make the column a scroll container, and
1200
+ * tabbing onto a late block then scrolled every block in that column
1201
+ * off the hour lines. The other axis must not be one of those either, or
1202
+ * the browser turns `clip` into `hidden`.
1203
+ */
1204
+ const daySlot: Record<string, string> =
1205
+ declarationsForSubject("rbc-day-slot");
1206
+
1207
+ expect(daySlot["overflow-y"]).toBe("clip");
1208
+
1209
+ for (const property of OVERFLOW_PROPERTIES) {
1210
+ expect(SCROLLING_OVERFLOW).not.toContain(daySlot[property]);
1211
+ }
1212
+
1213
+ // No shorthand that would reset overflow-y, wherever it came in the rule.
1214
+ expect(daySlot["overflow"]).toBeUndefined();
1215
+ });
1216
+
1217
+ test("the events container inside a day column sets no overflow of its own", () => {
1218
+ /*
1219
+ * The clip used to sit here as overflow: hidden, which made the events
1220
+ * container the scroll container: focusing a late block scrolled the
1221
+ * blocks while the hour lines, drawn by the column, stayed put.
1222
+ */
1223
+ const eventsContainer: Record<string, string> = declarationsForSubject(
1224
+ "rbc-events-container",
1225
+ );
1226
+
1227
+ for (const property of OVERFLOW_PROPERTIES) {
1228
+ expect(eventsContainer[property]).toBeUndefined();
1229
+ }
1230
+ });
1231
+
1232
+ test("focus and selection rings on grid blocks are drawn inside the block", () => {
1233
+ /*
1234
+ * The column clips vertically, so a ring drawn outside a block at the
1235
+ * top or bottom of the day would be cut off. The grid rules pull it
1236
+ * inside, and outrank the general ring rule instead of relying on order.
1237
+ */
1238
+ for (const state of [":focus", ".rbc-selected"]) {
1239
+ const gridSelector: string = `.oneuptime-calendar .rbc-day-slot .rbc-event${state}`;
1240
+ const outlineOffset: string | undefined =
1241
+ declarationsFor(gridSelector)["outline-offset"];
1242
+
1243
+ expect(outlineOffset).toBeDefined();
1244
+ expect(remToPx(outlineOffset!)).toBeLessThan(0);
1245
+
1246
+ expect(
1247
+ compareSpecificity(
1248
+ specificityOf(gridSelector),
1249
+ specificityOf(`.oneuptime-calendar .rbc-event${state}`),
1250
+ ),
1251
+ ).toBeGreaterThan(0);
1252
+ }
1253
+ });
1254
+
1255
+ test("the empty all-day strip is hidden when the wrapper says there are no all-day events", () => {
1256
+ expect(
1257
+ declarationsFor(
1258
+ ".oneuptime-calendar.oneuptime-calendar--no-all-day .rbc-time-header-content > .rbc-allday-cell",
1259
+ )["display"],
1260
+ ).toBe("none");
1261
+ });
1262
+
1263
+ test("background bands carry no time label or title", () => {
1264
+ expect(
1265
+ declarationsFor(
1266
+ ".oneuptime-calendar .rbc-background-event .rbc-event-label",
1267
+ )["display"],
1268
+ ).toBe("none");
1269
+ expect(
1270
+ declarationsFor(
1271
+ ".oneuptime-calendar .rbc-background-event .rbc-event-content",
1272
+ )["display"],
1273
+ ).toBe("none");
1274
+ });
1275
+ });
1276
+
1277
+ /*
1278
+ * Where a browser draws each block of a day column, as a percent of the
1279
+ * column, from the cascaded `position`. An absolutely positioned block sits
1280
+ * at its `top`. A relatively positioned one is first laid out in normal
1281
+ * flow, below every in-flow block before it, and only then moved down by
1282
+ * its `top`. That is how override blocks ended up hours after their start.
1283
+ */
1284
+ const drawnTops: (column: HTMLElement) => Map<string, number> = (
1285
+ column: HTMLElement,
1286
+ ): Map<string, number> => {
1287
+ const eventsContainer: HTMLElement | null =
1288
+ column.querySelector<HTMLElement>(".rbc-events-container");
1289
+
1290
+ if (!eventsContainer) {
1291
+ throw new Error("The day column has no events container");
1292
+ }
1293
+
1294
+ const tops: Map<string, number> = new Map<string, number>();
1295
+ let flowOffset: number = 0;
1296
+
1297
+ for (const child of Array.from(eventsContainer.children)) {
1298
+ const block: HTMLElement = child as HTMLElement;
1299
+ const position: string = cascadedValue(block, "position") || "static";
1300
+ const top: number = percent(block.style.top);
1301
+
1302
+ if (position === "absolute") {
1303
+ tops.set(titleOf(block), top);
1304
+ continue;
1305
+ }
1306
+
1307
+ tops.set(
1308
+ titleOf(block),
1309
+ flowOffset + (position === "relative" ? top : 0),
1310
+ );
1311
+ flowOffset += percent(block.style.height);
1312
+ }
1313
+
1314
+ return tops;
1315
+ };
1316
+
1317
+ describe("cascade on the rendered calendar", () => {
1318
+ test("override blocks in the grid resolve to position: absolute, so the 5:02 PM hand-off has no gap", () => {
1319
+ const { container } = renderWeek({
1320
+ defaultDate: sep(SATURDAY_12, 12),
1321
+ events: buildSaturday12(),
1322
+ });
1323
+
1324
+ const saturday: HTMLElement = getDayColumn(
1325
+ container,
1326
+ sep(SATURDAY_12, 0),
1327
+ );
1328
+ const blocks: Array<HTMLElement> = getBlocks(saturday);
1329
+
1330
+ expect(blocks).toHaveLength(3);
1331
+
1332
+ for (const block of blocks) {
1333
+ expect(cascadedValue(block, "position")).toBe("absolute");
1334
+ }
1335
+
1336
+ // The override rule still applies otherwise: this is its stripe padding.
1337
+ expect(
1338
+ cascadedValue(
1339
+ getBlock(saturday, "Blair (covering Alex)"),
1340
+ "padding-left",
1341
+ ),
1342
+ ).toBe("0.75rem");
1343
+
1344
+ /*
1345
+ * Where the blocks are drawn. With `position: relative` the second
1346
+ * override was pushed down by the height of the first one, far past
1347
+ * 9:26 PM, leaving a gap after Blair.
1348
+ */
1349
+ const tops: Map<string, number> = drawnTops(saturday);
1350
+ const alex: BlockBox = boxOf(getBlock(saturday, "Alex"));
1351
+ const blair: BlockBox = boxOf(
1352
+ getBlock(saturday, "Blair (covering Alex)"),
1353
+ );
1354
+
1355
+ expect(tops.get("Alex")).toBe(0);
1356
+ expect(tops.get("Blair (covering Alex)")).toBeCloseTo(
1357
+ alex.top + alex.height,
1358
+ 6,
1359
+ );
1360
+ expect(tops.get("Blair (covering Alex)")).toBeCloseTo(
1361
+ percentOfDay(17, 2),
1362
+ 6,
1363
+ );
1364
+ expect(tops.get("Casey (covering Alex)")).toBeCloseTo(
1365
+ blair.top + blair.height,
1366
+ 6,
1367
+ );
1368
+ expect(tops.get("Casey (covering Alex)")).toBeCloseTo(
1369
+ percentOfDay(21, 26),
1370
+ 6,
1371
+ );
1372
+ });
1373
+
1374
+ test("outside the grid, an override block keeps position: relative for its stripe", () => {
1375
+ /*
1376
+ * The grid fix is scoped to day columns. In the all-day strip (and month
1377
+ * rows) blocks sit in normal flow, and the stripe needs the block to be
1378
+ * its containing block.
1379
+ */
1380
+ const { container } = renderWeek({
1381
+ events: [
1382
+ makeEvent("Holiday cover", sep(23, 0), sep(24, 0), {
1383
+ allDay: true,
1384
+ className: OVERRIDE_CLASS,
1385
+ accentColor: "#16a34a",
1386
+ }),
1387
+ ],
1388
+ });
1389
+
1390
+ const cover: HTMLElement = getBlock(
1391
+ container.querySelector(".rbc-allday-cell")!,
1392
+ "Holiday cover",
1393
+ );
1394
+
1395
+ expect(cascadedValue(cover, "position")).toBe("relative");
1396
+ });
1397
+
1398
+ test("every hour row is short enough for all 24 to fit in the calendar's height", () => {
1399
+ const { container } = renderWeek({ events: [] });
1400
+
1401
+ const wrapper: HTMLElement = getWrapper(container);
1402
+ const heightClass: RegExpMatchArray | null =
1403
+ wrapper.className.match(/\bh-\[([\d.]+)rem\]/);
1404
+
1405
+ expect(heightClass).not.toBeNull();
1406
+
1407
+ const calendarHeightPx: number = parseFloat(heightClass![1]!) * 16;
1408
+
1409
+ // The time gutter and the seven days, 24 hours each.
1410
+ const hourRows: Array<HTMLElement> = Array.from(
1411
+ container.querySelectorAll<HTMLElement>(
1412
+ ".rbc-time-content .rbc-timeslot-group",
1413
+ ),
1414
+ );
1415
+
1416
+ expect(hourRows).toHaveLength(8 * 24);
1417
+
1418
+ let tallestMinHeightPx: number = 0;
1419
+
1420
+ for (const hourRow of hourRows) {
1421
+ const minHeight: string | undefined = cascadedValue(
1422
+ hourRow,
1423
+ "min-height",
1424
+ );
1425
+
1426
+ expect(minHeight).toBeDefined();
1427
+ tallestMinHeightPx = Math.max(tallestMinHeightPx, remToPx(minHeight!));
1428
+
1429
+ // The rows grow to share the height, rather than stay at the floor.
1430
+ expect(cascadedValue(hourRow, "flex")).toBe("1");
1431
+ }
1432
+
1433
+ /*
1434
+ * The toolbar and the day headers take the rest; 8rem is more than both
1435
+ * together. With rbc's 40px per hour a day needs 960px, far more than the
1436
+ * calendar is tall.
1437
+ */
1438
+ const TOOLBAR_AND_HEADERS_PX: number = 8 * 16;
1439
+
1440
+ expect(24 * tallestMinHeightPx).toBeLessThanOrEqual(
1441
+ calendarHeightPx - TOOLBAR_AND_HEADERS_PX,
1442
+ );
1443
+ });
1444
+
1445
+ test("the all-day strip is hidden while it is empty, and shown once it has an event", () => {
1446
+ const empty: RenderResult = renderWeek({
1447
+ events: [makeEvent("Alex", sep(23, 0), sep(24, 0))],
1448
+ });
1449
+
1450
+ const emptyCell: HTMLElement | null =
1451
+ empty.container.querySelector<HTMLElement>(".rbc-allday-cell");
1452
+
1453
+ expect(emptyCell).not.toBeNull();
1454
+ expect(cascadedValue(emptyCell!, "display")).toBe("none");
1455
+
1456
+ empty.unmount();
1457
+
1458
+ const withHoliday: RenderResult = renderWeek({
1459
+ events: [
1460
+ makeEvent("Alex", sep(23, 0), sep(24, 0)),
1461
+ makeEvent("Company holiday", sep(24, 0), sep(25, 0), {
1462
+ allDay: true,
1463
+ }),
1464
+ ],
1465
+ });
1466
+
1467
+ const filledCell: HTMLElement | null =
1468
+ withHoliday.container.querySelector<HTMLElement>(".rbc-allday-cell");
1469
+
1470
+ expect(filledCell).not.toBeNull();
1471
+ expect(cascadedValue(filledCell!, "display")).not.toBe("none");
1472
+ });
1473
+
1474
+ test("the current-time line is drawn over a red shift, with the white halo", () => {
1475
+ // The clock says Wednesday 10:00; a red shift covers that hour.
1476
+ const { container } = renderWeek({
1477
+ events: [
1478
+ makeEvent("Red shift", sep(23, 9), sep(23, 11), {
1479
+ color: "#dc2626",
1480
+ }),
1481
+ ],
1482
+ });
1483
+
1484
+ const wednesday: HTMLElement = getDayColumn(container, sep(23, 0));
1485
+ const indicator: HTMLElement | null =
1486
+ wednesday.querySelector<HTMLElement>(".rbc-current-time-indicator");
1487
+ const redShift: HTMLElement = getBlock(wednesday, "Red shift");
1488
+ const shiftBox: BlockBox = boxOf(redShift);
1489
+
1490
+ expect(indicator).not.toBeNull();
1491
+ expect(redShift.style.backgroundColor).toBe("rgb(220, 38, 38)");
1492
+
1493
+ // The line really crosses the red block.
1494
+ const lineTop: number = percent(indicator!.style.top);
1495
+
1496
+ expect(lineTop).toBeGreaterThan(shiftBox.top);
1497
+ expect(lineTop).toBeLessThan(shiftBox.top + shiftBox.height);
1498
+
1499
+ // It is stacked above the block, and ringed in white so red on red shows.
1500
+ const zIndexOf: (element: HTMLElement) => number = (
1501
+ element: HTMLElement,
1502
+ ): number => {
1503
+ const value: string | undefined = cascadedValue(element, "z-index");
1504
+ return value && value !== "auto" ? Number(value) : 0;
1505
+ };
1506
+ const lineZ: number = zIndexOf(indicator!);
1507
+ const blockZ: number = zIndexOf(redShift);
1508
+
1509
+ expect(lineZ).toBeGreaterThan(blockZ);
1510
+ expect(cascadedValue(indicator!, "box-shadow")).toContain("#ffffff");
1511
+ });
1512
+
1513
+ test("every rendered day column clips vertically, and nothing in it can scroll", () => {
1514
+ const { container } = renderWeek({ events: [] });
1515
+
1516
+ const columns: Array<HTMLElement> = getDayColumns(container);
1517
+
1518
+ expect(columns).toHaveLength(7);
1519
+
1520
+ for (const column of columns) {
1521
+ expect(cascadedValue(column, "overflow-y")).toBe("clip");
1522
+ expect(cascadedValue(column, "overflow")).toBeUndefined();
1523
+ expect(SCROLLING_OVERFLOW).not.toContain(
1524
+ cascadedValue(column, "overflow-x"),
1525
+ );
1526
+
1527
+ const eventsContainer: HTMLElement | null =
1528
+ column.querySelector<HTMLElement>(".rbc-events-container");
1529
+
1530
+ expect(eventsContainer).not.toBeNull();
1531
+
1532
+ for (const property of OVERFLOW_PROPERTIES) {
1533
+ expect(cascadedValue(eventsContainer!, property)).toBeUndefined();
1534
+ }
1535
+ }
1536
+ });
1537
+
1538
+ test("a focused or selected grid block has its whole ring inside the block", () => {
1539
+ const { container } = renderWeek({
1540
+ events: [makeEvent("Alex", sep(23, 9), sep(23, 17))],
1541
+ });
1542
+
1543
+ const findAlex: () => HTMLElement = (): HTMLElement => {
1544
+ return getBlock(getDayColumn(container, sep(23, 0)), "Alex");
1545
+ };
1546
+
1547
+ // The ring's width comes from the general rule, e.g. "2px solid #4f46e5".
1548
+ const expectRingInside: (block: HTMLElement) => void = (
1549
+ block: HTMLElement,
1550
+ ): void => {
1551
+ const outline: string | undefined = cascadedValue(block, "outline");
1552
+ const outlineOffset: string | undefined = cascadedValue(
1553
+ block,
1554
+ "outline-offset",
1555
+ );
1556
+
1557
+ expect(outline).toBeDefined();
1558
+ expect(outlineOffset).toBeDefined();
1559
+
1560
+ const ringWidthPx: number = remToPx(outline!.split(" ")[0]!);
1561
+
1562
+ expect(ringWidthPx).toBeGreaterThan(0);
1563
+ expect(remToPx(outlineOffset!)).toBeLessThanOrEqual(-ringWidthPx);
1564
+ };
1565
+
1566
+ // Keyboard focus: react-big-calendar makes each grid block tabbable.
1567
+ act(() => {
1568
+ findAlex().focus();
1569
+ });
1570
+
1571
+ expect(document.activeElement).toBe(findAlex());
1572
+ expectRingInside(findAlex());
1573
+
1574
+ act(() => {
1575
+ findAlex().blur();
1576
+ });
1577
+
1578
+ // A click selects the block.
1579
+ act(() => {
1580
+ fireEvent.click(findAlex());
1581
+ });
1582
+
1583
+ expect(findAlex()).toHaveClass("rbc-selected");
1584
+ expect(findAlex()).not.toBe(document.activeElement);
1585
+ expectRingInside(findAlex());
1586
+ });
1587
+
1588
+ test("the rendered background band hides its label and title", () => {
1589
+ const { container } = renderWeek({
1590
+ events: [],
1591
+ backgroundEvents: [makeEvent("No one on call", sep(23, 0), sep(23, 9))],
1592
+ });
1593
+
1594
+ const band: HTMLElement | null = container.querySelector<HTMLElement>(
1595
+ ".rbc-background-event",
1596
+ );
1597
+
1598
+ expect(band).not.toBeNull();
1599
+
1600
+ const label: HTMLElement = band!.querySelector(
1601
+ ".rbc-event-label",
1602
+ ) as HTMLElement;
1603
+ const content: HTMLElement = band!.querySelector(
1604
+ ".rbc-event-content",
1605
+ ) as HTMLElement;
1606
+
1607
+ expect(cascadedValue(label, "display")).toBe("none");
1608
+ expect(cascadedValue(content, "display")).toBe("none");
1609
+ });
1610
+ });
1611
+ });