@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,791 @@
1
+ import "@testing-library/jest-dom";
2
+ import { cleanup, render, screen, waitFor } from "@testing-library/react";
3
+ import React, { ReactElement } from "react";
4
+ import { MemoryRouter } from "react-router-dom";
5
+ import {
6
+ afterEach,
7
+ beforeEach,
8
+ describe,
9
+ expect,
10
+ jest,
11
+ test,
12
+ } from "@jest/globals";
13
+ import getJestMockFunction, { MockFunction } from "../../MockType";
14
+ import Monitor from "../../../Models/DatabaseModels/Monitor";
15
+ import NetworkDevice from "../../../Models/DatabaseModels/NetworkDevice";
16
+ import NetworkDeviceMonitoringMethod from "../../../Types/NetworkDevice/NetworkDeviceMonitoringMethod";
17
+ import ObjectID from "../../../Types/ObjectID";
18
+ import FormFieldSchemaType from "../../../UI/Components/Forms/Types/FormFieldSchemaType";
19
+
20
+ /*
21
+ * The create form's "Also create a Ping monitor for incidents" opt-in.
22
+ *
23
+ * Every device this form registers is probe-polled: its probe pings it on a
24
+ * schedule, so it has a status from its first poll and needs no monitor to
25
+ * read Up or Down. What it has no way to do on its own is RAISE something —
26
+ * an incident, a page, an alert — and until alert policies land, a Ping
27
+ * monitor created on the device's address and bound to it is the only
28
+ * one-click way to get that. So the opt-in stays, and says that instead.
29
+ *
30
+ * The properties that make it SAFE rather than merely present are all
31
+ * invisible in a screenshot:
32
+ *
33
+ * - it is OFF by default (monitors are billable and plan-limited, and a
34
+ * hidden checkbox that defaulted on would still be submitted);
35
+ * - it is offered only to someone allowed to create a monitor, because a
36
+ * box that fails on save is worse than no box;
37
+ * - the device is created FIRST and the monitor second, so a plan limit or
38
+ * a permission gap on the monitor never costs the operator the device;
39
+ * - an empty probe selection sends no `probes` key (an explicit empty
40
+ * selection means "attach nothing" to the server);
41
+ * - a failure is shown on the page and the device stays listed and polled,
42
+ * with nothing alerting on it — which is an allowed, explained state;
43
+ * - the list is refreshed afterwards, because the table refetches BEFORE
44
+ * onCreateSuccess runs, and would otherwise show the new device as
45
+ * carrying no monitor when one was bound to it a moment later.
46
+ *
47
+ * ModelTable is replaced by a prop recorder and its create hooks are called
48
+ * directly — the point is what the page does around the create, not the
49
+ * table (the same approach as NetworkDeviceBulkDelete.test.tsx).
50
+ */
51
+
52
+ jest.mock("react-i18next", () => {
53
+ return {
54
+ useTranslation: () => {
55
+ return {
56
+ t: (key: string): string => {
57
+ return key;
58
+ },
59
+ };
60
+ },
61
+ };
62
+ });
63
+
64
+ jest.mock("../../../UI/Utils/Permission", () => {
65
+ return {
66
+ __esModule: true,
67
+ default: {
68
+ getAllPermissions: () => {
69
+ return [];
70
+ },
71
+ getProjectPermissions: () => {
72
+ return [];
73
+ },
74
+ getGlobalPermissions: () => {
75
+ return [];
76
+ },
77
+ },
78
+ };
79
+ });
80
+
81
+ jest.mock("../../../UI/Utils/User", () => {
82
+ return {
83
+ __esModule: true,
84
+ default: {
85
+ isMasterAdmin: () => {
86
+ return false;
87
+ },
88
+ getUserId: () => {
89
+ return null;
90
+ },
91
+ },
92
+ };
93
+ });
94
+
95
+ const PROJECT_ID: ObjectID = new ObjectID(
96
+ "11111111-0000-4000-8000-000000000001",
97
+ );
98
+ const DEVICE_ID: ObjectID = new ObjectID(
99
+ "22222222-0000-4000-8000-000000000001",
100
+ );
101
+ const MONITOR_ID: ObjectID = new ObjectID(
102
+ "33333333-0000-4000-8000-000000000001",
103
+ );
104
+ jest.mock("../../../UI/Utils/Project", () => {
105
+ return {
106
+ __esModule: true,
107
+ default: {
108
+ getCurrentProjectId: () => {
109
+ return PROJECT_ID;
110
+ },
111
+ },
112
+ };
113
+ });
114
+
115
+ /*
116
+ * Whether the viewer may create a Monitor. Flipped per test: the opt-in must
117
+ * vanish for someone who could not complete it.
118
+ */
119
+ let canCreateMonitor: boolean = true;
120
+
121
+ jest.mock("../../../UI/Utils/PermissionGate", () => {
122
+ return {
123
+ __esModule: true,
124
+ default: {
125
+ check: () => {
126
+ return {
127
+ isAllowed: canCreateMonitor,
128
+ disabledReason: canCreateMonitor
129
+ ? undefined
130
+ : "You do not have permission to create monitors.",
131
+ };
132
+ },
133
+ },
134
+ ModelAction: {
135
+ Create: "create",
136
+ Read: "read",
137
+ Update: "update",
138
+ Delete: "delete",
139
+ },
140
+ };
141
+ });
142
+
143
+ const modelApiCreate: MockFunction = getJestMockFunction();
144
+ const modelApiUpdateById: MockFunction = getJestMockFunction();
145
+ const modelApiDeleteItem: MockFunction = getJestMockFunction();
146
+
147
+ jest.mock("../../../UI/Utils/ModelAPI/ModelAPI", () => {
148
+ return {
149
+ __esModule: true,
150
+ default: {
151
+ create: (...args: Array<unknown>) => {
152
+ return modelApiCreate(...args);
153
+ },
154
+ updateById: (...args: Array<unknown>) => {
155
+ return modelApiUpdateById(...args);
156
+ },
157
+ deleteItem: (...args: Array<unknown>) => {
158
+ return modelApiDeleteItem(...args);
159
+ },
160
+ getList: () => {
161
+ return Promise.resolve({ data: [], count: 0 });
162
+ },
163
+ },
164
+ };
165
+ });
166
+
167
+ jest.mock(
168
+ "../../../../App/FeatureSet/Dashboard/src/Components/NetworkDevice/PingMonitorSeedIds",
169
+ () => {
170
+ return {
171
+ __esModule: true,
172
+ default: {
173
+ resolve: () => {
174
+ return Promise.resolve({
175
+ onlineMonitorStatusId: new ObjectID(
176
+ "44444444-0000-4000-8000-000000000001",
177
+ ),
178
+ offlineMonitorStatusId: new ObjectID(
179
+ "44444444-0000-4000-8000-000000000002",
180
+ ),
181
+ defaultIncidentSeverityId: new ObjectID(
182
+ "55555555-0000-4000-8000-000000000001",
183
+ ),
184
+ defaultAlertSeverityId: new ObjectID(
185
+ "66666666-0000-4000-8000-000000000001",
186
+ ),
187
+ });
188
+ },
189
+ },
190
+ };
191
+ },
192
+ );
193
+
194
+ type FormValuesLike = Record<string, unknown>;
195
+
196
+ type CapturedFormField = {
197
+ field?: Record<string, unknown> | undefined;
198
+ overrideField?: Record<string, unknown> | undefined;
199
+ overrideFieldKey?: string | undefined;
200
+ showEvenIfPermissionDoesNotExist?: boolean | undefined;
201
+ title?: string | undefined;
202
+ stepId?: string | undefined;
203
+ description?: string | undefined;
204
+ fieldType?: FormFieldSchemaType | undefined;
205
+ defaultValue?: unknown;
206
+ required?: boolean | ((values: FormValuesLike) => boolean) | undefined;
207
+ showIf?: ((values: FormValuesLike) => boolean) | undefined;
208
+ dropdownOptions?: Array<{ label: string; value: unknown }> | undefined;
209
+ };
210
+
211
+ type CapturedFormStep = {
212
+ id: string;
213
+ title: string;
214
+ };
215
+
216
+ type CapturedTableProps = {
217
+ formFields?: Array<CapturedFormField> | undefined;
218
+ formSteps?: Array<CapturedFormStep> | undefined;
219
+ refreshToggle?: string | undefined;
220
+ onBeforeCreate?:
221
+ | ((
222
+ item: NetworkDevice,
223
+ miscDataProps: Record<string, unknown>,
224
+ ) => Promise<NetworkDevice>)
225
+ | undefined;
226
+ onCreateSuccess?:
227
+ | ((item: NetworkDevice) => Promise<NetworkDevice>)
228
+ | undefined;
229
+ };
230
+
231
+ let capturedTableProps: CapturedTableProps | null = null;
232
+
233
+ jest.mock("../../../UI/Components/ModelTable/ModelTable", () => {
234
+ return {
235
+ __esModule: true,
236
+ default: (props: CapturedTableProps) => {
237
+ capturedTableProps = props;
238
+ return null;
239
+ },
240
+ };
241
+ });
242
+
243
+ jest.mock(
244
+ "../../../../App/FeatureSet/Dashboard/src/Components/ResourceOwners/useResourceOwners",
245
+ () => {
246
+ const actual: Record<string, unknown> = jest.requireActual(
247
+ "../../../../App/FeatureSet/Dashboard/src/Components/ResourceOwners/useResourceOwners",
248
+ ) as Record<string, unknown>;
249
+
250
+ return {
251
+ ...actual,
252
+ __esModule: true,
253
+ default: () => {
254
+ return {
255
+ filterBar: null,
256
+ mergeFiltersIntoQuery: (
257
+ base: Record<string, unknown> | undefined,
258
+ ) => {
259
+ return base || {};
260
+ },
261
+ hasActiveFilters: false,
262
+ facetSelections: {},
263
+ facetOperators: {},
264
+ setFacetSelection: () => {
265
+ // no-op
266
+ },
267
+ clearAllFacets: () => {
268
+ // no-op
269
+ },
270
+ facetSaveState: {},
271
+ restoreFacetState: () => {
272
+ // no-op
273
+ },
274
+ getOwnersForResource: () => {
275
+ return [];
276
+ },
277
+ isLoadingOwners: false,
278
+ onResourcesFetched: () => {
279
+ // no-op
280
+ },
281
+ };
282
+ },
283
+ };
284
+ },
285
+ );
286
+
287
+ jest.mock("../../../UI/Components/BulkUpdate/BulkLabelActions", () => {
288
+ return {
289
+ __esModule: true,
290
+ default: () => {
291
+ return { bulkActions: [], modals: null };
292
+ },
293
+ };
294
+ });
295
+
296
+ jest.mock(
297
+ "../../../../App/FeatureSet/Dashboard/src/Components/NetworkDevice/useBulkOidTemplateActions",
298
+ () => {
299
+ return {
300
+ __esModule: true,
301
+ default: () => {
302
+ return { bulkActions: [], modals: null };
303
+ },
304
+ };
305
+ },
306
+ );
307
+
308
+ jest.mock(
309
+ "../../../../App/FeatureSet/Dashboard/src/Components/NetworkDevice/DeviceSummaryCards",
310
+ () => {
311
+ return {
312
+ __esModule: true,
313
+ default: () => {
314
+ return null;
315
+ },
316
+ };
317
+ },
318
+ );
319
+
320
+ /*
321
+ * One probe, so the "Ping from probes" picker has something to offer and
322
+ * its visibility rule (only when there is a probe to pick) is exercised
323
+ * against real data.
324
+ */
325
+ jest.mock("../../../../App/FeatureSet/Dashboard/src/Utils/Probe", () => {
326
+ return {
327
+ __esModule: true,
328
+ default: {
329
+ getAllProbes: async () => {
330
+ return [{ _id: "probe-1", name: "Branch probe" }];
331
+ },
332
+ },
333
+ };
334
+ });
335
+
336
+ import NetworkDevicesPage, {
337
+ CREATE_PING_MONITOR_FIELD_KEY,
338
+ PING_PROBES_FIELD_KEY,
339
+ } from "../../../../App/FeatureSet/Dashboard/src/Pages/NetworkDevice/Devices";
340
+ import PageComponentProps from "../../../../App/FeatureSet/Dashboard/src/Pages/PageComponentProps";
341
+ import Route from "../../../Types/API/Route";
342
+
343
+ const PAGE_PROPS: PageComponentProps = {
344
+ pageRoute: new Route("/dashboard/network-devices"),
345
+ currentProject: null,
346
+ hasPaymentMethod: true,
347
+ };
348
+
349
+ async function renderDevicesPage(): Promise<CapturedTableProps> {
350
+ const Page: (props: PageComponentProps) => ReactElement =
351
+ NetworkDevicesPage as unknown as (
352
+ props: PageComponentProps,
353
+ ) => ReactElement;
354
+
355
+ render(
356
+ <MemoryRouter>
357
+ <Page {...PAGE_PROPS} />
358
+ </MemoryRouter>,
359
+ );
360
+
361
+ await waitFor(() => {
362
+ expect(capturedTableProps).not.toBeNull();
363
+ });
364
+
365
+ return capturedTableProps!;
366
+ }
367
+
368
+ function overrideFieldFor(
369
+ props: CapturedTableProps,
370
+ key: string,
371
+ ): CapturedFormField {
372
+ const match: CapturedFormField | undefined = (props.formFields || []).find(
373
+ (field: CapturedFormField): boolean => {
374
+ return field.overrideFieldKey === key;
375
+ },
376
+ );
377
+
378
+ expect({ key: key, found: Boolean(match) }).toEqual({
379
+ key: key,
380
+ found: true,
381
+ });
382
+
383
+ return match!;
384
+ }
385
+
386
+ function isShown(field: CapturedFormField, values: FormValuesLike): boolean {
387
+ return field.showIf ? field.showIf(values) : true;
388
+ }
389
+
390
+ /*
391
+ * The form values a half-filled create form holds. There is no monitoring
392
+ * method among them any more — the form does not ask — so this is every
393
+ * device it can create.
394
+ */
395
+ const DEVICE: FormValuesLike = {
396
+ name: "lobby-ap-01",
397
+ hostname: "10.0.0.7",
398
+ };
399
+
400
+ function deviceBeingCreated(): NetworkDevice {
401
+ const item: NetworkDevice = new NetworkDevice();
402
+ item.name = "lobby-ap-01";
403
+ item.hostname = "10.0.0.7";
404
+
405
+ return item;
406
+ }
407
+
408
+ function createdDevice(): NetworkDevice {
409
+ const device: NetworkDevice = new NetworkDevice();
410
+ device.id = DEVICE_ID;
411
+ device.name = "lobby-ap-01";
412
+ device.hostname = "10.0.0.7";
413
+ device.monitoringMethod = NetworkDeviceMonitoringMethod.Probe;
414
+ return device;
415
+ }
416
+
417
+ /** Drive the two table hooks the way ModelTable does around a create. */
418
+ async function runCreate(
419
+ props: CapturedTableProps,
420
+ data: {
421
+ miscDataProps: Record<string, unknown>;
422
+ },
423
+ ): Promise<NetworkDevice> {
424
+ expect(props.onBeforeCreate).toBeDefined();
425
+ expect(props.onCreateSuccess).toBeDefined();
426
+
427
+ await props.onBeforeCreate!(deviceBeingCreated(), data.miscDataProps);
428
+
429
+ return props.onCreateSuccess!(createdDevice());
430
+ }
431
+
432
+ describe("the create form's Create a Ping monitor opt-in", () => {
433
+ beforeEach(() => {
434
+ capturedTableProps = null;
435
+ canCreateMonitor = true;
436
+ window.localStorage.clear();
437
+ modelApiCreate.mockReset();
438
+ modelApiUpdateById.mockReset();
439
+ modelApiDeleteItem.mockReset();
440
+ modelApiCreate.mockResolvedValue({ data: { id: MONITOR_ID } } as never);
441
+ modelApiUpdateById.mockResolvedValue({} as never);
442
+ modelApiDeleteItem.mockResolvedValue({} as never);
443
+ });
444
+
445
+ afterEach(() => {
446
+ cleanup();
447
+ jest.clearAllMocks();
448
+ });
449
+
450
+ describe("the fields", () => {
451
+ test("the checkbox is an override field on the probe-and-site step, off by default", async () => {
452
+ const props: CapturedTableProps = await renderDevicesPage();
453
+ const checkbox: CapturedFormField = overrideFieldFor(
454
+ props,
455
+ CREATE_PING_MONITOR_FIELD_KEY,
456
+ );
457
+
458
+ expect(checkbox.field).toBeUndefined();
459
+ expect(checkbox.overrideField).toEqual({
460
+ [CREATE_PING_MONITOR_FIELD_KEY]: true,
461
+ });
462
+ expect(checkbox.showEvenIfPermissionDoesNotExist).toBe(true);
463
+ expect(checkbox.fieldType).toBe(FormFieldSchemaType.Checkbox);
464
+ /*
465
+ * No defaultValue AT ALL, which is what "off" means here: BasicForm
466
+ * seeds a defaultValue with no showIf check, so a box that defaulted on
467
+ * would spend the operator's monitor quota even while hidden.
468
+ */
469
+ expect(checkbox.defaultValue).toBeUndefined();
470
+ expect(checkbox.required).toBe(false);
471
+
472
+ const stepIds: Array<string> = (props.formSteps || []).map(
473
+ (step: CapturedFormStep): string => {
474
+ return step.id;
475
+ },
476
+ );
477
+ expect(checkbox.stepId).toBe("probe-and-site");
478
+ expect(stepIds).toContain("probe-and-site");
479
+ });
480
+
481
+ /*
482
+ * The title carries the whole offer, because the checkbox is the one
483
+ * field an operator decides on without reading anything else: "also"
484
+ * says the device is already monitored without it, "for incidents" says
485
+ * what it adds, and "(optional)" says it may be skipped.
486
+ */
487
+ test("the checkbox is worded as an addition, not as the way to get a status", async () => {
488
+ const props: CapturedTableProps = await renderDevicesPage();
489
+ const checkbox: CapturedFormField = overrideFieldFor(
490
+ props,
491
+ CREATE_PING_MONITOR_FIELD_KEY,
492
+ );
493
+
494
+ expect(checkbox.title).toBe(
495
+ "Also create a Ping monitor for incidents (optional)",
496
+ );
497
+ });
498
+
499
+ /*
500
+ * Offered for every device this form creates. It used to be offered only
501
+ * for a monitor-backed device with nothing bound, because a monitor was
502
+ * the only thing that could give such a device a status; a probe-polled
503
+ * device has one either way, and the monitor is what alerts on it.
504
+ */
505
+ test("the checkbox is offered for the device being registered", async () => {
506
+ const props: CapturedTableProps = await renderDevicesPage();
507
+ const checkbox: CapturedFormField = overrideFieldFor(
508
+ props,
509
+ CREATE_PING_MONITOR_FIELD_KEY,
510
+ );
511
+
512
+ expect(isShown(checkbox, DEVICE)).toBe(true);
513
+ // Nothing about the device can hide it - not even an empty form.
514
+ expect(isShown(checkbox, {})).toBe(true);
515
+ });
516
+
517
+ test("the checkbox is hidden for someone who may not create a monitor", async () => {
518
+ canCreateMonitor = false;
519
+
520
+ const props: CapturedTableProps = await renderDevicesPage();
521
+
522
+ expect(
523
+ isShown(overrideFieldFor(props, CREATE_PING_MONITOR_FIELD_KEY), DEVICE),
524
+ ).toBe(false);
525
+ });
526
+
527
+ /*
528
+ * The copy has to say the monitor is an ADDITION — an operator who reads
529
+ * it as "this is how the device gets a status" will tick it for every
530
+ * device in the estate and pay for all of them.
531
+ */
532
+ test("the checkbox says the probe already gives the device a status", async () => {
533
+ const props: CapturedTableProps = await renderDevicesPage();
534
+ const checkbox: CapturedFormField = overrideFieldFor(
535
+ props,
536
+ CREATE_PING_MONITOR_FIELD_KEY,
537
+ );
538
+
539
+ expect(checkbox.description).toContain("already pings this device");
540
+ expect(checkbox.description).toContain("incident");
541
+ expect(checkbox.description).toContain("counts towards your plan");
542
+ expect(checkbox.description).toContain("incidents are off");
543
+ /*
544
+ * "No monitor" is the pill a monitor-backed device with nothing bound
545
+ * wears. No device created by this form can ever read it, so promising
546
+ * it here would send the operator hunting for a state that cannot
547
+ * happen.
548
+ */
549
+ expect(checkbox.description).not.toContain("No monitor");
550
+ });
551
+
552
+ test("the probe picker appears only once the box is ticked, and lists the project's probes", async () => {
553
+ const props: CapturedTableProps = await renderDevicesPage();
554
+ const probes: CapturedFormField = overrideFieldFor(
555
+ props,
556
+ PING_PROBES_FIELD_KEY,
557
+ );
558
+
559
+ expect(probes.fieldType).toBe(FormFieldSchemaType.MultiSelectDropdown);
560
+ expect(probes.stepId).toBe("probe-and-site");
561
+ expect(probes.required).toBe(false);
562
+ expect(probes.showEvenIfPermissionDoesNotExist).toBe(true);
563
+ expect(probes.dropdownOptions).toEqual([
564
+ { label: "Branch probe", value: "probe-1" },
565
+ ]);
566
+
567
+ expect(isShown(probes, DEVICE)).toBe(false);
568
+ expect(
569
+ isShown(probes, {
570
+ ...DEVICE,
571
+ [CREATE_PING_MONITOR_FIELD_KEY]: true,
572
+ }),
573
+ ).toBe(true);
574
+ });
575
+
576
+ test("the probe picker is hidden from someone who is not offered the box", async () => {
577
+ canCreateMonitor = false;
578
+
579
+ const props: CapturedTableProps = await renderDevicesPage();
580
+
581
+ expect(
582
+ isShown(overrideFieldFor(props, PING_PROBES_FIELD_KEY), {
583
+ ...DEVICE,
584
+ [CREATE_PING_MONITOR_FIELD_KEY]: true,
585
+ }),
586
+ ).toBe(false);
587
+ });
588
+ });
589
+
590
+ describe("what happens after the device is created", () => {
591
+ test("creates a Ping monitor on the device's address and binds it", async () => {
592
+ const props: CapturedTableProps = await renderDevicesPage();
593
+
594
+ const returned: NetworkDevice = await runCreate(props, {
595
+ miscDataProps: {
596
+ [CREATE_PING_MONITOR_FIELD_KEY]: true,
597
+ [PING_PROBES_FIELD_KEY]: ["probe-1"],
598
+ },
599
+ });
600
+
601
+ expect(returned.id?.toString()).toBe(DEVICE_ID.toString());
602
+
603
+ expect(modelApiCreate).toHaveBeenCalledTimes(1);
604
+ const createCall: {
605
+ model: Monitor;
606
+ modelType: unknown;
607
+ miscDataProps: Record<string, unknown>;
608
+ } = modelApiCreate.mock.calls[0]![0] as {
609
+ model: Monitor;
610
+ modelType: unknown;
611
+ miscDataProps: Record<string, unknown>;
612
+ };
613
+ expect(createCall.modelType).toBe(Monitor);
614
+ expect(createCall.model.name).toBe("Ping lobby-ap-01");
615
+ expect(
616
+ createCall.model.monitorSteps?.data?.monitorStepsInstanceArray[0]?.data?.monitorDestination?.toString(),
617
+ ).toBe("10.0.0.7");
618
+ expect(createCall.miscDataProps).toEqual({ probes: ["probe-1"] });
619
+
620
+ expect(modelApiUpdateById).toHaveBeenCalledTimes(1);
621
+ const bind: { id: ObjectID; data: Record<string, unknown> } =
622
+ modelApiUpdateById.mock.calls[0]![0] as {
623
+ id: ObjectID;
624
+ data: Record<string, unknown>;
625
+ };
626
+ expect(bind.id.toString()).toBe(DEVICE_ID.toString());
627
+ expect(bind.data).toEqual({ monitorId: MONITOR_ID.toString() });
628
+ });
629
+
630
+ test("creates the device's monitor after the device exists, not before", async () => {
631
+ const props: CapturedTableProps = await renderDevicesPage();
632
+
633
+ // onBeforeCreate alone must not touch the API.
634
+ await props.onBeforeCreate!(deviceBeingCreated(), {
635
+ [CREATE_PING_MONITOR_FIELD_KEY]: true,
636
+ });
637
+
638
+ expect(modelApiCreate).not.toHaveBeenCalled();
639
+ });
640
+
641
+ test("sends no probes key when no probe was picked", async () => {
642
+ const props: CapturedTableProps = await renderDevicesPage();
643
+
644
+ await runCreate(props, {
645
+ miscDataProps: { [CREATE_PING_MONITOR_FIELD_KEY]: true },
646
+ });
647
+
648
+ const createCall: { miscDataProps: Record<string, unknown> } =
649
+ modelApiCreate.mock.calls[0]![0] as {
650
+ miscDataProps: Record<string, unknown>;
651
+ };
652
+ expect(createCall.miscDataProps).toEqual({});
653
+ });
654
+
655
+ test("accepts a probe selection that arrives as options rather than ids", async () => {
656
+ const props: CapturedTableProps = await renderDevicesPage();
657
+
658
+ await runCreate(props, {
659
+ miscDataProps: {
660
+ [CREATE_PING_MONITOR_FIELD_KEY]: true,
661
+ [PING_PROBES_FIELD_KEY]: [
662
+ { label: "Branch probe", value: "probe-1" },
663
+ ],
664
+ },
665
+ });
666
+
667
+ const createCall: { miscDataProps: Record<string, unknown> } =
668
+ modelApiCreate.mock.calls[0]![0] as {
669
+ miscDataProps: Record<string, unknown>;
670
+ };
671
+ expect(createCall.miscDataProps).toEqual({ probes: ["probe-1"] });
672
+ });
673
+
674
+ /*
675
+ * The box is off unless ticked, and an unticked box sends nothing at all
676
+ * (ModelForm drops a false override) — so an absent flag is the normal
677
+ * case, not an edge one, and it must cost the operator nothing.
678
+ */
679
+ test("does nothing when the box was not ticked", async () => {
680
+ const props: CapturedTableProps = await renderDevicesPage();
681
+
682
+ await runCreate(props, {
683
+ miscDataProps: {},
684
+ });
685
+
686
+ expect(modelApiCreate).not.toHaveBeenCalled();
687
+ expect(modelApiUpdateById).not.toHaveBeenCalled();
688
+ });
689
+
690
+ test("shows a success notice and refreshes the list", async () => {
691
+ const props: CapturedTableProps = await renderDevicesPage();
692
+ const toggleBefore: string | undefined = props.refreshToggle;
693
+
694
+ await runCreate(props, {
695
+ miscDataProps: { [CREATE_PING_MONITOR_FIELD_KEY]: true },
696
+ });
697
+
698
+ await waitFor(() => {
699
+ expect(
700
+ screen.getByTestId("network-device-ping-monitor-notice"),
701
+ ).toBeInTheDocument();
702
+ });
703
+
704
+ const notice: HTMLElement = screen.getByTestId(
705
+ "network-device-ping-monitor-notice",
706
+ );
707
+ expect(notice.textContent).toContain("Ping lobby-ap-01");
708
+ expect(notice.textContent?.toLowerCase()).not.toContain("verified");
709
+
710
+ await waitFor(() => {
711
+ expect(capturedTableProps?.refreshToggle).not.toBe(toggleBefore);
712
+ });
713
+ });
714
+
715
+ test("a monitor failure is shown on the page and the device stays created", async () => {
716
+ modelApiCreate.mockRejectedValue(
717
+ new Error("You have reached the monitor limit for your plan.") as never,
718
+ );
719
+
720
+ const props: CapturedTableProps = await renderDevicesPage();
721
+ const toggleBefore: string | undefined = props.refreshToggle;
722
+
723
+ const returned: NetworkDevice = await runCreate(props, {
724
+ miscDataProps: { [CREATE_PING_MONITOR_FIELD_KEY]: true },
725
+ });
726
+
727
+ // Resolved, not rejected: the table must not treat the create as failed.
728
+ expect(returned.id?.toString()).toBe(DEVICE_ID.toString());
729
+ expect(modelApiUpdateById).not.toHaveBeenCalled();
730
+
731
+ await waitFor(() => {
732
+ expect(
733
+ screen.getByTestId("network-device-ping-monitor-notice"),
734
+ ).toBeInTheDocument();
735
+ });
736
+
737
+ const notice: HTMLElement = screen.getByTestId(
738
+ "network-device-ping-monitor-notice",
739
+ );
740
+ expect(notice.textContent).toContain("lobby-ap-01 was created");
741
+ expect(notice.textContent).toContain("monitor limit");
742
+ /*
743
+ * What was lost is the ALERTING, and only that: the device exists and
744
+ * its probe polls it. A notice that implied the device had no status
745
+ * would send the operator to fix something that is not broken.
746
+ */
747
+ expect(notice.textContent).toContain("its probe polls it");
748
+ expect(notice.textContent).toContain("Create Ping Monitor");
749
+
750
+ await waitFor(() => {
751
+ expect(capturedTableProps?.refreshToggle).not.toBe(toggleBefore);
752
+ });
753
+ });
754
+
755
+ test("a bind failure removes the monitor again and says so", async () => {
756
+ modelApiUpdateById.mockRejectedValue(
757
+ new Error("Monitor not found.") as never,
758
+ );
759
+
760
+ const props: CapturedTableProps = await renderDevicesPage();
761
+
762
+ await runCreate(props, {
763
+ miscDataProps: { [CREATE_PING_MONITOR_FIELD_KEY]: true },
764
+ });
765
+
766
+ expect(modelApiDeleteItem).toHaveBeenCalledTimes(1);
767
+
768
+ await waitFor(() => {
769
+ expect(
770
+ screen.getByTestId("network-device-ping-monitor-notice"),
771
+ ).toBeInTheDocument();
772
+ });
773
+ expect(
774
+ screen.getByTestId("network-device-ping-monitor-notice").textContent,
775
+ ).toContain("removed again");
776
+ });
777
+
778
+ test("a request is consumed once, so a second create does not reuse it", async () => {
779
+ const props: CapturedTableProps = await renderDevicesPage();
780
+
781
+ await runCreate(props, {
782
+ miscDataProps: { [CREATE_PING_MONITOR_FIELD_KEY]: true },
783
+ });
784
+ expect(modelApiCreate).toHaveBeenCalledTimes(1);
785
+
786
+ // A second success with no onBeforeCreate in between must not provision.
787
+ await props.onCreateSuccess!(createdDevice());
788
+ expect(modelApiCreate).toHaveBeenCalledTimes(1);
789
+ });
790
+ });
791
+ });