@oneuptime/common 12.0.30 → 12.0.32

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 (645) hide show
  1. package/Models/AnalyticsModels/SecurityEvent.ts +48 -16
  2. package/Models/AnalyticsModels/ThreatIntelIndicator.ts +10 -5
  3. package/Models/DatabaseModels/AlertSeverity.ts +44 -0
  4. package/Models/DatabaseModels/AlertState.ts +0 -2
  5. package/Models/DatabaseModels/DetectionRule.ts +16 -5
  6. package/Models/DatabaseModels/Domain.ts +1 -1
  7. package/Models/DatabaseModels/GoogleSecOpsConnection.ts +14 -5
  8. package/Models/DatabaseModels/Incident.ts +1 -1
  9. package/Models/DatabaseModels/IncidentSeverity.ts +44 -0
  10. package/Models/DatabaseModels/IncidentTemplate.ts +1 -1
  11. package/Models/DatabaseModels/Index.ts +4 -0
  12. package/Models/DatabaseModels/MetricType.ts +0 -2
  13. package/Models/DatabaseModels/MonitorStatusTimeline.ts +0 -2
  14. package/Models/DatabaseModels/MonitorTest.ts +0 -2
  15. package/Models/DatabaseModels/NetworkDevice.ts +234 -5
  16. package/Models/DatabaseModels/NetworkDeviceAutoImportRule.ts +88 -0
  17. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +22 -0
  18. package/Models/DatabaseModels/NetworkDeviceOidTemplate.ts +501 -0
  19. package/Models/DatabaseModels/NetworkDeviceRole.ts +648 -0
  20. package/Models/DatabaseModels/ScheduledMaintenance.ts +1 -1
  21. package/Models/DatabaseModels/ScheduledMaintenanceTemplate.ts +1 -1
  22. package/Models/DatabaseModels/StatusPageAnnouncement.ts +0 -2
  23. package/Models/DatabaseModels/StatusPageAnnouncementTemplate.ts +0 -2
  24. package/Models/DatabaseModels/StatusPagePrivateUser.ts +0 -2
  25. package/Models/DatabaseModels/StatusPageResource.ts +0 -2
  26. package/Models/DatabaseModels/StatusPageSubscriber.ts +0 -2
  27. package/Models/DatabaseModels/ThreatIntelFeed.ts +16 -5
  28. package/Server/API/GlobalConfigAPI.ts +362 -183
  29. package/Server/API/TelemetryAPI.ts +42 -4
  30. package/Server/EnvironmentConfig.ts +112 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1790500000000-AddNetworkDeviceOidTemplate.ts +59 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1790600000000-AddAutoImportRuleOidTemplate.ts +25 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1790800000000-AddNetworkDeviceRoleTable.ts +72 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  35. package/Server/Middleware/MultipartFormData.ts +118 -32
  36. package/Server/Services/AlertEpisodeLabelRuleEngineService.ts +9 -1
  37. package/Server/Services/AlertEpisodeOnCallRuleEngineService.ts +9 -1
  38. package/Server/Services/AlertEpisodeOwnerRuleEngineService.ts +9 -1
  39. package/Server/Services/AlertEpisodePrivacyRuleEngineService.ts +9 -1
  40. package/Server/Services/AlertGroupingEngineService.ts +9 -1
  41. package/Server/Services/AlertLabelRuleEngineService.ts +9 -1
  42. package/Server/Services/AlertOnCallRuleEngineService.ts +9 -1
  43. package/Server/Services/AlertOwnerRuleEngineService.ts +9 -1
  44. package/Server/Services/AlertPrivacyRuleEngineService.ts +9 -1
  45. package/Server/Services/AlertReminderRuleService.ts +9 -1
  46. package/Server/Services/AutoRemediationRuleEngineService.ts +9 -1
  47. package/Server/Services/CephClusterLabelRuleEngineService.ts +9 -1
  48. package/Server/Services/CephClusterOwnerRuleEngineService.ts +9 -1
  49. package/Server/Services/CloudResourceLabelRuleEngineService.ts +9 -1
  50. package/Server/Services/CloudResourceOwnerRuleEngineService.ts +9 -1
  51. package/Server/Services/DashboardLabelRuleEngineService.ts +9 -1
  52. package/Server/Services/DashboardOwnerRuleEngineService.ts +9 -1
  53. package/Server/Services/DatabaseService.ts +39 -9
  54. package/Server/Services/DockerHostLabelRuleEngineService.ts +9 -1
  55. package/Server/Services/DockerHostOwnerRuleEngineService.ts +9 -1
  56. package/Server/Services/DockerSwarmClusterLabelRuleEngineService.ts +9 -1
  57. package/Server/Services/DockerSwarmClusterOwnerRuleEngineService.ts +9 -1
  58. package/Server/Services/HostLabelRuleEngineService.ts +9 -1
  59. package/Server/Services/HostOwnerRuleEngineService.ts +9 -1
  60. package/Server/Services/IncidentEpisodeLabelRuleEngineService.ts +9 -1
  61. package/Server/Services/IncidentEpisodeOnCallRuleEngineService.ts +9 -1
  62. package/Server/Services/IncidentEpisodeOwnerRuleEngineService.ts +9 -1
  63. package/Server/Services/IncidentEpisodePrivacyRuleEngineService.ts +9 -1
  64. package/Server/Services/IncidentGroupingEngineService.ts +9 -1
  65. package/Server/Services/IncidentLabelRuleEngineService.ts +9 -1
  66. package/Server/Services/IncidentOnCallRuleEngineService.ts +9 -1
  67. package/Server/Services/IncidentOwnerRuleEngineService.ts +9 -1
  68. package/Server/Services/IncidentPrivacyRuleEngineService.ts +9 -1
  69. package/Server/Services/IncidentReminderRuleService.ts +9 -1
  70. package/Server/Services/IncidentSlaRuleService.ts +9 -1
  71. package/Server/Services/IncomingCallPolicyLabelRuleEngineService.ts +9 -1
  72. package/Server/Services/IncomingCallPolicyOwnerRuleEngineService.ts +9 -1
  73. package/Server/Services/Index.ts +4 -0
  74. package/Server/Services/IoTFleetLabelRuleEngineService.ts +9 -1
  75. package/Server/Services/IoTFleetOwnerRuleEngineService.ts +9 -1
  76. package/Server/Services/KubernetesClusterLabelRuleEngineService.ts +9 -1
  77. package/Server/Services/KubernetesClusterOwnerRuleEngineService.ts +9 -1
  78. package/Server/Services/KubernetesResourceService.ts +5 -1
  79. package/Server/Services/MonitorLabelRuleEngineService.ts +9 -1
  80. package/Server/Services/MonitorOwnerRuleEngineService.ts +9 -1
  81. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +35 -0
  82. package/Server/Services/NetworkDeviceAutoImportRuleService.ts +96 -0
  83. package/Server/Services/NetworkDeviceLabelRuleEngineService.ts +9 -1
  84. package/Server/Services/NetworkDeviceOidTemplateService.ts +201 -0
  85. package/Server/Services/NetworkDeviceOwnerRuleEngineService.ts +9 -1
  86. package/Server/Services/NetworkDeviceRoleService.ts +90 -0
  87. package/Server/Services/NetworkDeviceService.ts +209 -1
  88. package/Server/Services/OnCallDutyPolicyLabelRuleEngineService.ts +9 -1
  89. package/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.ts +9 -1
  90. package/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.ts +9 -1
  91. package/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.ts +9 -1
  92. package/Server/Services/PodmanHostLabelRuleEngineService.ts +9 -1
  93. package/Server/Services/PodmanHostOwnerRuleEngineService.ts +9 -1
  94. package/Server/Services/ProjectService.ts +85 -0
  95. package/Server/Services/ProxmoxClusterLabelRuleEngineService.ts +9 -1
  96. package/Server/Services/ProxmoxClusterOwnerRuleEngineService.ts +9 -1
  97. package/Server/Services/RumApplicationLabelRuleEngineService.ts +9 -1
  98. package/Server/Services/RumApplicationOwnerRuleEngineService.ts +9 -1
  99. package/Server/Services/RunbookLabelRuleEngineService.ts +9 -1
  100. package/Server/Services/RunbookOwnerRuleEngineService.ts +9 -1
  101. package/Server/Services/RunbookRuleEngineService.ts +9 -1
  102. package/Server/Services/ScheduledMaintenanceLabelRuleEngineService.ts +9 -1
  103. package/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.ts +9 -1
  104. package/Server/Services/ScheduledMaintenanceReminderRuleService.ts +9 -1
  105. package/Server/Services/ServerlessFunctionLabelRuleEngineService.ts +9 -1
  106. package/Server/Services/ServerlessFunctionOwnerRuleEngineService.ts +9 -1
  107. package/Server/Services/ServiceLabelRuleEngineService.ts +9 -1
  108. package/Server/Services/ServiceOwnerRuleEngineService.ts +9 -1
  109. package/Server/Services/StatusPageLabelRuleEngineService.ts +9 -1
  110. package/Server/Services/StatusPageMonitorRuleEngineService.ts +7 -0
  111. package/Server/Services/StatusPageOwnerRuleEngineService.ts +9 -1
  112. package/Server/Services/TelemetrySourceMapService.ts +266 -23
  113. package/Server/Services/UserNotificationSettingService.ts +0 -6
  114. package/Server/Services/UserService.ts +27 -0
  115. package/Server/Services/WorkflowLabelRuleEngineService.ts +9 -1
  116. package/Server/Services/WorkflowOwnerRuleEngineService.ts +9 -1
  117. package/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.ts +186 -0
  118. package/Server/Utils/Monitor/CapturedMetricAttributeUtil.ts +245 -0
  119. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +21 -2
  120. package/Server/Utils/Monitor/MonitorMetricUtil.ts +55 -21
  121. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +32 -0
  122. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +15 -2
  123. package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +18 -1
  124. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +10 -0
  125. package/Server/Utils/Monitor/SeriesResourceLabels.ts +34 -0
  126. package/Server/Utils/Rules/RuleEngineRuleRead.ts +48 -0
  127. package/Server/Utils/Telemetry/ExceptionSanitizer.ts +14 -1
  128. package/Server/Utils/Telemetry/LogExceptionExtractor.ts +14 -2
  129. package/Server/Utils/Telemetry/SourceMapResolver.ts +16 -5
  130. package/Server/Utils/Telemetry/StackTraceParser.ts +399 -0
  131. package/Tests/App/Dashboard/AddNeighborToMonitoringModal.test.tsx +31 -1
  132. package/Tests/App/Dashboard/DashboardChartWidgetZoom.test.tsx +35 -8
  133. package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +107 -3
  134. package/Tests/App/Dashboard/DashboardWideChartZoom.test.tsx +401 -0
  135. package/Tests/App/Dashboard/EventOverlayHook.test.tsx +125 -0
  136. package/Tests/App/Dashboard/HeaderImageAssets.test.tsx +93 -0
  137. package/Tests/App/Dashboard/MonitorTemplateColumnAndFacet.test.tsx +318 -0
  138. package/Tests/App/Dashboard/NetworkDeviceBulkDelete.test.tsx +357 -0
  139. package/Tests/App/Dashboard/NetworkSideMenu.test.tsx +590 -0
  140. package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +3 -3
  141. package/Tests/App/Dashboard/SideMenuHarness.tsx +11 -3
  142. package/Tests/App/Dashboard/UserElementEmail.test.tsx +12 -4
  143. package/Tests/App/Dashboard/UserEmailCallSites.test.tsx +1 -1
  144. package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +14 -0
  145. package/Tests/Models/DatabaseModels/ModelRegistryInvariants.test.ts +543 -0
  146. package/Tests/Models/SecurityDomainAccessControl.test.ts +429 -0
  147. package/Tests/Server/API/GlobalConfigLicense.test.ts +657 -0
  148. package/Tests/Server/API/SecurityEventAttributesAPI.test.ts +84 -6
  149. package/Tests/Server/API/TelemetryResolveStackTraceAPI.test.ts +805 -0
  150. package/Tests/Server/Infrastructure/Postgres/AddOnCallCalendarFeedsMigration.test.ts +32 -7
  151. package/Tests/Server/Infrastructure/Postgres/NetworkDeviceRoleTableMigration.test.ts +476 -0
  152. package/Tests/Server/Middleware/IdentityRateLimit.test.ts +1144 -0
  153. package/Tests/Server/Middleware/MultipartFormData.test.ts +618 -3
  154. package/Tests/Server/Services/DatabaseServiceGenerateSlug.test.ts +215 -0
  155. package/Tests/Server/Services/MonitorLabelRuleEngineScale.test.ts +520 -0
  156. package/Tests/Server/Services/NetworkDeviceOidTemplateService.test.ts +332 -0
  157. package/Tests/Server/Services/NetworkDeviceOidTemplateWriteGuards.test.ts +409 -0
  158. package/Tests/Server/Services/NetworkDeviceRoleModel.test.ts +672 -0
  159. package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +1 -1
  160. package/Tests/Server/Services/ProjectServiceCreateSubscriptionStarted.test.ts +67 -4
  161. package/Tests/Server/Services/RuleEngineRuleFetchLimit.test.ts +239 -0
  162. package/Tests/Server/Services/ScheduledMaintenanceSubscriberEndTime.test.ts +369 -0
  163. package/Tests/Server/Services/TelemetrySourceMapService.test.ts +1210 -2
  164. package/Tests/Server/Services/UserNotificationSettingMonitorDefaults.test.ts +248 -0
  165. package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +43 -2
  166. package/Tests/Server/Services/UserServiceSeatLimit.test.ts +182 -0
  167. package/Tests/Server/Types/AnalyticsDatabase/SecurityEventModelPermission.test.ts +255 -0
  168. package/Tests/Server/Types/Database/Permissions/ReadBlockPermission.test.ts +212 -0
  169. package/Tests/Server/Types/Database/Permissions/SecurityRoleAccess.test.ts +413 -0
  170. package/Tests/Server/Utils/BasicCron.test.ts +283 -0
  171. package/Tests/Server/Utils/CodeRepository.test.ts +689 -0
  172. package/Tests/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.test.ts +495 -0
  173. package/Tests/Server/Utils/ExceptionSanitizer.test.ts +77 -0
  174. package/Tests/Server/Utils/IncomingCallPhoneNumber.test.ts +174 -0
  175. package/Tests/Server/Utils/Monitor/CapturedMetricAttributeUtil.test.ts +284 -0
  176. package/Tests/Server/Utils/Monitor/MonitorCustomMetricAttributes.test.ts +503 -0
  177. package/Tests/Server/Utils/Monitor/MonitorTemplatePrototypePollution.test.ts +106 -0
  178. package/Tests/Server/Utils/Monitor/NetworkDeviceWalkLogWritePath.test.ts +33 -4
  179. package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +14 -4
  180. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +44 -0
  181. package/Tests/Server/Utils/OpenAPISpec.test.ts +536 -0
  182. package/Tests/Server/Utils/Rules/RuleEngineRuleRead.test.ts +115 -0
  183. package/Tests/Server/Utils/StackTraceParser.test.ts +610 -0
  184. package/Tests/Server/Utils/Telemetry/LogExceptionExtractor.test.ts +0 -0
  185. package/Tests/Server/Utils/Telemetry/SourceMapLimits.test.ts +656 -0
  186. package/Tests/Server/Utils/Telemetry/SourceMapResolver.test.ts +100 -0
  187. package/Tests/Types/Monitor/SnmpMonitor/SnmpOidListUtil.test.ts +454 -0
  188. package/Tests/Types/NetworkDevice/DefaultNetworkDeviceRole.test.ts +417 -0
  189. package/Tests/Types/SecurityRolePermissions.test.ts +193 -0
  190. package/Tests/UI/Components/Charts/AnnotationLayout.test.ts +773 -0
  191. package/Tests/UI/Components/Charts/ChartAnnotationRail.test.tsx +789 -0
  192. package/Tests/UI/Components/Charts/ChartBucketIdentity.test.ts +254 -0
  193. package/Tests/UI/Components/Charts/ChartClickDoubleClickDisambiguation.test.tsx +221 -0
  194. package/Tests/UI/Components/Charts/ChartDoubleClickReset.test.tsx +220 -0
  195. package/Tests/UI/Components/Charts/TimeAnnotation.test.ts +471 -0
  196. package/Tests/UI/Components/EditionLabelLicenseRefresh.test.tsx +405 -0
  197. package/Tests/UI/Components/ErrorMessageRefreshControl.test.tsx +83 -0
  198. package/Tests/UI/Components/MarkdownConverters.test.ts +686 -0
  199. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +751 -0
  200. package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +475 -43
  201. package/Tests/UI/Components/ModelTable/BaseModelTableDeleteAndEmptyStates.test.tsx +341 -0
  202. package/Tests/UI/Components/ModelTable/ColumnPreference.test.ts +89 -0
  203. package/Tests/UI/Components/NavBarCommandKGating.test.tsx +103 -8
  204. package/Tests/UI/Components/OrderedStatesList.test.tsx +5 -5
  205. package/Tests/UI/Components/PendingProjectInvitations.test.tsx +1 -1
  206. package/Tests/UI/Components/SideMenuItem.test.tsx +30 -0
  207. package/Tests/UI/Components/TableSortAndMobileColumns.test.tsx +195 -0
  208. package/Tests/UI/Components/XAxis.test.ts +270 -5
  209. package/Tests/UI/Components/XAxisDaylightSaving.test.ts +113 -0
  210. package/Tests/UI/Styles/ChartFocusRing.test.ts +153 -0
  211. package/Tests/UI/Styles/ChartFocusRingCoverage.test.tsx +377 -0
  212. package/Tests/UI/Styles/ThemeStylesheet.ts +162 -0
  213. package/Tests/UI/Utils/TableColumnsToCsv.test.ts +30 -0
  214. package/Tests/UI/Utils/UseDashboardTimeRangeZoom.test.tsx +187 -0
  215. package/Tests/Utils/Dashboard/DashboardResourceListSharedArgs.test.ts +302 -0
  216. package/Tests/Utils/Dashboard/DashboardTimeRangeZoom.test.ts +242 -0
  217. package/Tests/Utils/EnterpriseLicenseSeats.test.ts +507 -0
  218. package/Tests/Utils/Monitor/NetworkDeviceRoleCatalog.test.ts +981 -0
  219. package/Tests/Utils/Monitor/NetworkTopologyRoleCatalog.test.ts +865 -0
  220. package/Tests/Utils/NetworkDevice/DeviceRoleKeyUtil.test.ts +538 -0
  221. package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +951 -1
  222. package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +238 -0
  223. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +1056 -0
  224. package/Tests/Utils/NetworkDiscovery/ReverseDnsNameUtil.test.ts +882 -0
  225. package/Tests/Utils/Slo/SloEvaluation.test.ts +171 -0
  226. package/Tests/Utils/Slug.test.ts +61 -1
  227. package/Tests/jest.setup.ts +19 -0
  228. package/Types/Date.ts +39 -0
  229. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +61 -0
  230. package/Types/Monitor/SnmpMonitor/SnmpOidListUtil.ts +333 -0
  231. package/Types/NetworkDevice/DefaultNetworkDeviceRole.ts +145 -0
  232. package/Types/Permission.ts +141 -0
  233. package/Types/Rum/SessionReplay.ts +21 -0
  234. package/Types/Telemetry/SourceMap.ts +8 -0
  235. package/UI/Components/Charts/Area/AreaChart.tsx +7 -0
  236. package/UI/Components/Charts/Bar/BarChart.tsx +6 -0
  237. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +9 -1
  238. package/UI/Components/Charts/ChartLibrary/Annotations/AnnotationHoverCard.tsx +176 -0
  239. package/UI/Components/Charts/ChartLibrary/Annotations/AnnotationLayout.ts +745 -0
  240. package/UI/Components/Charts/ChartLibrary/Annotations/ChartAnnotationLayer.tsx +576 -0
  241. package/UI/Components/Charts/ChartLibrary/Annotations/UseChartAnnotations.tsx +204 -0
  242. package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +554 -545
  243. package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +337 -371
  244. package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +549 -540
  245. package/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.ts +7 -3
  246. package/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.ts +14 -3
  247. package/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.ts +13 -0
  248. package/UI/Components/Charts/Line/LineChart.tsx +7 -0
  249. package/UI/Components/Charts/Types/ChartEventKind.ts +13 -0
  250. package/UI/Components/Charts/Types/ReferenceRegionProps.ts +6 -0
  251. package/UI/Components/Charts/Types/TimeReferenceLineProps.ts +20 -3
  252. package/UI/Components/Charts/Utils/TimeAnnotation.ts +69 -35
  253. package/UI/Components/Charts/Utils/XAxis.ts +125 -18
  254. package/UI/Components/EditionLabel/EditionLabel.tsx +280 -26
  255. package/UI/Components/ErrorMessage/ErrorMessage.tsx +21 -10
  256. package/UI/Components/Feed/FeedItem.tsx +4 -5
  257. package/UI/Components/Header/HeaderIconDropdownButton.tsx +1 -2
  258. package/UI/Components/Header/UserProfile/UserProfile.tsx +1 -2
  259. package/UI/Components/Image/Image.tsx +20 -3
  260. package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
  261. package/UI/Components/MemberRoleAssignment/MemberRoleAssignment.tsx +1 -2
  262. package/UI/Components/ModelTable/BaseModelTable.tsx +200 -39
  263. package/UI/Components/Navbar/NavBar.tsx +62 -13
  264. package/UI/Components/Navbar/NavBarMenuModal.tsx +7 -2
  265. package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +2 -0
  266. package/UI/Components/SideMenu/SideMenu.tsx +12 -2
  267. package/UI/Components/SideMenu/SideMenuItem.tsx +4 -1
  268. package/UI/Components/SideMenu/SideMenuSection.tsx +14 -2
  269. package/UI/Components/Table/TableHeader.tsx +64 -48
  270. package/UI/Components/Table/TableRow.tsx +13 -3
  271. package/UI/Styles/Theme.css +38 -0
  272. package/UI/Utils/UseDashboardTimeRangeZoom.ts +77 -0
  273. package/Utils/Dashboard/DashboardTimeRangeZoom.ts +118 -0
  274. package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +271 -0
  275. package/Utils/Monitor/NetworkDeviceRoleCatalog.ts +232 -0
  276. package/Utils/Monitor/NetworkDeviceRoleUtil.ts +2 -1
  277. package/Utils/Monitor/NetworkTopologyUtil.ts +116 -33
  278. package/Utils/NetworkDevice/DeviceRoleKeyUtil.ts +137 -0
  279. package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +6 -0
  280. package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +141 -10
  281. package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +55 -3
  282. package/Utils/NetworkDiscovery/ReverseDnsNameUtil.ts +151 -0
  283. package/Utils/Rules/RuleEngineLimits.ts +32 -0
  284. package/Utils/Rules/RulePatternMatchUtil.ts +1 -1
  285. package/Utils/Slug.ts +34 -1
  286. package/build/dist/Models/AnalyticsModels/SecurityEvent.js +48 -16
  287. package/build/dist/Models/AnalyticsModels/SecurityEvent.js.map +1 -1
  288. package/build/dist/Models/AnalyticsModels/ThreatIntelIndicator.js +10 -5
  289. package/build/dist/Models/AnalyticsModels/ThreatIntelIndicator.js.map +1 -1
  290. package/build/dist/Models/DatabaseModels/AlertSeverity.js +46 -1
  291. package/build/dist/Models/DatabaseModels/AlertSeverity.js.map +1 -1
  292. package/build/dist/Models/DatabaseModels/AlertState.js +0 -2
  293. package/build/dist/Models/DatabaseModels/AlertState.js.map +1 -1
  294. package/build/dist/Models/DatabaseModels/DetectionRule.js +16 -5
  295. package/build/dist/Models/DatabaseModels/DetectionRule.js.map +1 -1
  296. package/build/dist/Models/DatabaseModels/Domain.js +1 -1
  297. package/build/dist/Models/DatabaseModels/Domain.js.map +1 -1
  298. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js +14 -5
  299. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js.map +1 -1
  300. package/build/dist/Models/DatabaseModels/Incident.js +1 -1
  301. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  302. package/build/dist/Models/DatabaseModels/IncidentSeverity.js +46 -1
  303. package/build/dist/Models/DatabaseModels/IncidentSeverity.js.map +1 -1
  304. package/build/dist/Models/DatabaseModels/IncidentTemplate.js +1 -1
  305. package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
  306. package/build/dist/Models/DatabaseModels/Index.js +4 -0
  307. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  308. package/build/dist/Models/DatabaseModels/MetricType.js +0 -2
  309. package/build/dist/Models/DatabaseModels/MetricType.js.map +1 -1
  310. package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js +0 -2
  311. package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js.map +1 -1
  312. package/build/dist/Models/DatabaseModels/MonitorTest.js +0 -2
  313. package/build/dist/Models/DatabaseModels/MonitorTest.js.map +1 -1
  314. package/build/dist/Models/DatabaseModels/NetworkDevice.js +239 -6
  315. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  316. package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js +88 -0
  317. package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js.map +1 -1
  318. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  319. package/build/dist/Models/DatabaseModels/NetworkDeviceOidTemplate.js +521 -0
  320. package/build/dist/Models/DatabaseModels/NetworkDeviceOidTemplate.js.map +1 -0
  321. package/build/dist/Models/DatabaseModels/NetworkDeviceRole.js +677 -0
  322. package/build/dist/Models/DatabaseModels/NetworkDeviceRole.js.map +1 -0
  323. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +1 -1
  324. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  325. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js +1 -1
  326. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js.map +1 -1
  327. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +0 -2
  328. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  329. package/build/dist/Models/DatabaseModels/StatusPageAnnouncementTemplate.js +0 -2
  330. package/build/dist/Models/DatabaseModels/StatusPageAnnouncementTemplate.js.map +1 -1
  331. package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js +0 -2
  332. package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js.map +1 -1
  333. package/build/dist/Models/DatabaseModels/StatusPageResource.js +0 -2
  334. package/build/dist/Models/DatabaseModels/StatusPageResource.js.map +1 -1
  335. package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js +0 -2
  336. package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js.map +1 -1
  337. package/build/dist/Models/DatabaseModels/ThreatIntelFeed.js +16 -5
  338. package/build/dist/Models/DatabaseModels/ThreatIntelFeed.js.map +1 -1
  339. package/build/dist/Server/API/GlobalConfigAPI.js +293 -176
  340. package/build/dist/Server/API/GlobalConfigAPI.js.map +1 -1
  341. package/build/dist/Server/API/TelemetryAPI.js +31 -3
  342. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  343. package/build/dist/Server/EnvironmentConfig.js +83 -0
  344. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  345. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790500000000-AddNetworkDeviceOidTemplate.js +26 -0
  346. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790500000000-AddNetworkDeviceOidTemplate.js.map +1 -0
  347. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790600000000-AddAutoImportRuleOidTemplate.js +14 -0
  348. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790600000000-AddAutoImportRuleOidTemplate.js.map +1 -0
  349. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790800000000-AddNetworkDeviceRoleTable.js +39 -0
  350. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790800000000-AddNetworkDeviceRoleTable.js.map +1 -0
  351. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  352. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  353. package/build/dist/Server/Middleware/MultipartFormData.js +93 -28
  354. package/build/dist/Server/Middleware/MultipartFormData.js.map +1 -1
  355. package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js +8 -1
  356. package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js.map +1 -1
  357. package/build/dist/Server/Services/AlertEpisodeOnCallRuleEngineService.js +8 -1
  358. package/build/dist/Server/Services/AlertEpisodeOnCallRuleEngineService.js.map +1 -1
  359. package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js +8 -1
  360. package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js.map +1 -1
  361. package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js +8 -1
  362. package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js.map +1 -1
  363. package/build/dist/Server/Services/AlertGroupingEngineService.js +8 -1
  364. package/build/dist/Server/Services/AlertGroupingEngineService.js.map +1 -1
  365. package/build/dist/Server/Services/AlertLabelRuleEngineService.js +8 -1
  366. package/build/dist/Server/Services/AlertLabelRuleEngineService.js.map +1 -1
  367. package/build/dist/Server/Services/AlertOnCallRuleEngineService.js +8 -1
  368. package/build/dist/Server/Services/AlertOnCallRuleEngineService.js.map +1 -1
  369. package/build/dist/Server/Services/AlertOwnerRuleEngineService.js +8 -1
  370. package/build/dist/Server/Services/AlertOwnerRuleEngineService.js.map +1 -1
  371. package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js +8 -1
  372. package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js.map +1 -1
  373. package/build/dist/Server/Services/AlertReminderRuleService.js +8 -1
  374. package/build/dist/Server/Services/AlertReminderRuleService.js.map +1 -1
  375. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +8 -1
  376. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
  377. package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js +8 -1
  378. package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js.map +1 -1
  379. package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js +8 -1
  380. package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js.map +1 -1
  381. package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js +8 -1
  382. package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js.map +1 -1
  383. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js +8 -1
  384. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js.map +1 -1
  385. package/build/dist/Server/Services/DashboardLabelRuleEngineService.js +8 -1
  386. package/build/dist/Server/Services/DashboardLabelRuleEngineService.js.map +1 -1
  387. package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js +8 -1
  388. package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js.map +1 -1
  389. package/build/dist/Server/Services/DatabaseService.js +31 -5
  390. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  391. package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js +8 -1
  392. package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js.map +1 -1
  393. package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js +8 -1
  394. package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js.map +1 -1
  395. package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js +8 -1
  396. package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js.map +1 -1
  397. package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js +8 -1
  398. package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js.map +1 -1
  399. package/build/dist/Server/Services/HostLabelRuleEngineService.js +8 -1
  400. package/build/dist/Server/Services/HostLabelRuleEngineService.js.map +1 -1
  401. package/build/dist/Server/Services/HostOwnerRuleEngineService.js +8 -1
  402. package/build/dist/Server/Services/HostOwnerRuleEngineService.js.map +1 -1
  403. package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js +8 -1
  404. package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js.map +1 -1
  405. package/build/dist/Server/Services/IncidentEpisodeOnCallRuleEngineService.js +8 -1
  406. package/build/dist/Server/Services/IncidentEpisodeOnCallRuleEngineService.js.map +1 -1
  407. package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js +8 -1
  408. package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js.map +1 -1
  409. package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js +8 -1
  410. package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js.map +1 -1
  411. package/build/dist/Server/Services/IncidentGroupingEngineService.js +8 -1
  412. package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
  413. package/build/dist/Server/Services/IncidentLabelRuleEngineService.js +8 -1
  414. package/build/dist/Server/Services/IncidentLabelRuleEngineService.js.map +1 -1
  415. package/build/dist/Server/Services/IncidentOnCallRuleEngineService.js +8 -1
  416. package/build/dist/Server/Services/IncidentOnCallRuleEngineService.js.map +1 -1
  417. package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js +8 -1
  418. package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js.map +1 -1
  419. package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js +8 -1
  420. package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js.map +1 -1
  421. package/build/dist/Server/Services/IncidentReminderRuleService.js +8 -1
  422. package/build/dist/Server/Services/IncidentReminderRuleService.js.map +1 -1
  423. package/build/dist/Server/Services/IncidentSlaRuleService.js +8 -1
  424. package/build/dist/Server/Services/IncidentSlaRuleService.js.map +1 -1
  425. package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js +8 -1
  426. package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js.map +1 -1
  427. package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js +8 -1
  428. package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js.map +1 -1
  429. package/build/dist/Server/Services/Index.js +4 -0
  430. package/build/dist/Server/Services/Index.js.map +1 -1
  431. package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js +8 -1
  432. package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js.map +1 -1
  433. package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js +8 -1
  434. package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js.map +1 -1
  435. package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js +8 -1
  436. package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js.map +1 -1
  437. package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js +8 -1
  438. package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js.map +1 -1
  439. package/build/dist/Server/Services/KubernetesResourceService.js +5 -1
  440. package/build/dist/Server/Services/KubernetesResourceService.js.map +1 -1
  441. package/build/dist/Server/Services/MonitorLabelRuleEngineService.js +8 -1
  442. package/build/dist/Server/Services/MonitorLabelRuleEngineService.js.map +1 -1
  443. package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js +8 -1
  444. package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js.map +1 -1
  445. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +30 -21
  446. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  447. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +64 -0
  448. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
  449. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js +8 -1
  450. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js.map +1 -1
  451. package/build/dist/Server/Services/NetworkDeviceOidTemplateService.js +180 -0
  452. package/build/dist/Server/Services/NetworkDeviceOidTemplateService.js.map +1 -0
  453. package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js +8 -1
  454. package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js.map +1 -1
  455. package/build/dist/Server/Services/NetworkDeviceRoleService.js +70 -0
  456. package/build/dist/Server/Services/NetworkDeviceRoleService.js.map +1 -0
  457. package/build/dist/Server/Services/NetworkDeviceService.js +154 -1
  458. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  459. package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js +8 -1
  460. package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js.map +1 -1
  461. package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js +8 -1
  462. package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js.map +1 -1
  463. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js +8 -1
  464. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js.map +1 -1
  465. package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js +8 -1
  466. package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js.map +1 -1
  467. package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js +8 -1
  468. package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js.map +1 -1
  469. package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js +8 -1
  470. package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js.map +1 -1
  471. package/build/dist/Server/Services/ProjectService.js +65 -0
  472. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  473. package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js +8 -1
  474. package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js.map +1 -1
  475. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js +8 -1
  476. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js.map +1 -1
  477. package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js +8 -1
  478. package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js.map +1 -1
  479. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js +8 -1
  480. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js.map +1 -1
  481. package/build/dist/Server/Services/RunbookLabelRuleEngineService.js +8 -1
  482. package/build/dist/Server/Services/RunbookLabelRuleEngineService.js.map +1 -1
  483. package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js +8 -1
  484. package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js.map +1 -1
  485. package/build/dist/Server/Services/RunbookRuleEngineService.js +8 -1
  486. package/build/dist/Server/Services/RunbookRuleEngineService.js.map +1 -1
  487. package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js +8 -1
  488. package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js.map +1 -1
  489. package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js +8 -1
  490. package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js.map +1 -1
  491. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js +8 -1
  492. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js.map +1 -1
  493. package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js +8 -1
  494. package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js.map +1 -1
  495. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js +8 -1
  496. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js.map +1 -1
  497. package/build/dist/Server/Services/ServiceLabelRuleEngineService.js +8 -1
  498. package/build/dist/Server/Services/ServiceLabelRuleEngineService.js.map +1 -1
  499. package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js +8 -1
  500. package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js.map +1 -1
  501. package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js +8 -1
  502. package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js.map +1 -1
  503. package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js +6 -0
  504. package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js.map +1 -1
  505. package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js +8 -1
  506. package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js.map +1 -1
  507. package/build/dist/Server/Services/TelemetrySourceMapService.js +213 -19
  508. package/build/dist/Server/Services/TelemetrySourceMapService.js.map +1 -1
  509. package/build/dist/Server/Services/UserNotificationSettingService.js +0 -1
  510. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  511. package/build/dist/Server/Services/UserService.js +25 -0
  512. package/build/dist/Server/Services/UserService.js.map +1 -1
  513. package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js +8 -1
  514. package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js.map +1 -1
  515. package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js +8 -1
  516. package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js.map +1 -1
  517. package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js +145 -0
  518. package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js.map +1 -0
  519. package/build/dist/Server/Utils/Monitor/CapturedMetricAttributeUtil.js +201 -0
  520. package/build/dist/Server/Utils/Monitor/CapturedMetricAttributeUtil.js.map +1 -0
  521. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +19 -2
  522. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  523. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +42 -23
  524. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  525. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +29 -0
  526. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  527. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +11 -2
  528. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
  529. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +16 -1
  530. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -1
  531. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +10 -0
  532. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  533. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +33 -0
  534. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
  535. package/build/dist/Server/Utils/Rules/RuleEngineRuleRead.js +37 -0
  536. package/build/dist/Server/Utils/Rules/RuleEngineRuleRead.js.map +1 -0
  537. package/build/dist/Server/Utils/Telemetry/ExceptionSanitizer.js +12 -1
  538. package/build/dist/Server/Utils/Telemetry/ExceptionSanitizer.js.map +1 -1
  539. package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js +14 -2
  540. package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js.map +1 -1
  541. package/build/dist/Server/Utils/Telemetry/SourceMapResolver.js +15 -5
  542. package/build/dist/Server/Utils/Telemetry/SourceMapResolver.js.map +1 -1
  543. package/build/dist/Server/Utils/Telemetry/StackTraceParser.js +307 -0
  544. package/build/dist/Server/Utils/Telemetry/StackTraceParser.js.map +1 -1
  545. package/build/dist/Types/Date.js +27 -0
  546. package/build/dist/Types/Date.js.map +1 -1
  547. package/build/dist/Types/Monitor/SnmpMonitor/SnmpOidListUtil.js +253 -0
  548. package/build/dist/Types/Monitor/SnmpMonitor/SnmpOidListUtil.js.map +1 -0
  549. package/build/dist/Types/NetworkDevice/DefaultNetworkDeviceRole.js +105 -0
  550. package/build/dist/Types/NetworkDevice/DefaultNetworkDeviceRole.js.map +1 -0
  551. package/build/dist/Types/Permission.js +126 -0
  552. package/build/dist/Types/Permission.js.map +1 -1
  553. package/build/dist/Types/Rum/SessionReplay.js +19 -0
  554. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  555. package/build/dist/UI/Components/Charts/Area/AreaChart.js +1 -1
  556. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  557. package/build/dist/UI/Components/Charts/Bar/BarChart.js +1 -1
  558. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  559. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +6 -1
  560. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  561. package/build/dist/UI/Components/Charts/ChartLibrary/Annotations/AnnotationHoverCard.js +83 -0
  562. package/build/dist/UI/Components/Charts/ChartLibrary/Annotations/AnnotationHoverCard.js.map +1 -0
  563. package/build/dist/UI/Components/Charts/ChartLibrary/Annotations/AnnotationLayout.js +531 -0
  564. package/build/dist/UI/Components/Charts/ChartLibrary/Annotations/AnnotationLayout.js.map +1 -0
  565. package/build/dist/UI/Components/Charts/ChartLibrary/Annotations/ChartAnnotationLayer.js +264 -0
  566. package/build/dist/UI/Components/Charts/ChartLibrary/Annotations/ChartAnnotationLayer.js.map +1 -0
  567. package/build/dist/UI/Components/Charts/ChartLibrary/Annotations/UseChartAnnotations.js +122 -0
  568. package/build/dist/UI/Components/Charts/ChartLibrary/Annotations/UseChartAnnotations.js.map +1 -0
  569. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +262 -234
  570. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
  571. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +146 -153
  572. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
  573. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +261 -233
  574. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
  575. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js +14 -0
  576. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js.map +1 -0
  577. package/build/dist/UI/Components/Charts/Line/LineChart.js +1 -1
  578. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  579. package/build/dist/UI/Components/Charts/Types/ChartEventKind.js +14 -0
  580. package/build/dist/UI/Components/Charts/Types/ChartEventKind.js.map +1 -0
  581. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +57 -28
  582. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -1
  583. package/build/dist/UI/Components/Charts/Utils/XAxis.js +103 -17
  584. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  585. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +198 -23
  586. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  587. package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js +15 -5
  588. package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js.map +1 -1
  589. package/build/dist/UI/Components/Feed/FeedItem.js +4 -5
  590. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  591. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +1 -2
  592. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
  593. package/build/dist/UI/Components/Header/UserProfile/UserProfile.js.map +1 -1
  594. package/build/dist/UI/Components/Image/Image.js +6 -1
  595. package/build/dist/UI/Components/Image/Image.js.map +1 -1
  596. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
  597. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
  598. package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js +1 -2
  599. package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js.map +1 -1
  600. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +143 -36
  601. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  602. package/build/dist/UI/Components/Navbar/NavBar.js +44 -9
  603. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  604. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +2 -2
  605. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  606. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +1 -1
  607. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
  608. package/build/dist/UI/Components/SideMenu/SideMenu.js +9 -6
  609. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  610. package/build/dist/UI/Components/SideMenu/SideMenuItem.js +1 -1
  611. package/build/dist/UI/Components/SideMenu/SideMenuItem.js.map +1 -1
  612. package/build/dist/UI/Components/SideMenu/SideMenuSection.js +7 -2
  613. package/build/dist/UI/Components/SideMenu/SideMenuSection.js.map +1 -1
  614. package/build/dist/UI/Components/Table/TableHeader.js +20 -22
  615. package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
  616. package/build/dist/UI/Components/Table/TableRow.js +13 -4
  617. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  618. package/build/dist/UI/Utils/UseDashboardTimeRangeZoom.js +42 -0
  619. package/build/dist/UI/Utils/UseDashboardTimeRangeZoom.js.map +1 -0
  620. package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js +74 -0
  621. package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js.map +1 -0
  622. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +153 -0
  623. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +1 -0
  624. package/build/dist/Utils/Monitor/NetworkDeviceRoleCatalog.js +126 -0
  625. package/build/dist/Utils/Monitor/NetworkDeviceRoleCatalog.js.map +1 -0
  626. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +2 -1
  627. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -1
  628. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +67 -32
  629. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  630. package/build/dist/Utils/NetworkDevice/DeviceRoleKeyUtil.js +114 -0
  631. package/build/dist/Utils/NetworkDevice/DeviceRoleKeyUtil.js.map +1 -0
  632. package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -1
  633. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +127 -7
  634. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
  635. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +50 -3
  636. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -1
  637. package/build/dist/Utils/NetworkDiscovery/ReverseDnsNameUtil.js +132 -0
  638. package/build/dist/Utils/NetworkDiscovery/ReverseDnsNameUtil.js.map +1 -0
  639. package/build/dist/Utils/Rules/RuleEngineLimits.js +31 -0
  640. package/build/dist/Utils/Rules/RuleEngineLimits.js.map +1 -0
  641. package/build/dist/Utils/Rules/RulePatternMatchUtil.js +1 -1
  642. package/build/dist/Utils/Slug.js +31 -1
  643. package/build/dist/Utils/Slug.js.map +1 -1
  644. package/jest.config.json +1 -0
  645. package/package.json +2 -2
@@ -0,0 +1,195 @@
1
+ import "@testing-library/jest-dom";
2
+ import { afterEach, describe, expect, jest, test } from "@jest/globals";
3
+ import { cleanup, fireEvent, render, screen } from "@testing-library/react";
4
+ import * as React from "react";
5
+ import Table from "../../../UI/Components/Table/Table";
6
+ import Columns from "../../../UI/Components/Table/Types/Columns";
7
+ import FieldType from "../../../UI/Components/Types/FieldType";
8
+ import SortOrder from "../../../Types/BaseDatabase/SortOrder";
9
+
10
+ /*
11
+ * Two things a table owes anyone not driving it with a mouse on a wide screen.
12
+ *
13
+ * Sorting was mouse-only: the handler sat on the <th>, which is not focusable
14
+ * and does not answer Enter or Space, even though aria-sort was already
15
+ * telling assistive technology the column WAS sortable. It sits on a button
16
+ * inside the header cell now.
17
+ *
18
+ * And `hideOnMobile` - about 200 column declarations across the product say
19
+ * it - was honoured by the header, the skeleton rows, and the desktop row, but
20
+ * not by the mobile card, which is the one layout it exists for.
21
+ */
22
+
23
+ jest.mock("react-i18next", () => {
24
+ return {
25
+ useTranslation: () => {
26
+ return {
27
+ t: (key: string, opts?: { defaultValue?: string }): string => {
28
+ return opts?.defaultValue ?? key;
29
+ },
30
+ };
31
+ },
32
+ };
33
+ });
34
+
35
+ interface Row {
36
+ _id?: string | undefined;
37
+ name?: string | undefined;
38
+ status?: string | undefined;
39
+ }
40
+
41
+ const columns: Columns<Row> = [
42
+ { title: "Name", type: FieldType.Text, key: "name" },
43
+ { title: "Status", type: FieldType.Text, key: "status", hideOnMobile: true },
44
+ // No key, so this one is not sortable and must stay a plain cell.
45
+ { title: "Notes", type: FieldType.Text },
46
+ ];
47
+
48
+ const data: Array<Row> = [
49
+ { _id: "1", name: "Alpha", status: "Up" },
50
+ { _id: "2", name: "Beta", status: "Down" },
51
+ ];
52
+
53
+ interface RenderTableOptions {
54
+ sortBy?: keyof Row | null | undefined;
55
+ sortOrder?: SortOrder | undefined;
56
+ onSortChanged?:
57
+ | ((sortBy: keyof Row | null, sortOrder: SortOrder) => void)
58
+ | undefined;
59
+ }
60
+
61
+ type RenderTableFunction = (options?: RenderTableOptions | undefined) => void;
62
+
63
+ const renderTable: RenderTableFunction = (
64
+ options?: RenderTableOptions | undefined,
65
+ ): void => {
66
+ render(
67
+ <Table<Row>
68
+ id="test-table"
69
+ data={data}
70
+ columns={columns}
71
+ currentPageNumber={1}
72
+ totalItemsCount={data.length}
73
+ itemsOnPage={10}
74
+ error=""
75
+ isLoading={false}
76
+ singularLabel="Monitor"
77
+ pluralLabel="Monitors"
78
+ sortOrder={options?.sortOrder ?? SortOrder.Ascending}
79
+ sortBy={options?.sortBy ?? null}
80
+ onSortChanged={options?.onSortChanged ?? (() => {})}
81
+ onNavigateToPage={() => {}}
82
+ />,
83
+ );
84
+ };
85
+
86
+ /*
87
+ * The table decides mobile vs desktop from window.innerWidth at mount
88
+ * (< 768 = mobile). jsdom defaults to 1024, so desktop is the baseline and
89
+ * mobile tests must set the width BEFORE rendering.
90
+ */
91
+ const setViewportWidth: (width: number) => void = (width: number): void => {
92
+ Object.defineProperty(window, "innerWidth", {
93
+ configurable: true,
94
+ writable: true,
95
+ value: width,
96
+ });
97
+ };
98
+
99
+ afterEach(() => {
100
+ cleanup();
101
+ setViewportWidth(1024);
102
+ });
103
+
104
+ describe("sortable column headers", () => {
105
+ test("a sortable header is a real button, so it is focusable", () => {
106
+ renderTable();
107
+
108
+ const sortButton: HTMLElement = screen.getByRole("button", {
109
+ name: "Name",
110
+ });
111
+
112
+ expect(sortButton.tagName).toBe("BUTTON");
113
+ expect(sortButton).toHaveAttribute("type", "button");
114
+
115
+ sortButton.focus();
116
+ expect(sortButton).toHaveFocus();
117
+ });
118
+
119
+ test("activating the header button sorts the column", () => {
120
+ const sortCalls: Array<[keyof Row | null, SortOrder]> = [];
121
+
122
+ renderTable({
123
+ onSortChanged: (sortBy: keyof Row | null, sortOrder: SortOrder) => {
124
+ sortCalls.push([sortBy, sortOrder]);
125
+ },
126
+ });
127
+
128
+ fireEvent.click(screen.getByRole("button", { name: "Name" }));
129
+
130
+ expect(sortCalls).toEqual([["name", SortOrder.Descending]]);
131
+ });
132
+
133
+ test("the sort direction still round-trips", () => {
134
+ const sortCalls: Array<[keyof Row | null, SortOrder]> = [];
135
+
136
+ renderTable({
137
+ sortBy: "name",
138
+ sortOrder: SortOrder.Descending,
139
+ onSortChanged: (sortBy: keyof Row | null, sortOrder: SortOrder) => {
140
+ sortCalls.push([sortBy, sortOrder]);
141
+ },
142
+ });
143
+
144
+ fireEvent.click(screen.getByRole("button", { name: /Name/ }));
145
+
146
+ expect(sortCalls).toEqual([["name", SortOrder.Ascending]]);
147
+ });
148
+
149
+ test("a column that cannot be sorted gets no button", () => {
150
+ renderTable();
151
+
152
+ expect(
153
+ screen.queryByRole("button", { name: "Notes" }),
154
+ ).not.toBeInTheDocument();
155
+ expect(screen.getByText("Notes")).toBeInTheDocument();
156
+ });
157
+
158
+ test("the header still announces sort state to assistive technology", () => {
159
+ renderTable({ sortBy: "name", sortOrder: SortOrder.Ascending });
160
+
161
+ const headers: Array<HTMLElement> = screen.getAllByRole("columnheader");
162
+ const nameHeader: HTMLElement | undefined = headers.find(
163
+ (header: HTMLElement) => {
164
+ return header.textContent?.includes("Name");
165
+ },
166
+ );
167
+
168
+ expect(nameHeader).toHaveAttribute("aria-sort", "ascending");
169
+ });
170
+ });
171
+
172
+ describe("hideOnMobile columns", () => {
173
+ test("the mobile card leaves out columns marked hideOnMobile", () => {
174
+ setViewportWidth(375);
175
+ renderTable();
176
+
177
+ // "Name" is shown on every breakpoint.
178
+ expect(screen.getAllByText("Alpha").length).toBeGreaterThan(0);
179
+
180
+ /*
181
+ * "Status" is hideOnMobile. Its header is already filtered out on mobile;
182
+ * the row used to render it anyway, which is the regression this pins.
183
+ */
184
+ expect(screen.queryByText("Up")).not.toBeInTheDocument();
185
+ expect(screen.queryByText("Down")).not.toBeInTheDocument();
186
+ });
187
+
188
+ test("the desktop row is untouched", () => {
189
+ setViewportWidth(1280);
190
+ renderTable();
191
+
192
+ expect(screen.getByText("Up")).toBeInTheDocument();
193
+ expect(screen.getByText("Down")).toBeInTheDocument();
194
+ });
195
+ });
@@ -1,18 +1,262 @@
1
- /** @timezone Europe/London */
1
+ /** @timezone UTC */
2
2
 
3
+ import { afterEach, describe, expect, test } from "@jest/globals";
4
+ import OneUptimeDate from "../../../Types/Date";
5
+ import Timezone from "../../../Types/Timezone";
6
+ import XAxisMaxMin from "../../../UI/Components/Charts/Types/XAxis/XAxisMaxMin";
7
+ import XAxisPrecision from "../../../UI/Components/Charts/Types/XAxis/XAxisPrecision";
3
8
  import XAxisUtil from "../../../UI/Components/Charts/Utils/XAxis";
4
9
 
5
- describe("XAxisUtil", () => {
6
- test("formats past-day chart labels in local BST time instead of UTC", () => {
10
+ /*
11
+ * A chart's x-axis label is the IDENTITY of its bucket, not decoration:
12
+ * DataPointUtil places a series row by finding the first row whose label
13
+ * matches, TimeAnnotationUtil resolves an event marker the same way, and
14
+ * recharts' categorical scale resolves no category at all once its domain
15
+ * holds a duplicate.
16
+ *
17
+ * These tests hold the property that makes all three safe — inside any one
18
+ * window, no two ticks may share a label — and the corollary that a window
19
+ * short enough not to need help keeps its short labels.
20
+ */
21
+
22
+ const HOUR_IN_MS: number = 60 * 60 * 1000;
23
+
24
+ const WINDOW_START: Date = new Date("2026-03-02T00:00:00.000Z");
25
+
26
+ function windowOf(
27
+ hours: number,
28
+ start: Date = WINDOW_START,
29
+ ): {
30
+ xAxisMin: XAxisMaxMin;
31
+ xAxisMax: XAxisMaxMin;
32
+ } {
33
+ return {
34
+ xAxisMin: start,
35
+ xAxisMax: new Date(start.getTime() + hours * HOUR_IN_MS),
36
+ };
37
+ }
38
+
39
+ function labelsFor(bounds: {
40
+ xAxisMin: XAxisMaxMin;
41
+ xAxisMax: XAxisMaxMin;
42
+ }): Array<string> {
43
+ const formatter: (value: Date) => string = XAxisUtil.getFormatter(bounds);
44
+ return XAxisUtil.getPrecisionIntervals(bounds).map((interval: Date) => {
45
+ return formatter(interval);
46
+ });
47
+ }
48
+
49
+ afterEach((): void => {
50
+ OneUptimeDate.setUserTimezone(null);
51
+ });
52
+
53
+ describe("XAxisUtil label uniqueness", () => {
54
+ test("a 24 hour window labels every one of its 97 ticks distinctly", () => {
55
+ /*
56
+ * The reported bug. A 24h window sits on the fifteen-minute tier and
57
+ * spans 97 interval starts, but a bare "HH:mm" only has 96 readings in
58
+ * a day — the first and last tick both read "00:00", so the last
59
+ * bucket's data and annotations were folded onto the first.
60
+ */
61
+ const bounds: ReturnType<typeof windowOf> = windowOf(24);
62
+
63
+ expect(XAxisUtil.getPrecision(bounds)).toBe(
64
+ XAxisPrecision.EVERY_FIFTEEN_MINUTES,
65
+ );
66
+
67
+ const labels: Array<string> = labelsFor(bounds);
68
+
69
+ expect(labels).toHaveLength(97);
70
+ expect(new Set(labels).size).toBe(97);
71
+ });
72
+
73
+ test("a 48 hour window labels every one of its 97 ticks distinctly", () => {
74
+ /*
75
+ * The severe case. A 48h window sits on the thirty-minute tier: 97
76
+ * interval starts over a bare "HH:mm" that has only 48 readings, so
77
+ * every label appeared exactly twice and the whole of day two merged
78
+ * onto day one.
79
+ */
80
+ const bounds: ReturnType<typeof windowOf> = windowOf(48);
81
+
82
+ expect(XAxisUtil.getPrecision(bounds)).toBe(
83
+ XAxisPrecision.EVERY_THIRTY_MINUTES,
84
+ );
85
+
86
+ const labels: Array<string> = labelsFor(bounds);
87
+
88
+ expect(labels).toHaveLength(97);
89
+ expect(new Set(labels).size).toBe(97);
90
+ });
91
+
92
+ test.each([
93
+ ["6 hours", 6, 73],
94
+ ["12 hours", 12, 145],
95
+ ["13 hours", 13, 53],
96
+ ["23 hours", 23, 93],
97
+ ["24 hours", 24, 97],
98
+ ["36 hours", 36, 73],
99
+ ["48 hours", 48, 97],
100
+ ["72 hours", 72, 145],
101
+ ["5 days", 120, 121],
102
+ ])(
103
+ "%s: no two ticks share a label",
104
+ (_name: string, hours: number, expectedTicks: number): void => {
105
+ const labels: Array<string> = labelsFor(windowOf(hours));
106
+
107
+ expect(labels).toHaveLength(expectedTicks);
108
+ expect(new Set(labels).size).toBe(labels.length);
109
+ },
110
+ );
111
+
112
+ test("no window across three days repeats a label, at any tier", () => {
113
+ /*
114
+ * The property itself, swept rather than sampled — including windows
115
+ * that start off a clean boundary, which is what a live "last N hours"
116
+ * range always does.
117
+ */
118
+ const start: Date = new Date("2026-03-02T07:23:00.000Z");
119
+ const repeating: Array<string> = [];
120
+
121
+ for (let minutes: number = 15; minutes <= 3 * 24 * 60; minutes += 97) {
122
+ const bounds: { xAxisMin: XAxisMaxMin; xAxisMax: XAxisMaxMin } = {
123
+ xAxisMin: start,
124
+ xAxisMax: new Date(start.getTime() + minutes * 60 * 1000),
125
+ };
126
+ const labels: Array<string> = labelsFor(bounds);
127
+ if (new Set(labels).size !== labels.length) {
128
+ repeating.push(
129
+ `${minutes}min: ${labels.length} ticks, ${new Set(labels).size} distinct`,
130
+ );
131
+ }
132
+ }
133
+
134
+ expect(repeating).toEqual([]);
135
+ });
136
+ });
137
+
138
+ describe("XAxisUtil label verbosity", () => {
139
+ test("a window that cannot wrap the clock keeps its bare time labels", () => {
140
+ /*
141
+ * The date is bought at the cost of nearly tripling the label width,
142
+ * so it is only spent where a bare reading would be ambiguous. 23h is
143
+ * the last window that cannot repeat one.
144
+ */
145
+ const labels: Array<string> = labelsFor(windowOf(23));
146
+
147
+ expect(labels[0]).toBe("00:00");
148
+ expect(labels[labels.length - 1]).toBe("23:00");
149
+ });
150
+
151
+ test("a window that can wrap the clock says which day each tick is", () => {
152
+ const labels: Array<string> = labelsFor(windowOf(48));
153
+
154
+ expect(labels[0]).toBe("02 Mar, 00:00");
155
+ expect(labels[labels.length - 1]).toBe("04 Mar, 00:00");
156
+ // The same clock reading on the two days is now two different labels.
157
+ expect(labels).toContain("03 Mar, 00:00");
158
+ });
159
+
160
+ test("the day-qualified form matches the shape the hourly tier already uses", () => {
161
+ /*
162
+ * EVERY_HOUR and every coarser tier have carried "DD MMM, HH:00" for
163
+ * this same reason all along, so the finer tiers borrow its shape
164
+ * rather than inventing one.
165
+ */
166
+ const hourly: Array<string> = labelsFor(windowOf(5 * 24));
167
+ const subHourly: Array<string> = labelsFor(windowOf(48));
168
+
169
+ expect(hourly[0]).toBe("02 Mar, 00:00");
170
+ expect(subHourly[0]).toBe("02 Mar, 00:00");
171
+ });
172
+ });
173
+
174
+ describe("XAxisUtil labels across a daylight saving transition", () => {
175
+ /*
176
+ * The browser reports UTC here (see the docblock) while the user has
177
+ * configured London — the normal case for anyone who has set a timezone,
178
+ * and the one where a transition in the configured zone is invisible to
179
+ * the interval walker.
180
+ */
181
+
182
+ test("clocks going back do not give two ticks the same label", () => {
183
+ /*
184
+ * On 2026-10-25 London runs 01:00-01:59 BST and then 01:00-01:59 GMT.
185
+ * A four hour window is nowhere near long enough to wrap the clock,
186
+ * but the replayed hour repeated twelve five-minute labels — and the
187
+ * date does not settle it either, since both readings are on the 25th.
188
+ */
189
+ OneUptimeDate.setUserTimezone("Europe/London" as Timezone);
190
+
191
+ const bounds: ReturnType<typeof windowOf> = windowOf(
192
+ 4,
193
+ new Date("2026-10-25T00:00:00.000Z"),
194
+ );
195
+ const labels: Array<string> = labelsFor(bounds);
196
+
197
+ expect(new Set(labels).size).toBe(labels.length);
198
+ expect(labels).toContain("25 Oct, 01:00 BST");
199
+ expect(labels).toContain("25 Oct, 01:00 GMT");
200
+ });
201
+
202
+ test("clocks going forward stay on the plain form", () => {
203
+ /*
204
+ * A spring-forward skips an hour rather than replaying one, so it
205
+ * cannot produce a duplicate and must not cost the axis any width.
206
+ */
207
+ OneUptimeDate.setUserTimezone("Europe/London" as Timezone);
208
+
209
+ const bounds: ReturnType<typeof windowOf> = windowOf(
210
+ 4,
211
+ new Date("2026-03-29T00:00:00.000Z"),
212
+ );
213
+ const labels: Array<string> = labelsFor(bounds);
214
+
215
+ expect(new Set(labels).size).toBe(labels.length);
216
+ for (const label of labels) {
217
+ expect(label).toMatch(/^\d{2}:\d{2}$/);
218
+ }
219
+ });
220
+
221
+ test("an ordinary window in the same zone is untouched", () => {
222
+ OneUptimeDate.setUserTimezone("Europe/London" as Timezone);
223
+
224
+ const labels: Array<string> = labelsFor(
225
+ windowOf(6, new Date("2026-06-01T00:00:00.000Z")),
226
+ );
227
+
228
+ expect(new Set(labels).size).toBe(labels.length);
229
+ expect(labels[0]).toBe("01:00");
230
+ });
231
+ });
232
+
233
+ describe("XAxisUtil formats in the configured timezone", () => {
234
+ test("past-day labels read in local BST time instead of UTC", () => {
235
+ OneUptimeDate.setUserTimezone("Europe/London" as Timezone);
236
+
7
237
  const formatter: (value: Date) => string = XAxisUtil.getFormatter({
8
238
  xAxisMin: new Date("2026-04-06T14:00:00.000Z"),
9
239
  xAxisMax: new Date("2026-04-07T14:00:00.000Z"),
10
240
  });
11
241
 
12
242
  /*
13
- * A 24h window now uses the fifteen-minute precision tier, whose labels
14
- * are local wall-clock times: 07:30 UTC is 08:30 in BST.
243
+ * A 24h window uses the fifteen-minute tier, and is exactly long
244
+ * enough to wrap the clock so the label carries its day. 07:30 UTC
245
+ * is 08:30 BST on the 7th.
15
246
  */
247
+ expect(formatter(new Date("2026-04-07T07:30:00.000Z"))).toBe(
248
+ "07 Apr, 08:30",
249
+ );
250
+ });
251
+
252
+ test("a window too short to wrap still reads in local BST time", () => {
253
+ OneUptimeDate.setUserTimezone("Europe/London" as Timezone);
254
+
255
+ const formatter: (value: Date) => string = XAxisUtil.getFormatter({
256
+ xAxisMin: new Date("2026-04-07T02:00:00.000Z"),
257
+ xAxisMax: new Date("2026-04-07T14:00:00.000Z"),
258
+ });
259
+
16
260
  expect(formatter(new Date("2026-04-07T07:30:00.000Z"))).toBe("08:30");
17
261
  });
18
262
 
@@ -28,4 +272,25 @@ describe("XAxisUtil", () => {
28
272
 
29
273
  expect(originalDate.toISOString()).toBe("2026-04-07T07:30:45.000Z");
30
274
  });
275
+
276
+ test("the weekly tier reads its day and its month in the same zone", () => {
277
+ /*
278
+ * These used to be mixed inside one label — the day came from the
279
+ * browser's clock and the month from the configured one — so a tick
280
+ * near midnight could report a day from one date and a month from
281
+ * another.
282
+ */
283
+ OneUptimeDate.setUserTimezone("Pacific/Auckland" as Timezone);
284
+
285
+ const formatter: (value: Date) => string = XAxisUtil.getFormatter({
286
+ xAxisMin: new Date("2026-01-01T00:00:00.000Z"),
287
+ xAxisMax: new Date("2026-03-01T00:00:00.000Z"),
288
+ });
289
+
290
+ /*
291
+ * 31 Jan 23:00 UTC is already 1 Feb in Auckland (UTC+13). Both halves
292
+ * of the label have to agree on that.
293
+ */
294
+ expect(formatter(new Date("2026-01-31T23:00:00.000Z"))).toBe("01 Feb");
295
+ });
31
296
  });
@@ -0,0 +1,113 @@
1
+ /** @timezone Europe/London */
2
+
3
+ import { describe, expect, test } from "@jest/globals";
4
+ import XAxisMaxMin from "../../../UI/Components/Charts/Types/XAxis/XAxisMaxMin";
5
+ import XAxisUtil from "../../../UI/Components/Charts/Utils/XAxis";
6
+
7
+ /*
8
+ * The daylight-saving half of the label-uniqueness property, in the OTHER
9
+ * of the two configurations it has to hold in.
10
+ *
11
+ * OneUptimeDate.getCurrentTimezone() is `userTimezone || moment.tz.guess()`,
12
+ * so a user who has never opened User Settings reads dates in the zone the
13
+ * browser reports — the configured and browser zones are the SAME. That is
14
+ * this file (the docblock sets both to London). XAxis.test.ts covers the
15
+ * other configuration, where a user has picked a zone the browser does not
16
+ * report.
17
+ *
18
+ * The two behave differently and both need holding: the interval walker
19
+ * steps in browser wall-clock time, so when the zones agree it walks
20
+ * straight over the repeated hour and never emits it twice, while when
21
+ * they differ the transition is invisible to it and the hour is emitted
22
+ * twice over.
23
+ */
24
+
25
+ const WINDOW_START: Date = new Date("2026-10-25T00:00:00.000Z");
26
+
27
+ /*
28
+ * London's 2026 fall-back: 02:00 BST becomes 01:00 GMT, so 01:00-01:59
29
+ * is a wall-clock reading that names two different instants that day.
30
+ */
31
+ const FOUR_HOURS_ACROSS_THE_FALL_BACK: {
32
+ xAxisMin: XAxisMaxMin;
33
+ xAxisMax: XAxisMaxMin;
34
+ } = {
35
+ xAxisMin: WINDOW_START,
36
+ xAxisMax: new Date(WINDOW_START.getTime() + 4 * 60 * 60 * 1000),
37
+ };
38
+
39
+ function labelsFor(bounds: {
40
+ xAxisMin: XAxisMaxMin;
41
+ xAxisMax: XAxisMaxMin;
42
+ }): Array<string> {
43
+ const formatter: (value: Date) => string = XAxisUtil.getFormatter(bounds);
44
+ return XAxisUtil.getPrecisionIntervals(bounds).map((interval: Date) => {
45
+ return formatter(interval);
46
+ });
47
+ }
48
+
49
+ /** The zone London is really in at `date`, straight from the platform. */
50
+ function actualZoneAbbr(date: Date): string {
51
+ return (
52
+ new Intl.DateTimeFormat("en-GB", {
53
+ timeZone: "Europe/London",
54
+ timeZoneName: "short",
55
+ })
56
+ .formatToParts(date)
57
+ .find((part: Intl.DateTimeFormatPart): boolean => {
58
+ return part.type === "timeZoneName";
59
+ })?.value || ""
60
+ );
61
+ }
62
+
63
+ describe("a fall-back window when the browser and configured zones agree", () => {
64
+ test("no two ticks share a label", () => {
65
+ const labels: Array<string> = labelsFor(FOUR_HOURS_ACROSS_THE_FALL_BACK);
66
+
67
+ expect(new Set(labels).size).toBe(labels.length);
68
+ });
69
+
70
+ test("every tick names the zone it is really in", () => {
71
+ /*
72
+ * The labels carry a zone abbreviation here, and an abbreviation that
73
+ * lied would be worse than none — a reader would take an instant for
74
+ * one an hour away. Checked against the platform's own answer rather
75
+ * than against our formatter.
76
+ */
77
+ const intervals: Array<Date> = XAxisUtil.getPrecisionIntervals(
78
+ FOUR_HOURS_ACROSS_THE_FALL_BACK,
79
+ );
80
+ const labels: Array<string> = labelsFor(FOUR_HOURS_ACROSS_THE_FALL_BACK);
81
+
82
+ for (let index: number = 0; index < intervals.length; index++) {
83
+ expect(labels[index]).toContain(actualZoneAbbr(intervals[index]!));
84
+ }
85
+ });
86
+
87
+ test("the transition reads straight through, BST into GMT", () => {
88
+ const labels: Array<string> = labelsFor(FOUR_HOURS_ACROSS_THE_FALL_BACK);
89
+
90
+ /*
91
+ * Stepping wall-clock minutes in the browser's own zone walks over the
92
+ * repeated hour rather than through it, so the axis never holds both
93
+ * 01:30s. It still says which side of the change each tick is on.
94
+ */
95
+ expect(labels).toContain("25 Oct, 01:55 BST");
96
+ expect(labels).toContain("25 Oct, 02:00 GMT");
97
+ expect(labels).not.toContain("25 Oct, 01:00 GMT");
98
+ });
99
+
100
+ test("an ordinary window in the same zone keeps its bare labels", () => {
101
+ // No transition, well under a day: nothing to disambiguate, nothing spent.
102
+ const summer: Date = new Date("2026-06-01T00:00:00.000Z");
103
+ const labels: Array<string> = labelsFor({
104
+ xAxisMin: summer,
105
+ xAxisMax: new Date(summer.getTime() + 6 * 60 * 60 * 1000),
106
+ });
107
+
108
+ expect(new Set(labels).size).toBe(labels.length);
109
+ for (const label of labels) {
110
+ expect(label).toMatch(/^\d{2}:\d{2}$/);
111
+ }
112
+ });
113
+ });