@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,661 @@
1
+ import "@testing-library/jest-dom";
2
+ import { beforeEach, describe, expect, test } from "@jest/globals";
3
+ import { fireEvent, render, screen, within } from "@testing-library/react";
4
+ import * as React from "react";
5
+ import RecommendationsList from "../../../../App/FeatureSet/Dashboard/src/Components/Recommendations/RecommendationsList";
6
+ import {
7
+ RecommendationCategoryGroup,
8
+ RecommendationStatus,
9
+ RecommendationViewModel,
10
+ } from "../../../../App/FeatureSet/Dashboard/src/Components/Recommendations/RecommendationViewModel";
11
+ import Route from "../../../Types/API/Route";
12
+ import MonitorStep from "../../../Types/Monitor/MonitorStep";
13
+ import MonitorType from "../../../Types/Monitor/MonitorType";
14
+ import {
15
+ MonitorRecommendation,
16
+ MonitorRecommendationResourceType,
17
+ MonitorRecommendationSeverity,
18
+ } from "../../../Types/Monitor/Recommendation/MonitorRecommendationTypes";
19
+ import ObjectID from "../../../Types/ObjectID";
20
+ import RecommendationType from "../../../Types/Recommendation/RecommendationType";
21
+
22
+ /*
23
+ * The body of the recommendations page: category sections of cards, and the
24
+ * selection maths that feeds the bulk-create button.
25
+ *
26
+ * Selection is the part worth guarding. It is one Set held by the page, and
27
+ * every control here rebuilds it: a card's own toggle, and a per-category
28
+ * "Select all". Rebuilding it wrong is invisible on screen right up until the
29
+ * moment it matters — a select-all that REPLACES the Set instead of adding to
30
+ * it silently drops the category the user ticked a second ago, and they find
31
+ * out by counting the monitors that got created. A select-all that sweeps in
32
+ * created or dismissed recommendations is worse: those are filtered back out
33
+ * before the POST, so the button offers to create seven things and creates
34
+ * four, with nothing saying why.
35
+ *
36
+ * The heading counts are the other half. They are what a person uses to decide
37
+ * whether a section is worth opening at all, so a section that has work left
38
+ * must never read as finished.
39
+ */
40
+
41
+ const MONITOR_ID: ObjectID = ObjectID.generate();
42
+ const STORAGE_MONITOR_ID: ObjectID = ObjectID.generate();
43
+
44
+ type BuildRecommendationFunction = (data: {
45
+ templateId: string;
46
+ name: string;
47
+ category: string;
48
+ severity: MonitorRecommendationSeverity;
49
+ }) => MonitorRecommendation;
50
+
51
+ const buildRecommendation: BuildRecommendationFunction = (data: {
52
+ templateId: string;
53
+ name: string;
54
+ category: string;
55
+ severity: MonitorRecommendationSeverity;
56
+ }): MonitorRecommendation => {
57
+ return {
58
+ recommendationId: `Kubernetes:${data.templateId}`,
59
+ recommendationType: RecommendationType.Monitor,
60
+ resourceType: MonitorRecommendationResourceType.Kubernetes,
61
+ monitorType: MonitorType.Kubernetes,
62
+ templateId: data.templateId,
63
+ name: data.name,
64
+ /*
65
+ * Deliberately short. RecommendationCard clamps anything past 170
66
+ * characters behind a "Show more", and an extra button per card would be
67
+ * noise in every query here.
68
+ */
69
+ description: `Watch for ${data.name.toLowerCase()}.`,
70
+ category: data.category,
71
+ severity: data.severity,
72
+ getMonitorStep: () => {
73
+ return new MonitorStep();
74
+ },
75
+ };
76
+ };
77
+
78
+ const API_SERVER_DOWN: RecommendationViewModel = {
79
+ recommendation: buildRecommendation({
80
+ templateId: "k8s-api-server-down",
81
+ name: "API Server Down",
82
+ category: "Control Plane",
83
+ severity: "Critical",
84
+ }),
85
+ status: RecommendationStatus.Available,
86
+ };
87
+
88
+ const ETCD_NO_LEADER: RecommendationViewModel = {
89
+ recommendation: buildRecommendation({
90
+ templateId: "k8s-etcd-no-leader",
91
+ name: "Etcd Has No Leader",
92
+ category: "Control Plane",
93
+ severity: "Critical",
94
+ }),
95
+ status: RecommendationStatus.Available,
96
+ };
97
+
98
+ const NODE_NOT_READY: RecommendationViewModel = {
99
+ recommendation: buildRecommendation({
100
+ templateId: "k8s-node-not-ready",
101
+ name: "Node Not Ready",
102
+ category: "Control Plane",
103
+ severity: "Critical",
104
+ }),
105
+ status: RecommendationStatus.Created,
106
+ monitorId: MONITOR_ID,
107
+ };
108
+
109
+ const POD_CRASH_LOOPING: RecommendationViewModel = {
110
+ recommendation: buildRecommendation({
111
+ templateId: "k8s-pod-crash-loop",
112
+ name: "Pod Crash Looping",
113
+ category: "Workload",
114
+ severity: "Critical",
115
+ }),
116
+ status: RecommendationStatus.Available,
117
+ };
118
+
119
+ const JOB_FAILED: RecommendationViewModel = {
120
+ recommendation: buildRecommendation({
121
+ templateId: "k8s-job-failed",
122
+ name: "Job Failed",
123
+ category: "Workload",
124
+ severity: "Warning",
125
+ }),
126
+ status: RecommendationStatus.Dismissed,
127
+ dismissalId: ObjectID.generate(),
128
+ dismissalReason: "We run these jobs by hand.",
129
+ };
130
+
131
+ const VOLUME_ALMOST_FULL: RecommendationViewModel = {
132
+ recommendation: buildRecommendation({
133
+ templateId: "k8s-pv-almost-full",
134
+ name: "Persistent Volume Almost Full",
135
+ category: "Storage",
136
+ severity: "Warning",
137
+ }),
138
+ status: RecommendationStatus.Created,
139
+ monitorId: STORAGE_MONITOR_ID,
140
+ };
141
+
142
+ /*
143
+ * Three shapes on one page, on purpose: a category with work left AND work
144
+ * done, a category whose only handled card is a dismissal, and a category with
145
+ * nothing left to do.
146
+ */
147
+ const GROUPS: Array<RecommendationCategoryGroup> = [
148
+ {
149
+ category: "Control Plane",
150
+ recommendations: [API_SERVER_DOWN, ETCD_NO_LEADER, NODE_NOT_READY],
151
+ },
152
+ {
153
+ category: "Workload",
154
+ recommendations: [POD_CRASH_LOOPING, JOB_FAILED],
155
+ },
156
+ {
157
+ category: "Storage",
158
+ recommendations: [VOLUME_ALMOST_FULL],
159
+ },
160
+ ];
161
+
162
+ type RecommendationIdFunction = (viewModel: RecommendationViewModel) => string;
163
+
164
+ const idOf: RecommendationIdFunction = (
165
+ viewModel: RecommendationViewModel,
166
+ ): string => {
167
+ return viewModel.recommendation.recommendationId;
168
+ };
169
+
170
+ let selectionChanges: Array<Set<string>> = [];
171
+ let dismissed: Array<RecommendationViewModel> = [];
172
+ let restored: Array<RecommendationViewModel> = [];
173
+ let monitorRouteRequests: Array<ObjectID> = [];
174
+
175
+ interface RenderListOptions {
176
+ groups?: Array<RecommendationCategoryGroup> | undefined;
177
+ selectedRecommendationIds?: Set<string> | undefined;
178
+ isDisabled?: boolean | undefined;
179
+ }
180
+
181
+ type RenderListFunction = (options?: RenderListOptions) => void;
182
+
183
+ const renderList: RenderListFunction = (
184
+ options: RenderListOptions = {},
185
+ ): void => {
186
+ render(
187
+ <RecommendationsList
188
+ groups={options.groups || GROUPS}
189
+ selectedRecommendationIds={
190
+ options.selectedRecommendationIds || new Set<string>()
191
+ }
192
+ isDisabled={options.isDisabled}
193
+ onSelectionChange={(selectedRecommendationIds: Set<string>) => {
194
+ selectionChanges.push(selectedRecommendationIds);
195
+ }}
196
+ onDismiss={(viewModel: RecommendationViewModel) => {
197
+ dismissed.push(viewModel);
198
+ }}
199
+ onRestore={(viewModel: RecommendationViewModel) => {
200
+ restored.push(viewModel);
201
+ }}
202
+ getMonitorRoute={(monitorId: ObjectID) => {
203
+ monitorRouteRequests.push(monitorId);
204
+ return new Route(`/dashboard/monitors/${monitorId.toString()}`);
205
+ }}
206
+ />,
207
+ );
208
+ };
209
+
210
+ type LatestSelectionFunction = () => Set<string>;
211
+
212
+ const latestSelection: LatestSelectionFunction = (): Set<string> => {
213
+ const latest: Set<string> | undefined =
214
+ selectionChanges[selectionChanges.length - 1];
215
+
216
+ if (!latest) {
217
+ throw new Error("onSelectionChange was never called");
218
+ }
219
+
220
+ return latest;
221
+ };
222
+
223
+ /*
224
+ * The whole heading row for a category — the title, both count chips and the
225
+ * select-all control. Scoping to it is what keeps "1 handled" in one category
226
+ * from satisfying an assertion about another.
227
+ */
228
+ type GroupHeadingFunction = (category: string) => HTMLElement;
229
+
230
+ const groupHeading: GroupHeadingFunction = (category: string): HTMLElement => {
231
+ const heading: HTMLElement = screen.getByRole("heading", {
232
+ name: category,
233
+ level: 4,
234
+ });
235
+
236
+ const row: HTMLElement | null | undefined =
237
+ heading.closest("div")?.parentElement;
238
+
239
+ if (!row) {
240
+ throw new Error(`No heading row rendered for category ${category}`);
241
+ }
242
+
243
+ return row;
244
+ };
245
+
246
+ beforeEach(() => {
247
+ selectionChanges = [];
248
+ dismissed = [];
249
+ restored = [];
250
+ monitorRouteRequests = [];
251
+ });
252
+
253
+ describe("RecommendationsList", () => {
254
+ describe("groups and cards", () => {
255
+ /*
256
+ * Catalog order, not alphabetical. The template modules declare their most
257
+ * important category first — sorting would bury "Workload" under
258
+ * "Control Plane" on every cluster.
259
+ */
260
+ test("renders the categories in the order they were given", () => {
261
+ renderList();
262
+
263
+ expect(
264
+ screen
265
+ .getAllByRole("heading", { level: 4 })
266
+ .map((heading: HTMLElement) => {
267
+ return heading.textContent;
268
+ }),
269
+ ).toEqual(["Control Plane", "Workload", "Storage"]);
270
+ });
271
+
272
+ test("renders a card for every recommendation in every group", () => {
273
+ renderList();
274
+
275
+ expect(screen.getByText("API Server Down")).toBeInTheDocument();
276
+ expect(screen.getByText("Etcd Has No Leader")).toBeInTheDocument();
277
+ expect(screen.getByText("Node Not Ready")).toBeInTheDocument();
278
+ expect(screen.getByText("Pod Crash Looping")).toBeInTheDocument();
279
+ expect(screen.getByText("Job Failed")).toBeInTheDocument();
280
+ expect(
281
+ screen.getByText("Persistent Volume Almost Full"),
282
+ ).toBeInTheDocument();
283
+ });
284
+
285
+ /*
286
+ * Cards carry their own state, and the list must not flatten it: only the
287
+ * available ones offer selection, because creating something that already
288
+ * exists duplicates a monitor and creating something dismissed contradicts
289
+ * the dismissal shown on the card.
290
+ */
291
+ test("only the available cards offer selection", () => {
292
+ renderList();
293
+
294
+ expect(
295
+ screen.getByRole("button", { name: "Select API Server Down" }),
296
+ ).toBeInTheDocument();
297
+ expect(
298
+ screen.getByRole("button", { name: "Select Pod Crash Looping" }),
299
+ ).toBeInTheDocument();
300
+ expect(
301
+ screen.queryByRole("button", { name: "Select Node Not Ready" }),
302
+ ).not.toBeInTheDocument();
303
+ expect(
304
+ screen.queryByRole("button", { name: "Select Job Failed" }),
305
+ ).not.toBeInTheDocument();
306
+ });
307
+
308
+ test("a dismissed card still shows why it was dismissed", () => {
309
+ renderList();
310
+
311
+ expect(
312
+ screen.getByText("We run these jobs by hand."),
313
+ ).toBeInTheDocument();
314
+ });
315
+ });
316
+
317
+ describe("heading counts", () => {
318
+ /*
319
+ * "<n> to set up" is the number a person uses to decide whether to open
320
+ * the section at all, so it counts only what is actually left: the created
321
+ * and dismissed cards below it are not work.
322
+ */
323
+ test("a category with work left says how much", () => {
324
+ renderList();
325
+
326
+ expect(
327
+ within(groupHeading("Control Plane")).getByText("2 to set up"),
328
+ ).toBeInTheDocument();
329
+ expect(
330
+ within(groupHeading("Workload")).getByText("1 to set up"),
331
+ ).toBeInTheDocument();
332
+ });
333
+
334
+ test("it also says how much has already been handled", () => {
335
+ renderList();
336
+
337
+ expect(
338
+ within(groupHeading("Control Plane")).getByText("1 handled"),
339
+ ).toBeInTheDocument();
340
+ expect(
341
+ within(groupHeading("Workload")).getByText("1 handled"),
342
+ ).toBeInTheDocument();
343
+ });
344
+
345
+ /*
346
+ * A finished category reads as finished rather than as "0 to set up",
347
+ * which is the same information dressed as an outstanding task.
348
+ */
349
+ test("a category with nothing left reads as all handled", () => {
350
+ renderList();
351
+
352
+ const storage: HTMLElement = groupHeading("Storage");
353
+
354
+ expect(within(storage).getByText("All handled")).toBeInTheDocument();
355
+ expect(within(storage).queryByText(/to set up/)).not.toBeInTheDocument();
356
+ });
357
+
358
+ test("a category with nothing handled shows no handled count", () => {
359
+ renderList({
360
+ groups: [
361
+ {
362
+ category: "Control Plane",
363
+ recommendations: [API_SERVER_DOWN, ETCD_NO_LEADER],
364
+ },
365
+ ],
366
+ });
367
+
368
+ const controlPlane: HTMLElement = groupHeading("Control Plane");
369
+
370
+ expect(within(controlPlane).getByText("2 to set up")).toBeInTheDocument();
371
+ expect(
372
+ within(controlPlane).queryByText(/handled/),
373
+ ).not.toBeInTheDocument();
374
+ });
375
+ });
376
+
377
+ describe("select all", () => {
378
+ test("the control names how many it will select", () => {
379
+ renderList();
380
+
381
+ expect(
382
+ within(groupHeading("Control Plane")).getByRole("button", {
383
+ name: "Select all 2",
384
+ }),
385
+ ).toBeInTheDocument();
386
+ expect(
387
+ within(groupHeading("Workload")).getByRole("button", {
388
+ name: "Select all 1",
389
+ }),
390
+ ).toBeInTheDocument();
391
+ });
392
+
393
+ /*
394
+ * The created and dismissed cards in the same category must stay out of
395
+ * the Set. They are filtered out again before the create request, so
396
+ * including them here would make the button offer more monitors than it
397
+ * can create.
398
+ */
399
+ test("it selects every available recommendation in the category and nothing else", () => {
400
+ renderList();
401
+
402
+ fireEvent.click(screen.getByRole("button", { name: "Select all 2" }));
403
+
404
+ expect(selectionChanges).toHaveLength(1);
405
+ expect(latestSelection()).toEqual(
406
+ new Set<string>([idOf(API_SERVER_DOWN), idOf(ETCD_NO_LEADER)]),
407
+ );
408
+ expect(latestSelection().has(idOf(NODE_NOT_READY))).toBe(false);
409
+ });
410
+
411
+ test("it does not touch a category the user has not pressed", () => {
412
+ renderList();
413
+
414
+ fireEvent.click(screen.getByRole("button", { name: "Select all 1" }));
415
+
416
+ expect(latestSelection()).toEqual(
417
+ new Set<string>([idOf(POD_CRASH_LOOPING)]),
418
+ );
419
+ });
420
+
421
+ /*
422
+ * Additivity is the whole point: pressing Select all on a second category
423
+ * has to keep the first one. Replacing the Set instead would silently drop
424
+ * everything the user picked before, and the only symptom is a lower
425
+ * number on the create button.
426
+ */
427
+ test("it adds to selections made in other categories", () => {
428
+ renderList({
429
+ selectedRecommendationIds: new Set<string>([idOf(POD_CRASH_LOOPING)]),
430
+ });
431
+
432
+ fireEvent.click(screen.getByRole("button", { name: "Select all 2" }));
433
+
434
+ expect(latestSelection()).toEqual(
435
+ new Set<string>([
436
+ idOf(POD_CRASH_LOOPING),
437
+ idOf(API_SERVER_DOWN),
438
+ idOf(ETCD_NO_LEADER),
439
+ ]),
440
+ );
441
+ });
442
+
443
+ // Partially selected is still "select the rest", not "clear".
444
+ test("with some of the category selected it still reads as select all", () => {
445
+ renderList({
446
+ selectedRecommendationIds: new Set<string>([idOf(API_SERVER_DOWN)]),
447
+ });
448
+
449
+ expect(
450
+ within(groupHeading("Control Plane")).getByRole("button", {
451
+ name: "Select all 2",
452
+ }),
453
+ ).toBeInTheDocument();
454
+
455
+ fireEvent.click(screen.getByRole("button", { name: "Select all 2" }));
456
+
457
+ expect(latestSelection()).toEqual(
458
+ new Set<string>([idOf(API_SERVER_DOWN), idOf(ETCD_NO_LEADER)]),
459
+ );
460
+ });
461
+
462
+ test("with the whole category selected it reads as a clear action", () => {
463
+ renderList({
464
+ selectedRecommendationIds: new Set<string>([
465
+ idOf(API_SERVER_DOWN),
466
+ idOf(ETCD_NO_LEADER),
467
+ ]),
468
+ });
469
+
470
+ expect(
471
+ within(groupHeading("Control Plane")).getByRole("button", {
472
+ name: "Clear all",
473
+ }),
474
+ ).toBeInTheDocument();
475
+ });
476
+
477
+ test("clearing removes exactly that category and leaves the rest selected", () => {
478
+ renderList({
479
+ selectedRecommendationIds: new Set<string>([
480
+ idOf(API_SERVER_DOWN),
481
+ idOf(ETCD_NO_LEADER),
482
+ idOf(POD_CRASH_LOOPING),
483
+ ]),
484
+ });
485
+
486
+ /*
487
+ * Scoped to the category on purpose: with Workload's only available
488
+ * recommendation selected too, both headings read "Clear all" at the
489
+ * same time, and the point of the assertion is that pressing one of them
490
+ * leaves the other category's selection alone.
491
+ */
492
+ fireEvent.click(
493
+ within(groupHeading("Control Plane")).getByRole("button", {
494
+ name: "Clear all",
495
+ }),
496
+ );
497
+
498
+ expect(latestSelection()).toEqual(
499
+ new Set<string>([idOf(POD_CRASH_LOOPING)]),
500
+ );
501
+ });
502
+
503
+ /*
504
+ * A category with nothing to set up has nothing to select, and an
505
+ * always-visible "Select all 0" on a finished section is a control that
506
+ * can only ever do nothing.
507
+ */
508
+ test("a fully handled category offers no select-all", () => {
509
+ renderList();
510
+
511
+ expect(
512
+ within(groupHeading("Storage")).queryByRole("button"),
513
+ ).not.toBeInTheDocument();
514
+ });
515
+ });
516
+
517
+ describe("while a create is in flight", () => {
518
+ /*
519
+ * isDisabled is set while the bulk create runs. Changing the selection
520
+ * underneath a request that is already using it is how a user ends up
521
+ * with monitors they did not pick.
522
+ */
523
+ test("isDisabled hides the select-all control entirely", () => {
524
+ renderList({ isDisabled: true });
525
+
526
+ expect(
527
+ screen.queryByRole("button", { name: /Select all/ }),
528
+ ).not.toBeInTheDocument();
529
+ expect(
530
+ screen.queryByRole("button", { name: "Clear all" }),
531
+ ).not.toBeInTheDocument();
532
+ });
533
+
534
+ test("the cards still render while disabled", () => {
535
+ renderList({ isDisabled: true });
536
+
537
+ expect(screen.getByText("API Server Down")).toBeInTheDocument();
538
+ expect(screen.getByText("Pod Crash Looping")).toBeInTheDocument();
539
+ });
540
+ });
541
+
542
+ describe("selecting one card", () => {
543
+ /*
544
+ * Add to the Set, never replace it. Selection is built one card at a time
545
+ * across several categories, and a card that replaced it would let a user
546
+ * tick five things and create one.
547
+ */
548
+ test("ticking a card keeps everything already selected", () => {
549
+ renderList({
550
+ selectedRecommendationIds: new Set<string>([idOf(POD_CRASH_LOOPING)]),
551
+ });
552
+
553
+ fireEvent.click(
554
+ screen.getByRole("button", { name: "Select API Server Down" }),
555
+ );
556
+
557
+ expect(latestSelection()).toEqual(
558
+ new Set<string>([idOf(POD_CRASH_LOOPING), idOf(API_SERVER_DOWN)]),
559
+ );
560
+ });
561
+
562
+ test("unticking a card removes only that one", () => {
563
+ renderList({
564
+ selectedRecommendationIds: new Set<string>([
565
+ idOf(API_SERVER_DOWN),
566
+ idOf(ETCD_NO_LEADER),
567
+ idOf(POD_CRASH_LOOPING),
568
+ ]),
569
+ });
570
+
571
+ fireEvent.click(
572
+ screen.getByRole("button", { name: "Select API Server Down" }),
573
+ );
574
+
575
+ expect(latestSelection()).toEqual(
576
+ new Set<string>([idOf(ETCD_NO_LEADER), idOf(POD_CRASH_LOOPING)]),
577
+ );
578
+ });
579
+
580
+ test("a selected card is announced as pressed", () => {
581
+ renderList({
582
+ selectedRecommendationIds: new Set<string>([idOf(API_SERVER_DOWN)]),
583
+ });
584
+
585
+ expect(
586
+ screen.getByRole("button", { name: "Select API Server Down" }),
587
+ ).toHaveAttribute("aria-pressed", "true");
588
+ expect(
589
+ screen.getByRole("button", { name: "Select Etcd Has No Leader" }),
590
+ ).toHaveAttribute("aria-pressed", "false");
591
+ });
592
+ });
593
+
594
+ describe("dismiss and restore", () => {
595
+ /*
596
+ * Both handlers take the view model rather than an id, and the page needs
597
+ * the right one: dismissing writes a row keyed on that recommendation, and
598
+ * restoring deletes the dismissal row carried on that view model. Handing
599
+ * back a neighbouring card's model dismisses the wrong recommendation, and
600
+ * the user watches a different card disappear.
601
+ */
602
+ test("dismissing a card hands back that card's own recommendation", () => {
603
+ renderList();
604
+
605
+ fireEvent.click(
606
+ screen.getByRole("button", { name: "Dismiss Etcd Has No Leader" }),
607
+ );
608
+
609
+ expect(dismissed).toHaveLength(1);
610
+ expect(dismissed[0]).toBe(ETCD_NO_LEADER);
611
+ expect(selectionChanges).toHaveLength(0);
612
+ });
613
+
614
+ test("only the available cards can be dismissed", () => {
615
+ renderList();
616
+
617
+ expect(
618
+ screen.getByRole("button", { name: "Dismiss API Server Down" }),
619
+ ).toBeInTheDocument();
620
+ expect(
621
+ screen.queryByRole("button", { name: "Dismiss Node Not Ready" }),
622
+ ).not.toBeInTheDocument();
623
+ expect(
624
+ screen.queryByRole("button", { name: "Dismiss Job Failed" }),
625
+ ).not.toBeInTheDocument();
626
+ });
627
+
628
+ test("restoring hands back the dismissed card's view model", () => {
629
+ renderList();
630
+
631
+ fireEvent.click(screen.getByRole("button", { name: "Restore" }));
632
+
633
+ expect(restored).toHaveLength(1);
634
+ expect(restored[0]).toBe(JOB_FAILED);
635
+ expect(restored[0]?.dismissalId).toBe(JOB_FAILED.dismissalId);
636
+ });
637
+ });
638
+
639
+ describe("created cards", () => {
640
+ /*
641
+ * The only reason the list knows about routes at all. A created card whose
642
+ * link is built from the wrong card's monitorId sends the user to somebody
643
+ * else's monitor, which reads as "this recommendation created the wrong
644
+ * thing".
645
+ */
646
+ test("a created card links to the monitor built from its own monitorId", () => {
647
+ renderList();
648
+
649
+ const links: Array<HTMLElement> = screen.getAllByRole("link", {
650
+ name: "View monitor",
651
+ });
652
+
653
+ expect(links).toHaveLength(2);
654
+ expect(monitorRouteRequests).toEqual([MONITOR_ID, STORAGE_MONITOR_ID]);
655
+ expect(links[0]).toHaveAttribute(
656
+ "href",
657
+ `/dashboard/monitors/${MONITOR_ID.toString()}`,
658
+ );
659
+ });
660
+ });
661
+ });