@oneuptime/common 12.0.32 → 12.0.33

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 (597) hide show
  1. package/Models/AnalyticsModels/Span.ts +14 -0
  2. package/Models/DatabaseModels/EnterpriseLicense.ts +56 -0
  3. package/Models/DatabaseModels/Index.ts +10 -0
  4. package/Models/DatabaseModels/Monitor.ts +76 -0
  5. package/Models/DatabaseModels/NetworkAlertPolicy.ts +690 -0
  6. package/Models/DatabaseModels/NetworkDevice.ts +176 -1
  7. package/Models/DatabaseModels/NetworkSite.ts +201 -2
  8. package/Models/DatabaseModels/NetworkSiteType.ts +102 -3
  9. package/Models/DatabaseModels/NetworkSnmpCredentialProfile.ts +841 -0
  10. package/Models/DatabaseModels/TelemetryException.ts +119 -0
  11. package/Models/DatabaseModels/UserNotificationEmailRollupBatch.ts +334 -0
  12. package/Models/DatabaseModels/UserNotificationEmailRollupItem.ts +370 -0
  13. package/Models/DatabaseModels/UserNotificationEmailRollupSetting.ts +282 -0
  14. package/Server/API/EnterpriseLicenseAPI.ts +391 -64
  15. package/Server/API/LlmProviderAPI.ts +137 -22
  16. package/Server/EnvironmentConfig.ts +14 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.ts +55 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.ts +31 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.ts +124 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.ts +132 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.ts +79 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.ts +191 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
  24. package/Server/Infrastructure/QueueWorker.ts +38 -8
  25. package/Server/Middleware/BearerTokenAuthorization.ts +12 -0
  26. package/Server/Middleware/ProjectAuthorization.ts +11 -0
  27. package/Server/Middleware/SCIMAuthorization.ts +12 -0
  28. package/Server/Middleware/TelemetryIngest.ts +11 -0
  29. package/Server/Services/AIBillingService.ts +101 -27
  30. package/Server/Services/EnterpriseLicenseInstanceService.ts +197 -0
  31. package/Server/Services/EnterpriseLicenseService.ts +55 -0
  32. package/Server/Services/Index.ts +10 -0
  33. package/Server/Services/MonitorService.ts +143 -21
  34. package/Server/Services/MonitorStatusTimelineService.ts +150 -8
  35. package/Server/Services/MonitorTemplateService.ts +217 -1
  36. package/Server/Services/NetworkAlertPolicyEngineService.ts +2159 -0
  37. package/Server/Services/NetworkAlertPolicyService.ts +944 -0
  38. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +9 -10
  39. package/Server/Services/NetworkDeviceAutoImportRuleService.ts +60 -15
  40. package/Server/Services/NetworkDeviceService.ts +1032 -73
  41. package/Server/Services/NetworkSiteService.ts +1502 -129
  42. package/Server/Services/NetworkSiteTypeService.ts +1216 -0
  43. package/Server/Services/NetworkSnmpCredentialProfileService.ts +238 -0
  44. package/Server/Services/NotificationService.ts +118 -28
  45. package/Server/Services/ProjectService.ts +105 -48
  46. package/Server/Services/StatusPagePrivateUserService.ts +103 -3
  47. package/Server/Services/UserNotificationEmailRollupBatchService.ts +78 -0
  48. package/Server/Services/UserNotificationEmailRollupItemService.ts +79 -0
  49. package/Server/Services/UserNotificationEmailRollupSettingService.ts +113 -0
  50. package/Server/Services/UserNotificationSettingService.ts +62 -25
  51. package/Server/Services/UserService.ts +95 -0
  52. package/Server/Types/Database/QueryHelper.ts +2 -2
  53. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +14 -3
  54. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +10 -0
  55. package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +10 -0
  56. package/Server/Utils/AI/SRE/Insights/InsightTriageRunner.ts +62 -1
  57. package/Server/Utils/AI/Toolbox/AlertTools.ts +15 -1
  58. package/Server/Utils/Billing/BillingFailureNoticeThrottle.ts +80 -0
  59. package/Server/Utils/DataSource/HttpFetch.ts +9 -2
  60. package/Server/Utils/EmailRollup/EmailRollupConstants.ts +98 -0
  61. package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +872 -0
  62. package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +781 -0
  63. package/Server/Utils/EmailRollup/EmailRollupWriter.ts +368 -0
  64. package/Server/Utils/LLM/LLMService.ts +78 -0
  65. package/Server/Utils/LogRedaction.ts +8 -0
  66. package/Server/Utils/Logger.ts +79 -1
  67. package/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.ts +190 -0
  68. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +9 -2
  69. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +61 -1
  70. package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +14 -0
  71. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +49 -0
  72. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +255 -4
  73. package/Server/Utils/Monitor/MonitorMetricUtil.ts +41 -0
  74. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +43 -0
  75. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +499 -19
  76. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +66 -10
  77. package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +238 -44
  78. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +146 -39
  79. package/Server/Utils/NetworkDevice/DeviceHealthAggregation.ts +31 -18
  80. package/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.ts +213 -0
  81. package/Server/Utils/OutboundUserAgent.ts +152 -0
  82. package/Server/Utils/StartServer.ts +51 -19
  83. package/Server/Utils/Telemetry/CaptureSpan.ts +32 -8
  84. package/Server/Utils/Telemetry/ErrorClassResolver.ts +120 -0
  85. package/Server/Utils/Telemetry/SpanUtil.ts +33 -0
  86. package/Server/Utils/Telemetry.ts +198 -51
  87. package/Server/Views/Partials/SensitiveUrlToken.ejs +140 -0
  88. package/Tests/App/Dashboard/AddNeighborToMonitoringModal.test.tsx +134 -33
  89. package/Tests/App/Dashboard/AskAiSuggestedPrompts.test.ts +279 -0
  90. package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +517 -0
  91. package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +26 -0
  92. package/Tests/App/Dashboard/DeviceStatusHero.test.tsx +588 -0
  93. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +18 -9
  94. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +632 -0
  95. package/Tests/App/Dashboard/MonitorRecommendationCreateProgress.test.tsx +682 -0
  96. package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +4 -2
  97. package/Tests/App/Dashboard/NetworkDeviceCreateFormMonitorBinding.test.tsx +676 -0
  98. package/Tests/App/Dashboard/NetworkDeviceCreateFormPingMonitor.test.tsx +791 -0
  99. package/Tests/App/Dashboard/NetworkDeviceCreateFormProbeAndSnmp.test.tsx +833 -0
  100. package/Tests/App/Dashboard/NetworkDeviceCriteriaFilter.test.ts +161 -0
  101. package/Tests/App/Dashboard/NetworkDeviceSettingsMonitoringSection.test.tsx +458 -0
  102. package/Tests/App/Dashboard/NetworkSideMenu.test.tsx +41 -5
  103. package/Tests/App/Dashboard/PingMonitorProvisioning.test.ts +368 -0
  104. package/Tests/App/Dashboard/RecommendationCard.test.tsx +796 -0
  105. package/Tests/App/Dashboard/RecommendationToolbar.test.tsx +519 -0
  106. package/Tests/App/Dashboard/RecommendationsList.test.tsx +661 -0
  107. package/Tests/App/Dashboard/UseBulkCreatePingMonitors.test.tsx +899 -0
  108. package/Tests/App/Dashboard/UseBulkSnmpCredentialProfileActions.test.tsx +732 -0
  109. package/Tests/App/SensitiveUrlTokenBootstrap.test.ts +256 -0
  110. package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +11 -1
  111. package/Tests/App/StatusPage/StatusPageLoginCodeBootstrap.test.ts +9 -4
  112. package/Tests/Models/NetworkSiteHierarchy.test.ts +41 -4
  113. package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +951 -7
  114. package/Tests/Server/API/LlmProviderConnectionTest.test.ts +522 -0
  115. package/Tests/Server/Infrastructure/Postgres/NetworkSnmpCredentialProfilesAndAlertPoliciesMigration.test.ts +854 -0
  116. package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +18 -0
  117. package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupTableMigration.test.ts +535 -0
  118. package/Tests/Server/Services/AIChatPrivacyPin.test.ts +560 -0
  119. package/Tests/Server/Services/BillingRechargeOwnerEmailGuards.test.ts +783 -0
  120. package/Tests/Server/Services/EnterpriseLicenseInstanceServiceDeletionUsage.test.ts +707 -0
  121. package/Tests/Server/Services/EnterpriseLicenseServiceUsageAggregationLock.test.ts +329 -0
  122. package/Tests/Server/Services/MonitorServiceDeleteNetworkDeviceCleanup.test.ts +294 -0
  123. package/Tests/Server/Services/MonitorStatusBridgeProbePath.test.ts +802 -0
  124. package/Tests/Server/Services/MonitorStatusTimelineService.test.ts +72 -2
  125. package/Tests/Server/Services/NetworkAlertPolicyEngineHooks.test.ts +752 -0
  126. package/Tests/Server/Services/NetworkAlertPolicyEngineService.test.ts +1849 -0
  127. package/Tests/Server/Services/NetworkAlertPolicyModel.test.ts +1793 -0
  128. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +47 -4
  129. package/Tests/Server/Services/NetworkDeviceAutoImportRuleService.test.ts +97 -12
  130. package/Tests/Server/Services/NetworkDeviceAutoMonitorLifecycle.test.ts +148 -3
  131. package/Tests/Server/Services/NetworkDeviceMonitorBindingUpdateGuard.test.ts +514 -0
  132. package/Tests/Server/Services/NetworkDeviceMonitorStatusStamp.test.ts +447 -58
  133. package/Tests/Server/Services/NetworkDeviceMonitoringMethodTransition.test.ts +739 -0
  134. package/Tests/Server/Services/NetworkDevicePollingTenancy.test.ts +501 -0
  135. package/Tests/Server/Services/NetworkDeviceSiteDefaultProbe.test.ts +432 -0
  136. package/Tests/Server/Services/NetworkSiteMonitoringDefaults.test.ts +498 -0
  137. package/Tests/Server/Services/NetworkSiteRollupPolicyAndMaintenance.test.ts +337 -55
  138. package/Tests/Server/Services/NetworkSiteService.test.ts +1868 -131
  139. package/Tests/Server/Services/NetworkSiteTypeService.test.ts +1109 -0
  140. package/Tests/Server/Services/NetworkSnmpCredentialProfileModel.test.ts +926 -0
  141. package/Tests/Server/Services/NetworkSnmpCredentialProfileService.test.ts +796 -0
  142. package/Tests/Server/Services/ProjectServiceNetworkSiteTypeDefaults.test.ts +214 -0
  143. package/Tests/Server/Services/StatusPagePrivateUserEmailChangePasswordResetExpiry.test.ts +269 -0
  144. package/Tests/Server/Services/UserEmailChangePasswordResetExpiry.test.ts +472 -0
  145. package/Tests/Server/Services/UserNotificationEmailRollupModels.test.ts +569 -0
  146. package/Tests/Server/Services/UserNotificationEmailRollupSettingModel.test.ts +314 -0
  147. package/Tests/Server/Services/UserNotificationEmailRollupSettingService.test.ts +409 -0
  148. package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +856 -0
  149. package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +102 -1
  150. package/Tests/Server/Types/Database/Permissions/DashboardAccessPermission.test.ts +321 -0
  151. package/Tests/Server/Types/Database/QueryHelperOperators.test.ts +17 -0
  152. package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +124 -0
  153. package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +208 -0
  154. package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +235 -0
  155. package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +253 -0
  156. package/Tests/Server/Utils/Captcha.test.ts +422 -0
  157. package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +96 -2
  158. package/Tests/Server/Utils/Database/MigrationFailureLog.test.ts +466 -0
  159. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1096 -0
  160. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerClaim.test.ts +466 -0
  161. package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +1428 -0
  162. package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +752 -0
  163. package/Tests/Server/Utils/EmailRollup/EmailRollupWriter.test.ts +864 -0
  164. package/Tests/Server/Utils/LoggerFaultDemotion.test.ts +346 -0
  165. package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +633 -0
  166. package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +196 -0
  167. package/Tests/Server/Utils/Monitor/DatabaseMetricWrite.test.ts +367 -0
  168. package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +100 -0
  169. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +5 -0
  170. package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +512 -31
  171. package/Tests/Server/Utils/Monitor/NetworkDeviceMetricUtil.test.ts +252 -0
  172. package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +479 -42
  173. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +351 -5
  174. package/Tests/Server/Utils/NetworkDevice/DeviceHealthAggregation.test.ts +136 -12
  175. package/Tests/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.test.ts +306 -0
  176. package/Tests/Server/Utils/OutboundUserAgent.test.ts +266 -0
  177. package/Tests/Server/Utils/SecurityEvent/ThreatIntel/TaxiiClientUserAgent.test.ts +141 -0
  178. package/Tests/Server/Utils/Telemetry/ErrorClassResolver.test.ts +298 -0
  179. package/Tests/Server/Utils/Telemetry.test.ts +456 -66
  180. package/Tests/Types/Monitor/DatabaseMetricCatalog.test.ts +388 -0
  181. package/Tests/Types/Monitor/MonitorStepDatabaseMonitor.test.ts +243 -0
  182. package/Tests/Types/Monitor/MonitorStepDefaultTelemetryConfig.test.ts +1 -0
  183. package/Tests/Types/Monitor/MonitorType.test.ts +1 -0
  184. package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +16 -7
  185. package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +60 -0
  186. package/Tests/Types/NetworkDevice/NetworkAlertPolicyScope.test.ts +655 -0
  187. package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +115 -26
  188. package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +39 -0
  189. package/Tests/Types/NotificationSetting/NotificationEmailRollupPolicy.test.ts +299 -0
  190. package/Tests/Types/Telemetry/ErrorClass.test.ts +483 -0
  191. package/Tests/UI/Components/BasicRadioButtons.test.tsx +336 -0
  192. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +15 -0
  193. package/Tests/UI/Components/ProgressBar.test.tsx +38 -2
  194. package/Tests/UI/Components/SideMenuItem.test.tsx +226 -4
  195. package/Tests/UI/Components/SideMenuSection.test.tsx +310 -0
  196. package/Tests/UI/Components/SideOverSubmitState.test.tsx +335 -0
  197. package/Tests/UI/Utils/PageScrollLock.test.tsx +377 -0
  198. package/Tests/UI/Utils/PermissionGate.test.ts +78 -0
  199. package/Tests/UI/Utils/SensitiveUrlToken.test.ts +140 -0
  200. package/Tests/Utils/EnterpriseLicenseSeats.test.ts +69 -0
  201. package/Tests/Utils/EnterpriseLicenseSync.test.ts +7 -1
  202. package/Tests/Utils/EnterpriseLicenseUsage.test.ts +433 -2
  203. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +280 -1
  204. package/Tests/Utils/Monitor/MonitorSummarySnapshotUtil.test.ts +1 -0
  205. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +38 -0
  206. package/Tests/Utils/NetworkDevice/DeviceHealthStateUtil.test.ts +284 -23
  207. package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +177 -0
  208. package/Tests/Utils/NetworkDevice/MonitoringMethodThreadedClassifiers.test.ts +992 -0
  209. package/Tests/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.test.ts +427 -0
  210. package/Tests/Utils/NetworkDevice/ReachabilityStampConsistency.test.ts +185 -0
  211. package/Tests/Utils/NetworkDevice/SnmpCredentialUtil.test.ts +268 -0
  212. package/Tests/Utils/NetworkDiscovery/AutoImportRuleMatcher.test.ts +55 -5
  213. package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +98 -21
  214. package/Tests/Utils/NetworkDiscovery/DiscoveryImportEligibility.test.ts +98 -20
  215. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +8 -7
  216. package/Tests/Utils/NetworkDiscovery/PingMonitorBuilderForAddress.test.ts +274 -0
  217. package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +230 -51
  218. package/Tests/Utils/NetworkSite/TypeHierarchyUtil.test.ts +209 -0
  219. package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +145 -0
  220. package/Types/AI/ExceptionAIClassification.ts +10 -24
  221. package/Types/Email/EmailTemplateType.ts +2 -0
  222. package/Types/EnterpriseLicense/EnterpriseLicenseInstanceSummary.ts +5 -0
  223. package/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.ts +13 -0
  224. package/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.ts +6 -0
  225. package/Types/Exception/ApiException.ts +10 -0
  226. package/Types/Exception/BadDataException.ts +11 -0
  227. package/Types/Exception/BadRequestException.ts +11 -0
  228. package/Types/Exception/Exception.ts +65 -0
  229. package/Types/Exception/ForbiddenException.ts +10 -0
  230. package/Types/Exception/NotAuthenticatedException.ts +10 -0
  231. package/Types/Exception/NotAuthorizedException.ts +10 -0
  232. package/Types/Exception/NotFoundException.ts +11 -0
  233. package/Types/Exception/PayloadTooLargeException.ts +11 -0
  234. package/Types/Exception/PaymentRequiredException.ts +10 -0
  235. package/Types/Exception/ServiceUnavailableException.ts +10 -0
  236. package/Types/Exception/SsoAuthorizationException.ts +10 -0
  237. package/Types/Exception/TenantNotFoundException.ts +11 -0
  238. package/Types/Exception/TimeoutException.ts +10 -0
  239. package/Types/Exception/TooManyRequestsException.ts +10 -0
  240. package/Types/Exception/UnableToReachServer.ts +10 -0
  241. package/Types/Exception/WebsiteRequestException.ts +10 -0
  242. package/Types/Monitor/CriteriaFilter.ts +60 -2
  243. package/Types/Monitor/DatabaseMetricCatalog.ts +693 -0
  244. package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +83 -0
  245. package/Types/Monitor/MonitorCriteriaInstance.ts +76 -0
  246. package/Types/Monitor/MonitorMetricType.ts +71 -0
  247. package/Types/Monitor/MonitorStep.ts +76 -0
  248. package/Types/Monitor/MonitorStepDatabaseMonitor.ts +171 -0
  249. package/Types/Monitor/MonitorStepSqlMonitor.ts +2 -20
  250. package/Types/Monitor/MonitorType.ts +47 -1
  251. package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +22 -1
  252. package/Types/Monitor/SqlConnectionConfig.ts +31 -0
  253. package/Types/NetworkDevice/NetworkAlertPolicyScope.ts +343 -0
  254. package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +42 -22
  255. package/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.ts +30 -0
  256. package/Types/NotificationSetting/NotificationEmailRollupCategory.ts +255 -0
  257. package/Types/NotificationSetting/NotificationEmailRollupPolicy.ts +104 -0
  258. package/Types/Permission.ts +90 -0
  259. package/Types/Probe/ProbeMonitorResponse.ts +16 -0
  260. package/Types/Telemetry/ErrorClass.ts +274 -0
  261. package/Types/Telemetry/UnitOfWork.ts +59 -0
  262. package/UI/Components/CommandPalette/CommandPalette.tsx +2 -8
  263. package/UI/Components/EditionLabel/EditionLabel.tsx +4 -0
  264. package/UI/Components/Modal/Modal.tsx +2 -8
  265. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
  266. package/UI/Components/ProgressBar/ProgressBar.tsx +12 -1
  267. package/UI/Components/RadioButtons/BasicRadioButtons.tsx +37 -7
  268. package/UI/Components/SideMenu/SideMenu.tsx +123 -5
  269. package/UI/Components/SideMenu/SideMenuItem.tsx +76 -84
  270. package/UI/Components/SideMenu/SideMenuSection.tsx +55 -23
  271. package/UI/Components/SideOver/SideOver.tsx +21 -20
  272. package/UI/Utils/PageScrollLock.ts +79 -3
  273. package/UI/Utils/PermissionGate.ts +61 -0
  274. package/UI/Utils/SensitiveUrlToken.ts +112 -0
  275. package/UI/Utils/TestLLMProvider.ts +11 -0
  276. package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +16 -0
  277. package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +191 -11
  278. package/Utils/Monitor/MonitorMetricType.ts +153 -1
  279. package/Utils/Monitor/NetworkTopologyUtil.ts +23 -3
  280. package/Utils/NetworkDevice/DeviceHealthStateUtil.ts +65 -14
  281. package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +43 -14
  282. package/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.ts +247 -0
  283. package/Utils/NetworkDevice/SnmpCredentialUtil.ts +68 -0
  284. package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +15 -7
  285. package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +52 -17
  286. package/Utils/NetworkDiscovery/DiscoveryImportEligibility.ts +55 -23
  287. package/Utils/NetworkDiscovery/PingMonitorBuilder.ts +115 -13
  288. package/Utils/NetworkSite/SiteStatusRollupUtil.ts +66 -20
  289. package/Utils/NetworkSite/TypeHierarchyUtil.ts +313 -0
  290. package/build/dist/Models/AnalyticsModels/Span.js +14 -0
  291. package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
  292. package/build/dist/Models/DatabaseModels/EnterpriseLicense.js +59 -0
  293. package/build/dist/Models/DatabaseModels/EnterpriseLicense.js.map +1 -1
  294. package/build/dist/Models/DatabaseModels/Index.js +10 -0
  295. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  296. package/build/dist/Models/DatabaseModels/Monitor.js +75 -0
  297. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  298. package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js +713 -0
  299. package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js.map +1 -0
  300. package/build/dist/Models/DatabaseModels/NetworkDevice.js +180 -1
  301. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  302. package/build/dist/Models/DatabaseModels/NetworkSite.js +200 -2
  303. package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -1
  304. package/build/dist/Models/DatabaseModels/NetworkSiteType.js +102 -3
  305. package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -1
  306. package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js +878 -0
  307. package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js.map +1 -0
  308. package/build/dist/Models/DatabaseModels/TelemetryException.js +123 -0
  309. package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
  310. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js +363 -0
  311. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js.map +1 -0
  312. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js +402 -0
  313. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js.map +1 -0
  314. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js +296 -0
  315. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js.map +1 -0
  316. package/build/dist/Server/API/EnterpriseLicenseAPI.js +273 -60
  317. package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
  318. package/build/dist/Server/API/LlmProviderAPI.js +108 -13
  319. package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
  320. package/build/dist/Server/EnvironmentConfig.js +12 -0
  321. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  322. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js +24 -0
  323. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js.map +1 -0
  324. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js +16 -0
  325. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js.map +1 -0
  326. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js +111 -0
  327. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js.map +1 -0
  328. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js +77 -0
  329. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js.map +1 -0
  330. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js +50 -0
  331. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js.map +1 -0
  332. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js +83 -0
  333. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js.map +1 -0
  334. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
  335. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  336. package/build/dist/Server/Infrastructure/QueueWorker.js +33 -5
  337. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  338. package/build/dist/Server/Middleware/BearerTokenAuthorization.js +12 -0
  339. package/build/dist/Server/Middleware/BearerTokenAuthorization.js.map +1 -1
  340. package/build/dist/Server/Middleware/ProjectAuthorization.js +11 -0
  341. package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
  342. package/build/dist/Server/Middleware/SCIMAuthorization.js +12 -0
  343. package/build/dist/Server/Middleware/SCIMAuthorization.js.map +1 -1
  344. package/build/dist/Server/Middleware/TelemetryIngest.js +11 -0
  345. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  346. package/build/dist/Server/Services/AIBillingService.js +70 -16
  347. package/build/dist/Server/Services/AIBillingService.js.map +1 -1
  348. package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js +167 -0
  349. package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js.map +1 -1
  350. package/build/dist/Server/Services/EnterpriseLicenseService.js +39 -0
  351. package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
  352. package/build/dist/Server/Services/Index.js +10 -0
  353. package/build/dist/Server/Services/Index.js.map +1 -1
  354. package/build/dist/Server/Services/MonitorService.js +119 -21
  355. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  356. package/build/dist/Server/Services/MonitorStatusTimelineService.js +127 -8
  357. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  358. package/build/dist/Server/Services/MonitorTemplateService.js +162 -0
  359. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  360. package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js +1683 -0
  361. package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js.map +1 -0
  362. package/build/dist/Server/Services/NetworkAlertPolicyService.js +732 -0
  363. package/build/dist/Server/Services/NetworkAlertPolicyService.js.map +1 -0
  364. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +10 -9
  365. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  366. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +54 -11
  367. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
  368. package/build/dist/Server/Services/NetworkDeviceService.js +841 -70
  369. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  370. package/build/dist/Server/Services/NetworkSiteService.js +1145 -107
  371. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
  372. package/build/dist/Server/Services/NetworkSiteTypeService.js +863 -0
  373. package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -1
  374. package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js +217 -0
  375. package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js.map +1 -0
  376. package/build/dist/Server/Services/NotificationService.js +80 -17
  377. package/build/dist/Server/Services/NotificationService.js.map +1 -1
  378. package/build/dist/Server/Services/ProjectService.js +66 -30
  379. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  380. package/build/dist/Server/Services/StatusPagePrivateUserService.js +92 -2
  381. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  382. package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js +76 -0
  383. package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js.map +1 -0
  384. package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js +77 -0
  385. package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js.map +1 -0
  386. package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js +111 -0
  387. package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js.map +1 -0
  388. package/build/dist/Server/Services/UserNotificationSettingService.js +46 -20
  389. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  390. package/build/dist/Server/Services/UserService.js +90 -0
  391. package/build/dist/Server/Services/UserService.js.map +1 -1
  392. package/build/dist/Server/Types/Database/QueryHelper.js +1 -1
  393. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  394. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +14 -3
  395. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
  396. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +10 -0
  397. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
  398. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +10 -0
  399. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
  400. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js +54 -1
  401. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js.map +1 -1
  402. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +18 -4
  403. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
  404. package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js +59 -0
  405. package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js.map +1 -0
  406. package/build/dist/Server/Utils/DataSource/HttpFetch.js +2 -1
  407. package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
  408. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +91 -0
  409. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -0
  410. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +691 -0
  411. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -0
  412. package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +497 -0
  413. package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js.map +1 -0
  414. package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js +257 -0
  415. package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js.map +1 -0
  416. package/build/dist/Server/Utils/LLM/LLMService.js +64 -1
  417. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  418. package/build/dist/Server/Utils/LogRedaction.js +8 -0
  419. package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
  420. package/build/dist/Server/Utils/Logger.js +63 -1
  421. package/build/dist/Server/Utils/Logger.js.map +1 -1
  422. package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js +141 -0
  423. package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js.map +1 -0
  424. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
  425. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  426. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +51 -1
  427. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  428. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js +7 -0
  429. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -1
  430. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +37 -0
  431. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  432. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +158 -6
  433. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  434. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
  435. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  436. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +32 -0
  437. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  438. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +330 -21
  439. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  440. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +55 -10
  441. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
  442. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +178 -49
  443. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -1
  444. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +119 -29
  445. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  446. package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js +30 -17
  447. package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js.map +1 -1
  448. package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js +158 -0
  449. package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js.map +1 -0
  450. package/build/dist/Server/Utils/OutboundUserAgent.js +123 -0
  451. package/build/dist/Server/Utils/OutboundUserAgent.js.map +1 -0
  452. package/build/dist/Server/Utils/StartServer.js +38 -14
  453. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  454. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +28 -8
  455. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
  456. package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js +95 -0
  457. package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js.map +1 -0
  458. package/build/dist/Server/Utils/Telemetry/SpanUtil.js +29 -0
  459. package/build/dist/Server/Utils/Telemetry/SpanUtil.js.map +1 -1
  460. package/build/dist/Server/Utils/Telemetry.js +162 -46
  461. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  462. package/build/dist/Types/AI/ExceptionAIClassification.js +10 -24
  463. package/build/dist/Types/AI/ExceptionAIClassification.js.map +1 -1
  464. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  465. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  466. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js +2 -0
  467. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js.map +1 -0
  468. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js +7 -0
  469. package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js.map +1 -0
  470. package/build/dist/Types/Exception/ApiException.js +9 -0
  471. package/build/dist/Types/Exception/ApiException.js.map +1 -1
  472. package/build/dist/Types/Exception/BadDataException.js +10 -0
  473. package/build/dist/Types/Exception/BadDataException.js.map +1 -1
  474. package/build/dist/Types/Exception/BadRequestException.js +10 -0
  475. package/build/dist/Types/Exception/BadRequestException.js.map +1 -1
  476. package/build/dist/Types/Exception/Exception.js +56 -0
  477. package/build/dist/Types/Exception/Exception.js.map +1 -1
  478. package/build/dist/Types/Exception/ForbiddenException.js +9 -0
  479. package/build/dist/Types/Exception/ForbiddenException.js.map +1 -1
  480. package/build/dist/Types/Exception/NotAuthenticatedException.js +9 -0
  481. package/build/dist/Types/Exception/NotAuthenticatedException.js.map +1 -1
  482. package/build/dist/Types/Exception/NotAuthorizedException.js +9 -0
  483. package/build/dist/Types/Exception/NotAuthorizedException.js.map +1 -1
  484. package/build/dist/Types/Exception/NotFoundException.js +10 -0
  485. package/build/dist/Types/Exception/NotFoundException.js.map +1 -1
  486. package/build/dist/Types/Exception/PayloadTooLargeException.js +10 -0
  487. package/build/dist/Types/Exception/PayloadTooLargeException.js.map +1 -1
  488. package/build/dist/Types/Exception/PaymentRequiredException.js +9 -0
  489. package/build/dist/Types/Exception/PaymentRequiredException.js.map +1 -1
  490. package/build/dist/Types/Exception/ServiceUnavailableException.js +9 -0
  491. package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -1
  492. package/build/dist/Types/Exception/SsoAuthorizationException.js +9 -0
  493. package/build/dist/Types/Exception/SsoAuthorizationException.js.map +1 -1
  494. package/build/dist/Types/Exception/TenantNotFoundException.js +10 -0
  495. package/build/dist/Types/Exception/TenantNotFoundException.js.map +1 -1
  496. package/build/dist/Types/Exception/TimeoutException.js +9 -0
  497. package/build/dist/Types/Exception/TimeoutException.js.map +1 -1
  498. package/build/dist/Types/Exception/TooManyRequestsException.js +9 -0
  499. package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -1
  500. package/build/dist/Types/Exception/UnableToReachServer.js +9 -0
  501. package/build/dist/Types/Exception/UnableToReachServer.js.map +1 -1
  502. package/build/dist/Types/Exception/WebsiteRequestException.js +9 -0
  503. package/build/dist/Types/Exception/WebsiteRequestException.js.map +1 -1
  504. package/build/dist/Types/Monitor/CriteriaFilter.js +45 -2
  505. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  506. package/build/dist/Types/Monitor/DatabaseMetricCatalog.js +594 -0
  507. package/build/dist/Types/Monitor/DatabaseMetricCatalog.js.map +1 -0
  508. package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js +21 -0
  509. package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js.map +1 -0
  510. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +70 -0
  511. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  512. package/build/dist/Types/Monitor/MonitorMetricType.js +61 -0
  513. package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
  514. package/build/dist/Types/Monitor/MonitorStep.js +54 -0
  515. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  516. package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js +122 -0
  517. package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js.map +1 -0
  518. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -1
  519. package/build/dist/Types/Monitor/MonitorType.js +45 -1
  520. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  521. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +21 -1
  522. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
  523. package/build/dist/Types/Monitor/SqlConnectionConfig.js +2 -0
  524. package/build/dist/Types/Monitor/SqlConnectionConfig.js.map +1 -0
  525. package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js +172 -0
  526. package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js.map +1 -0
  527. package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +40 -22
  528. package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -1
  529. package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js +26 -0
  530. package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js.map +1 -0
  531. package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js +186 -0
  532. package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js.map +1 -0
  533. package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js +87 -0
  534. package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js.map +1 -0
  535. package/build/dist/Types/Permission.js +80 -0
  536. package/build/dist/Types/Permission.js.map +1 -1
  537. package/build/dist/Types/Telemetry/ErrorClass.js +216 -0
  538. package/build/dist/Types/Telemetry/ErrorClass.js.map +1 -0
  539. package/build/dist/Types/Telemetry/UnitOfWork.js +59 -0
  540. package/build/dist/Types/Telemetry/UnitOfWork.js.map +1 -0
  541. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +2 -7
  542. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
  543. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +3 -0
  544. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  545. package/build/dist/UI/Components/Modal/Modal.js +2 -7
  546. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  547. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +39 -0
  548. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  549. package/build/dist/UI/Components/ProgressBar/ProgressBar.js +12 -1
  550. package/build/dist/UI/Components/ProgressBar/ProgressBar.js.map +1 -1
  551. package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js +6 -6
  552. package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js.map +1 -1
  553. package/build/dist/UI/Components/SideMenu/SideMenu.js +67 -5
  554. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  555. package/build/dist/UI/Components/SideMenu/SideMenuItem.js +49 -53
  556. package/build/dist/UI/Components/SideMenu/SideMenuItem.js.map +1 -1
  557. package/build/dist/UI/Components/SideMenu/SideMenuSection.js +25 -7
  558. package/build/dist/UI/Components/SideMenu/SideMenuSection.js.map +1 -1
  559. package/build/dist/UI/Components/SideOver/SideOver.js +5 -20
  560. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  561. package/build/dist/UI/Utils/PageScrollLock.js +31 -3
  562. package/build/dist/UI/Utils/PageScrollLock.js.map +1 -1
  563. package/build/dist/UI/Utils/PermissionGate.js +42 -1
  564. package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
  565. package/build/dist/UI/Utils/SensitiveUrlToken.js +97 -0
  566. package/build/dist/UI/Utils/SensitiveUrlToken.js.map +1 -0
  567. package/build/dist/UI/Utils/TestLLMProvider.js +4 -5
  568. package/build/dist/UI/Utils/TestLLMProvider.js.map +1 -1
  569. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +15 -0
  570. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +1 -1
  571. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +111 -9
  572. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
  573. package/build/dist/Utils/Monitor/MonitorMetricType.js +109 -1
  574. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  575. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +8 -3
  576. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  577. package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js +27 -7
  578. package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js.map +1 -1
  579. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +7 -5
  580. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -1
  581. package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js +180 -0
  582. package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js.map +1 -0
  583. package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js +12 -0
  584. package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js.map +1 -0
  585. package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js +15 -5
  586. package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -1
  587. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +44 -15
  588. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
  589. package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js +52 -23
  590. package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js.map +1 -1
  591. package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js +85 -13
  592. package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js.map +1 -1
  593. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +30 -15
  594. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
  595. package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js +191 -0
  596. package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js.map +1 -0
  597. package/package.json +2 -2
@@ -0,0 +1,336 @@
1
+ // Components
2
+ import BasicRadioButtons, {
3
+ BasicRadioButtonOption,
4
+ } from "../../../UI/Components/RadioButtons/BasicRadioButtons";
5
+ import { describe, expect, test } from "@jest/globals";
6
+ import "@testing-library/jest-dom";
7
+ import { fireEvent, render, screen } from "@testing-library/react";
8
+ import React from "react";
9
+ import getJestMockFunction, { MockFunction } from "../../../Tests/MockType";
10
+
11
+ /*
12
+ * A regression suite for a bug that shipped and was visible on every desktop.
13
+ *
14
+ * The option title and its description were two inline spans inside one label,
15
+ * separated by `ml-1 sm:ml-0`. The `sm:` variant cancels the margin at every
16
+ * breakpoint from 640px up -- i.e. on every desktop -- so the only gap between
17
+ * the two strings disappeared and the pair rendered as one run-on sentence:
18
+ * "Create an alertNotifies the team and runs the on-call policy." The narrow
19
+ * phone layout, the one place the 4px margin survived, was the only place it
20
+ * looked right, which is why it went unnoticed.
21
+ *
22
+ * So the assertions below are about the two strings being separate, stacked
23
+ * block elements with no horizontal-margin hack between them. The rest of the
24
+ * suite pins the selection behaviour that these options exist to drive.
25
+ */
26
+
27
+ const ALERT_TITLE: string = "Create an alert";
28
+ const ALERT_DESCRIPTION: string =
29
+ "Notifies the team and runs the on-call policy.";
30
+ const SILENT_TITLE: string = "Do nothing";
31
+ const SILENT_DESCRIPTION: string = "Leaves the monitor silent.";
32
+
33
+ const options: Array<BasicRadioButtonOption> = [
34
+ {
35
+ title: ALERT_TITLE,
36
+ description: ALERT_DESCRIPTION,
37
+ value: "alert",
38
+ },
39
+ {
40
+ title: SILENT_TITLE,
41
+ description: SILENT_DESCRIPTION,
42
+ value: "silent",
43
+ },
44
+ ];
45
+
46
+ type RadioAtFunction = (index: number) => HTMLInputElement;
47
+
48
+ /*
49
+ * Addressed by position because the suite also asserts things about the pair
50
+ * of elements at each index. Where the point of a test is the ASSOCIATION
51
+ * between a radio and its label, it queries by accessible name instead --
52
+ * see the "each radio is named by its own title" group.
53
+ */
54
+ const radioAt: RadioAtFunction = (index: number): HTMLInputElement => {
55
+ const radio: HTMLElement | undefined = screen.getAllByRole("radio")[index];
56
+
57
+ if (!radio) {
58
+ throw new Error(`No radio button rendered at index ${index}.`);
59
+ }
60
+
61
+ return radio as HTMLInputElement;
62
+ };
63
+
64
+ describe("BasicRadioButtons", () => {
65
+ /*
66
+ * The label used to be a bare sibling of its input, with no htmlFor and
67
+ * without wrapping it, so nothing tied the two together. Two things followed
68
+ * from that, and neither was visible to a sighted mouse user: the radio had
69
+ * no accessible name at all -- a screen reader announced "radio button, not
70
+ * checked" and never read "Create an alert" -- and the only hit target was
71
+ * the 16px dot, so clicking the words did nothing.
72
+ */
73
+ describe("each radio is named by its own title", () => {
74
+ test("the radio can be found by its title", () => {
75
+ render(
76
+ <BasicRadioButtons
77
+ options={options}
78
+ onChange={getJestMockFunction()}
79
+ />,
80
+ );
81
+
82
+ expect(
83
+ screen.getByRole("radio", { name: new RegExp(ALERT_TITLE) }),
84
+ ).toBeInTheDocument();
85
+ expect(
86
+ screen.getByRole("radio", { name: new RegExp(SILENT_TITLE) }),
87
+ ).toBeInTheDocument();
88
+ });
89
+
90
+ test("no two radios share a name", () => {
91
+ render(
92
+ <BasicRadioButtons
93
+ options={options}
94
+ onChange={getJestMockFunction()}
95
+ />,
96
+ );
97
+
98
+ const first: HTMLElement = screen.getByRole("radio", {
99
+ name: new RegExp(ALERT_TITLE),
100
+ });
101
+ const second: HTMLElement = screen.getByRole("radio", {
102
+ name: new RegExp(SILENT_TITLE),
103
+ });
104
+
105
+ expect(first).not.toBe(second);
106
+ });
107
+
108
+ test("clicking the title text selects that option", () => {
109
+ const onChange: MockFunction = getJestMockFunction();
110
+
111
+ render(<BasicRadioButtons options={options} onChange={onChange} />);
112
+
113
+ onChange.mockClear();
114
+ fireEvent.click(screen.getByText(SILENT_TITLE));
115
+
116
+ expect(onChange).toHaveBeenCalledWith("silent");
117
+ });
118
+
119
+ test("clicking the description text selects that option too", () => {
120
+ const onChange: MockFunction = getJestMockFunction();
121
+
122
+ render(<BasicRadioButtons options={options} onChange={onChange} />);
123
+
124
+ onChange.mockClear();
125
+ fireEvent.click(screen.getByText(SILENT_DESCRIPTION));
126
+
127
+ expect(onChange).toHaveBeenCalledWith("silent");
128
+ });
129
+ });
130
+
131
+ describe("an option's title and description", () => {
132
+ /*
133
+ * The exact bug. `sm:ml-0` on the description is what glued the two strings
134
+ * together on desktop, and a horizontal margin is meaningless once the
135
+ * description is a block on its own line -- so its reappearance is the
136
+ * regression, whatever else changes around it.
137
+ */
138
+ test("the description is a block under the title, not an inline span nudged sideways", () => {
139
+ const onChange: MockFunction = getJestMockFunction();
140
+ render(<BasicRadioButtons onChange={onChange} options={options} />);
141
+
142
+ const title: HTMLElement = screen.getByText(ALERT_TITLE);
143
+ const description: HTMLElement = screen.getByText(ALERT_DESCRIPTION);
144
+
145
+ expect(title).toHaveClass("block");
146
+ expect(description).toHaveClass("block");
147
+ expect(description.className).not.toContain("ml-1");
148
+ expect(description.className).not.toContain("sm:ml-0");
149
+ });
150
+
151
+ /*
152
+ * That an exact-match query for the title alone finds an element is the
153
+ * proof that the two strings are still two elements: fold them into one
154
+ * text node -- the shape the bug rendered as -- and this query finds
155
+ * nothing, because the node's text would be title + description.
156
+ */
157
+ test("the title is queryable on its own, and the description follows it", () => {
158
+ const onChange: MockFunction = getJestMockFunction();
159
+ render(<BasicRadioButtons onChange={onChange} options={options} />);
160
+
161
+ const title: HTMLElement = screen.getByText(ALERT_TITLE);
162
+ const description: HTMLElement = screen.getByText(ALERT_DESCRIPTION);
163
+
164
+ expect(title).not.toBe(description);
165
+ expect(title.contains(description)).toBe(false);
166
+ expect(title.nextElementSibling).toBe(description);
167
+ expect(title.closest("label")).toBe(description.closest("label"));
168
+ });
169
+
170
+ /*
171
+ * `description` is optional, and an empty <span> still takes its `mt-0.5`
172
+ * with it -- which would leave a ragged extra gap under every title-only
173
+ * option in a list that mixes the two.
174
+ */
175
+ test("an option with no description renders no description element", () => {
176
+ const onChange: MockFunction = getJestMockFunction();
177
+ render(
178
+ <BasicRadioButtons
179
+ onChange={onChange}
180
+ options={[{ title: SILENT_TITLE, value: "silent" }]}
181
+ />,
182
+ );
183
+
184
+ const label: HTMLLabelElement | null = screen
185
+ .getByText(SILENT_TITLE)
186
+ .closest("label");
187
+
188
+ expect(label).not.toBeNull();
189
+ expect(label?.children).toHaveLength(1);
190
+ expect(screen.getAllByRole("radio")).toHaveLength(1);
191
+ });
192
+ });
193
+
194
+ describe("selection", () => {
195
+ /*
196
+ * The whole point of the control: the form above it only learns which
197
+ * branch the user picked through onChange.
198
+ */
199
+ test("picking an option reports its value and checks only that radio", () => {
200
+ const onChange: MockFunction = getJestMockFunction();
201
+ render(<BasicRadioButtons onChange={onChange} options={options} />);
202
+
203
+ fireEvent.click(radioAt(0));
204
+
205
+ expect(onChange).toHaveBeenLastCalledWith("alert");
206
+ expect(radioAt(0)).toBeChecked();
207
+ expect(radioAt(1)).not.toBeChecked();
208
+
209
+ fireEvent.click(radioAt(1));
210
+
211
+ expect(onChange).toHaveBeenLastCalledWith("silent");
212
+ expect(radioAt(0)).not.toBeChecked();
213
+ expect(radioAt(1)).toBeChecked();
214
+ });
215
+
216
+ /*
217
+ * A form that opens on a saved value has to show that value selected AND
218
+ * hand it back once, so the parent's state matches what is on screen
219
+ * before the user touches anything. Firing more than once here is not
220
+ * harmless: callers wire onChange to setState and to "mark form dirty".
221
+ */
222
+ test("initialValue selects that option on mount and reports it exactly once", () => {
223
+ const onChange: MockFunction = getJestMockFunction();
224
+ render(
225
+ <BasicRadioButtons
226
+ onChange={onChange}
227
+ options={options}
228
+ initialValue="silent"
229
+ />,
230
+ );
231
+
232
+ expect(radioAt(1)).toBeChecked();
233
+ expect(radioAt(0)).not.toBeChecked();
234
+ expect(onChange).toHaveBeenCalledTimes(1);
235
+ expect(onChange).toHaveBeenCalledWith("silent");
236
+ });
237
+
238
+ /*
239
+ * No initial value means no pre-selected branch. A control that quietly
240
+ * checked the first option would submit a choice the user never made.
241
+ */
242
+ test("with no initialValue nothing is selected and the empty value is reported", () => {
243
+ const onChange: MockFunction = getJestMockFunction();
244
+ render(<BasicRadioButtons onChange={onChange} options={options} />);
245
+
246
+ expect(radioAt(0)).not.toBeChecked();
247
+ expect(radioAt(1)).not.toBeChecked();
248
+ expect(onChange).toHaveBeenCalledWith("");
249
+ });
250
+
251
+ test("an empty-string initialValue also selects nothing", () => {
252
+ const onChange: MockFunction = getJestMockFunction();
253
+ render(
254
+ <BasicRadioButtons
255
+ onChange={onChange}
256
+ options={options}
257
+ initialValue=""
258
+ />,
259
+ );
260
+
261
+ expect(radioAt(0)).not.toBeChecked();
262
+ expect(radioAt(1)).not.toBeChecked();
263
+ expect(onChange).toHaveBeenCalledWith("");
264
+ });
265
+ });
266
+
267
+ describe("per-option children", () => {
268
+ /*
269
+ * Options carry their own follow-up fields (pick an on-call policy, choose
270
+ * a status page). Showing them for an unchosen option would put inputs on
271
+ * screen that the form never reads; leaving them behind after the user
272
+ * switches branches is worse -- the stale field looks live and editable.
273
+ */
274
+ test("children appear only while their own option is checked", () => {
275
+ const childText: string = "Choose an on-call policy";
276
+ const onChange: MockFunction = getJestMockFunction();
277
+
278
+ render(
279
+ <BasicRadioButtons
280
+ onChange={onChange}
281
+ options={[
282
+ {
283
+ title: ALERT_TITLE,
284
+ description: ALERT_DESCRIPTION,
285
+ value: "alert",
286
+ children: <div>{childText}</div>,
287
+ },
288
+ {
289
+ title: SILENT_TITLE,
290
+ value: "silent",
291
+ },
292
+ ]}
293
+ />,
294
+ );
295
+
296
+ expect(screen.queryByText(childText)).not.toBeInTheDocument();
297
+
298
+ fireEvent.click(radioAt(0));
299
+
300
+ expect(screen.getByText(childText)).toBeInTheDocument();
301
+
302
+ fireEvent.click(radioAt(1));
303
+
304
+ expect(screen.queryByText(childText)).not.toBeInTheDocument();
305
+ });
306
+ });
307
+
308
+ describe("validation message", () => {
309
+ /*
310
+ * The error is the only feedback a user gets when a required choice was
311
+ * skipped; a swallowed message leaves a form that refuses to submit and
312
+ * says nothing about why.
313
+ */
314
+ test("the error prop renders its message", () => {
315
+ const onChange: MockFunction = getJestMockFunction();
316
+ render(
317
+ <BasicRadioButtons
318
+ onChange={onChange}
319
+ options={options}
320
+ error="Pick one of these."
321
+ />,
322
+ );
323
+
324
+ expect(screen.getByTestId("error-message")).toHaveTextContent(
325
+ "Pick one of these.",
326
+ );
327
+ });
328
+
329
+ test("no error element is rendered when there is no error", () => {
330
+ const onChange: MockFunction = getJestMockFunction();
331
+ render(<BasicRadioButtons onChange={onChange} options={options} />);
332
+
333
+ expect(screen.queryByTestId("error-message")).not.toBeInTheDocument();
334
+ });
335
+ });
336
+ });
@@ -234,6 +234,21 @@ const PER_TYPE_EXPECTATIONS: Array<PerTypeExpectation> = [
234
234
  "failureCause",
235
235
  ],
236
236
  },
237
+ {
238
+ monitorType: MonitorType.Database,
239
+ title: "Database Health",
240
+ keys: [
241
+ "isOnline",
242
+ "responseTimeInMs",
243
+ "failureCause",
244
+ "connectionError",
245
+ "engineVersion",
246
+ "collectedGroups",
247
+ "unavailableGroups",
248
+ "collectionIssueSummary",
249
+ "metrics",
250
+ ],
251
+ },
237
252
  {
238
253
  monitorType: MonitorType.ExternalStatusPage,
239
254
  title: "External Status Page",
@@ -27,10 +27,46 @@ describe("ProgressBar Component", () => {
27
27
  expect(countText.innerHTML).toEqual("30 of 99 items");
28
28
  });
29
29
 
30
- test("should handle zero total count without crashing", () => {
30
+ /*
31
+ * A zero total reads as an empty track, not a full one.
32
+ *
33
+ * JavaScript does not throw on a divide by zero, so before the component
34
+ * guarded the total this arithmetic produced Infinity (capped to a
35
+ * misleading 100%) or, for a zero count, NaN — which reached the DOM three
36
+ * times over: `width: NaN%`, which the browser discards, aria-valuenow, and
37
+ * a visible "NaN%" beside the count. Nothing to do is nothing done, so 0 is
38
+ * the honest reading and it is what every branch below asserts.
39
+ */
40
+ test("shows an empty bar when the total is zero", () => {
31
41
  render(<ProgressBar count={30} totalCount={0} suffix="items" />);
32
42
  const progressBar: HTMLElement = getProgressBar();
33
- expect(progressBar).toHaveStyle({ width: "100%" });
43
+ expect(progressBar).toHaveStyle({ width: "0%" });
44
+ });
45
+
46
+ test("shows an empty bar when both the count and the total are zero", () => {
47
+ render(<ProgressBar count={0} totalCount={0} suffix="items" />);
48
+ const progressBar: HTMLElement = getProgressBar();
49
+ expect(progressBar).toHaveStyle({ width: "0%" });
50
+ });
51
+
52
+ test("never renders NaN to the user when the total is zero", () => {
53
+ const { container } = render(
54
+ <ProgressBar count={0} totalCount={0} suffix="items" />,
55
+ );
56
+
57
+ // The readout, the aria value and the width - the three NaN reached.
58
+ expect(container.textContent).not.toContain("NaN");
59
+ expect(screen.getByRole("progressbar")).toHaveAttribute(
60
+ "aria-valuenow",
61
+ "0",
62
+ );
63
+ expect(getProgressBar()).toHaveStyle({ width: "0%" });
64
+ });
65
+
66
+ test("a negative total is treated as nothing to do, not as progress", () => {
67
+ render(<ProgressBar count={5} totalCount={-10} suffix="items" />);
68
+ const progressBar: HTMLElement = getProgressBar();
69
+ expect(progressBar).toHaveStyle({ width: "0%" });
34
70
  });
35
71
 
36
72
  test("should round up the percentage to the nearest integer", () => {
@@ -5,19 +5,26 @@ import SideMenuItem, {
5
5
  ComponentProps,
6
6
  } from "../../../UI/Components/SideMenu/SideMenuItem";
7
7
  import * as Navigation from "../../../UI/Utils/Navigation";
8
- import { describe, expect, afterEach, jest } from "@jest/globals";
8
+ import { describe, expect, it, afterEach, jest } from "@jest/globals";
9
9
  import "@testing-library/jest-dom";
10
10
  import { fireEvent, render, screen } from "@testing-library/react";
11
11
  // Types
12
12
  import Route from "../../../Types/API/Route";
13
+ import URL from "../../../Types/API/URL";
13
14
  import IconProp from "../../../Types/Icon/IconProp";
14
15
  import React from "react";
15
16
  import getJestMockFunction from "../../../Tests/MockType";
16
17
 
17
- const highlightClassList: string =
18
- "bg-gradient-to-r from-indigo-50 to-indigo-50/50 text-indigo-700 shadow-sm";
18
+ /*
19
+ * The active-row treatment, pinned here because it is the only thing that
20
+ * tells a user which page they are on. A flat indigo ground plus semibold
21
+ * text replaced the earlier gradient-and-shadow: the shadow read as a raised
22
+ * card inside a card, and the gradient's second stop was invisible at the
23
+ * width the menu actually renders at.
24
+ */
25
+ const highlightClassList: string = "bg-indigo-50 text-indigo-700 font-semibold";
19
26
 
20
- const subItemHighlightClassList: string = "bg-indigo-50/70 text-indigo-700";
27
+ const subItemHighlightClassList: string = "bg-indigo-50 text-indigo-700";
21
28
 
22
29
  jest.mock("../../../UI/Utils/Navigation.ts", () => {
23
30
  return {
@@ -192,4 +199,219 @@ describe("Side Menu Item", () => {
192
199
  .closest("a");
193
200
  expect(subLinkElement).toHaveClass(subItemHighlightClassList);
194
201
  });
202
+
203
+ /*
204
+ * The redesigned row: a bare icon, a truncating title span, and indicators
205
+ * that carry no text. Each of the three is depended on somewhere outside
206
+ * this component, so a well-meaning restyle breaks a suite that says nothing
207
+ * about side menus.
208
+ */
209
+ describe("Redesigned row layout", () => {
210
+ type SetActivePageFunction = (activeRoute: Route | URL | null) => void;
211
+
212
+ /*
213
+ * Every test below states the active page for itself instead of inheriting
214
+ * whatever mock the previous test left on the module -- jest.clearAllMocks
215
+ * clears calls, not implementations, so an inherited mockReturnValue(true)
216
+ * would quietly turn a "this row is not highlighted" assertion into a test
217
+ * of nothing.
218
+ */
219
+ const setActivePage: SetActivePageFunction = (
220
+ activeRoute: Route | URL | null,
221
+ ): void => {
222
+ Navigation.default.isOnThisPage =
223
+ getJestMockFunction().mockImplementation((to: Route | URL): boolean => {
224
+ return activeRoute !== null && to === activeRoute;
225
+ });
226
+ };
227
+
228
+ const longLink: {
229
+ title: string;
230
+ to: Route;
231
+ } = {
232
+ title: "Scheduled Maintenance",
233
+ to: new Route("/scheduled-maintenance"),
234
+ };
235
+
236
+ /*
237
+ * `span.truncate` is a read interface, not just an ellipsis.
238
+ * SideMenuHarness.linksIn() takes a row's title from `span.truncate` and
239
+ * falls back to the anchor's whole textContent when it is missing -- so
240
+ * dropping the class does not fail here, it makes five product menu suites
241
+ * expect "Scheduled Maintenance" and read "Scheduled Maintenance12".
242
+ */
243
+ it("Should keep the title in span.truncate with the badge digits outside it", () => {
244
+ setActivePage(null);
245
+
246
+ const badgeCount: number = 12;
247
+ render(
248
+ <SideMenuItem
249
+ link={longLink}
250
+ icon={IconProp.Home}
251
+ badge={badgeCount}
252
+ badgeType={BadgeType.DANGER}
253
+ />,
254
+ );
255
+
256
+ const mainLink: HTMLAnchorElement = screen
257
+ .getByText(longLink.title)
258
+ .closest("a") as HTMLAnchorElement;
259
+
260
+ const titleSpan: HTMLSpanElement | null =
261
+ mainLink.querySelector("span.truncate");
262
+
263
+ expect(titleSpan).not.toBeNull();
264
+ expect(titleSpan?.textContent).toBe(longLink.title);
265
+ expect(titleSpan?.textContent).not.toContain(String(badgeCount));
266
+
267
+ // The badge is inside the same anchor, which is why the span is needed.
268
+ expect(mainLink.textContent).toContain(String(badgeCount));
269
+ expect(mainLink.textContent).not.toBe(longLink.title);
270
+ });
271
+
272
+ /*
273
+ * The icon is drawn bare. A filled chip around it cost ~28px of a 208px
274
+ * menu, and that is the width the long titles above were losing to the
275
+ * ellipsis -- so a chip coming back is a layout regression, not a taste
276
+ * question.
277
+ */
278
+ it("Should render the icon without a filled chip behind it", () => {
279
+ setActivePage(null);
280
+
281
+ const { container } = render(
282
+ <SideMenuItem {...defaultProps} icon={IconProp.Home} />,
283
+ );
284
+
285
+ const mainLink: HTMLAnchorElement = container.querySelector(
286
+ "a",
287
+ ) as HTMLAnchorElement;
288
+
289
+ expect(mainLink.querySelector("svg")).not.toBeNull();
290
+ expect(mainLink.querySelector(".bg-gray-100")).toBeNull();
291
+ expect(mainLink.querySelector(".bg-indigo-100")).toBeNull();
292
+ });
293
+
294
+ // The active row is where a tinted chip is most tempting, and costs the same width.
295
+ it("Should render the active row's icon without a filled chip either", () => {
296
+ setActivePage(defaultProps.link.to);
297
+
298
+ const { container } = render(
299
+ <SideMenuItem {...defaultProps} icon={IconProp.Home} />,
300
+ );
301
+
302
+ const mainLink: HTMLAnchorElement = container.querySelector(
303
+ "a",
304
+ ) as HTMLAnchorElement;
305
+
306
+ expect(mainLink).toHaveClass(highlightClassList);
307
+ expect(mainLink.querySelector(".bg-indigo-100")).toBeNull();
308
+ expect(mainLink.querySelector(".bg-gray-100")).toBeNull();
309
+ });
310
+
311
+ /*
312
+ * The other half of the highlight assertion above. Without this, a row that
313
+ * painted itself active unconditionally would still pass the positive test
314
+ * -- and the menu would tell the user they are on every page at once.
315
+ */
316
+ it("Should not highlight the main link when on a different page", () => {
317
+ setActivePage(null);
318
+
319
+ render(<SideMenuItem {...defaultProps} />);
320
+
321
+ const mainLink: HTMLAnchorElement | null = screen
322
+ .getByText(defaultProps.link.title)
323
+ .closest("a");
324
+
325
+ expect(mainLink).not.toHaveClass("bg-indigo-50");
326
+ expect(mainLink).not.toHaveClass("text-indigo-700");
327
+ expect(mainLink).not.toHaveClass("font-semibold");
328
+ expect(mainLink).toHaveClass("text-gray-600");
329
+ });
330
+
331
+ /*
332
+ * A sub-item is a different page from its parent. Highlighting both would
333
+ * leave two rows claiming to be the current page, which is precisely the
334
+ * question the highlight exists to answer.
335
+ */
336
+ it("Should leave the main link unhighlighted when only the sub item is active", () => {
337
+ const subLink: {
338
+ title: string;
339
+ to: Route;
340
+ } = {
341
+ title: "Sub Page",
342
+ to: new Route("/sub-page"),
343
+ };
344
+
345
+ setActivePage(subLink.to);
346
+
347
+ render(<SideMenuItem {...defaultProps} subItemLink={subLink} />);
348
+
349
+ const mainLink: HTMLAnchorElement | null = screen
350
+ .getByText(defaultProps.link.title)
351
+ .closest("a");
352
+ const subLinkElement: HTMLAnchorElement | null = screen
353
+ .getByText(subLink.title)
354
+ .closest("a");
355
+
356
+ expect(subLinkElement).toHaveClass(subItemHighlightClassList);
357
+ expect(mainLink).not.toBe(subLinkElement);
358
+ expect(mainLink).not.toHaveClass("bg-indigo-50");
359
+ expect(mainLink).not.toHaveClass("text-indigo-700");
360
+ });
361
+
362
+ /*
363
+ * "Something is wrong here" and "something needs attention here" are
364
+ * different messages, and colour alone is not enough to tell them apart --
365
+ * the two indicators have to be different glyphs as well.
366
+ */
367
+ it("Should render alert and warning as distinguishable indicators", () => {
368
+ setActivePage(null);
369
+
370
+ const withAlert: HTMLElement = render(
371
+ <SideMenuItem {...defaultProps} showAlert={true} />,
372
+ ).container;
373
+ const withWarning: HTMLElement = render(
374
+ <SideMenuItem {...defaultProps} showWarning={true} />,
375
+ ).container;
376
+
377
+ const alertIcon: SVGElement | null =
378
+ withAlert.querySelector("svg.text-red-500");
379
+ const warningIcon: SVGElement | null =
380
+ withWarning.querySelector("svg.text-amber-500");
381
+
382
+ expect(alertIcon).not.toBeNull();
383
+ expect(warningIcon).not.toBeNull();
384
+ expect(withAlert.querySelector("svg.text-amber-500")).toBeNull();
385
+ expect(withWarning.querySelector("svg.text-red-500")).toBeNull();
386
+ expect(alertIcon?.innerHTML).not.toBe(warningIcon?.innerHTML);
387
+ });
388
+
389
+ /*
390
+ * Neither indicator may put TEXT inside the anchor.
391
+ * Common/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx reads
392
+ * anchor.textContent as the row's title, so a screen-reader label rendered
393
+ * as visible text here ("Alert", "!") fails that unrelated suite instead of
394
+ * this one.
395
+ */
396
+ it("Should add no text to the anchor for the alert and warning indicators", () => {
397
+ setActivePage(null);
398
+
399
+ const { container } = render(
400
+ <SideMenuItem
401
+ {...defaultProps}
402
+ icon={IconProp.Home}
403
+ showAlert={true}
404
+ showWarning={true}
405
+ />,
406
+ );
407
+
408
+ const mainLink: HTMLAnchorElement = container.querySelector(
409
+ "a",
410
+ ) as HTMLAnchorElement;
411
+
412
+ expect(mainLink.textContent?.trim()).toBe(defaultProps.link.title);
413
+ // Row icon plus both indicators, all drawn as inline <svg>.
414
+ expect(mainLink.querySelectorAll("svg")).toHaveLength(3);
415
+ });
416
+ });
195
417
  });