@oneuptime/common 11.5.9 → 11.5.10

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 (376) hide show
  1. package/Models/AnalyticsModels/Index.ts +13 -0
  2. package/Models/AnalyticsModels/MetricItemAggMV1mByContainer.ts +178 -0
  3. package/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.ts +179 -0
  4. package/Models/AnalyticsModels/MetricItemAggMV1mByService.ts +179 -0
  5. package/Models/AnalyticsModels/NetworkFlow.ts +397 -0
  6. package/Models/DatabaseModels/EnterpriseLicenseInstance.ts +18 -0
  7. package/Models/DatabaseModels/GlobalConfig.ts +36 -0
  8. package/Models/DatabaseModels/Index.ts +2 -0
  9. package/Models/DatabaseModels/MarketingConversion.ts +198 -0
  10. package/Models/DatabaseModels/MetricSavedView.ts +34 -0
  11. package/Models/DatabaseModels/MetricType.ts +74 -0
  12. package/Models/DatabaseModels/NetworkDevice.ts +332 -0
  13. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +113 -0
  14. package/Models/DatabaseModels/NetworkInterface.ts +58 -0
  15. package/Models/DatabaseModels/Project.ts +37 -0
  16. package/Models/DatabaseModels/User.ts +37 -0
  17. package/Server/API/BaseAnalyticsAPI.ts +23 -0
  18. package/Server/API/EnterpriseLicenseAPI.ts +14 -0
  19. package/Server/EnvironmentConfig.ts +84 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.ts +38 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.ts +28 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.ts +108 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.ts +31 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.ts +29 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.ts +35 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
  27. package/Server/Services/AnalyticsDatabaseService.ts +70 -1
  28. package/Server/Services/IncidentService.ts +13 -0
  29. package/Server/Services/Index.ts +10 -0
  30. package/Server/Services/MarketingConversionService.ts +10 -0
  31. package/Server/Services/MetricItemAggMV1mByContainerService.ts +31 -0
  32. package/Server/Services/MetricItemAggMV1mByK8sClusterService.ts +31 -0
  33. package/Server/Services/MetricItemAggMV1mByServiceService.ts +31 -0
  34. package/Server/Services/MetricService.ts +970 -122
  35. package/Server/Services/MonitorService.ts +14 -0
  36. package/Server/Services/NetworkDeviceOwnerTeamService.ts +42 -0
  37. package/Server/Services/NetworkDeviceOwnerUserService.ts +106 -0
  38. package/Server/Services/NetworkFlowService.ts +11 -0
  39. package/Server/Services/OnCallDutyPolicyService.ts +11 -1
  40. package/Server/Services/ProjectService.ts +136 -0
  41. package/Server/Services/SpanService.ts +13 -9
  42. package/Server/Services/StatusPageService.ts +10 -0
  43. package/Server/Services/TeamMemberService.ts +11 -0
  44. package/Server/Services/UserService.ts +59 -0
  45. package/Server/Types/AnalyticsDatabase/AggregateBy.ts +37 -7
  46. package/Server/Utils/Attribution.ts +99 -0
  47. package/Server/Utils/Marketing/ConversionUploadProvider.ts +103 -0
  48. package/Server/Utils/Marketing/ConversionUploadProviders.ts +22 -0
  49. package/Server/Utils/Marketing/Providers/GoogleAds.ts +270 -0
  50. package/Server/Utils/Marketing/Providers/LinkedIn.ts +147 -0
  51. package/Server/Utils/Marketing/Providers/Meta.ts +148 -0
  52. package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +196 -0
  53. package/Server/Utils/Marketing/Providers/Reddit.ts +178 -0
  54. package/Server/Utils/Monitor/MonitorAlert.ts +71 -7
  55. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +31 -19
  56. package/Server/Utils/Monitor/MonitorIncident.ts +71 -7
  57. package/Server/Utils/Monitor/MonitorMetricUtil.ts +57 -0
  58. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +94 -0
  59. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +15 -0
  60. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +125 -14
  61. package/Server/Utils/ProductAnalytics.ts +133 -0
  62. package/Server/Utils/Telemetry/Telemetry.ts +39 -0
  63. package/Server/Utils/Telemetry/TelemetryEntity.ts +21 -0
  64. package/Tests/Server/API/BaseAnalyticsAPI.test.ts +72 -0
  65. package/Tests/Server/Infrastructure/SemaphorePermit.test.ts +9 -1
  66. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +21 -2
  67. package/Tests/Server/Services/MetricEntityMVKeyParity.test.ts +173 -0
  68. package/Tests/Server/Services/MetricServiceAggregate.test.ts +1391 -0
  69. package/Tests/Server/Services/NetworkDeviceOwnerServices.test.ts +260 -0
  70. package/Tests/Server/Utils/Monitor/MonitorTemplateUtilNetworkDevice.test.ts +389 -0
  71. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +764 -0
  72. package/Tests/Types/BaseDatabase/AggregationIntervalUtil.test.ts +111 -2
  73. package/Tests/Types/Database/EndsWith.test.ts +64 -0
  74. package/Tests/Types/Database/GreaterThan.test.ts +62 -0
  75. package/Tests/Types/Database/GreaterThanOrEqual.test.ts +65 -0
  76. package/Tests/Types/Database/GreaterThanOrNull.test.ts +63 -0
  77. package/Tests/Types/Database/Includes.test.ts +65 -0
  78. package/Tests/Types/Database/IncludesAll.test.ts +65 -0
  79. package/Tests/Types/Database/IncludesNone.test.ts +65 -0
  80. package/Tests/Types/Database/IsNull.test.ts +44 -0
  81. package/Tests/Types/Database/LessThan.test.ts +62 -0
  82. package/Tests/Types/Database/LessThanOrEqual.test.ts +62 -0
  83. package/Tests/Types/Database/LessThanOrNull.test.ts +62 -0
  84. package/Tests/Types/Database/MultiSearch.test.ts +81 -0
  85. package/Tests/Types/Database/NotContains.test.ts +64 -0
  86. package/Tests/Types/Database/NotNull.test.ts +44 -0
  87. package/Tests/Types/Database/StartsWith.test.ts +64 -0
  88. package/Tests/Types/Monitor/MonitorStepSqlMonitor.test.ts +83 -1
  89. package/Tests/Types/Monitor/SnmpV3EnumParsing.test.ts +247 -0
  90. package/Tests/Types/Monitor/SnmpVendorTemplate.test.ts +263 -0
  91. package/Tests/UI/Components/XAxis.test.ts +5 -3
  92. package/Tests/Utils/EnterpriseLicenseUsage.test.ts +76 -0
  93. package/Tests/Utils/Metrics/MetricExplorerUrl.test.ts +622 -0
  94. package/Tests/Utils/Metrics/MetricFormulaEvaluator.test.ts +474 -0
  95. package/Tests/Utils/Telemetry/HeartbeatAvailability.test.ts +52 -4
  96. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +11 -0
  97. package/Types/BaseDatabase/AggregateBy.ts +31 -2
  98. package/Types/BaseDatabase/AggregatedResult.ts +22 -0
  99. package/Types/BaseDatabase/AggregationInterval.ts +11 -0
  100. package/Types/BaseDatabase/AggregationIntervalUtil.ts +30 -5
  101. package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +16 -0
  102. package/Types/Email/EmailTemplateType.ts +3 -0
  103. package/Types/Marketing/MarketingConversion.ts +11 -0
  104. package/Types/Metrics/MetricQueryConfigData.ts +21 -0
  105. package/Types/Metrics/MetricQueryData.ts +8 -0
  106. package/Types/Metrics/MetricViewData.ts +8 -0
  107. package/Types/Monitor/MonitorMetricType.ts +8 -0
  108. package/Types/Monitor/MonitorStep.ts +9 -0
  109. package/Types/Monitor/MonitorStepSqlMonitor.ts +12 -0
  110. package/Types/Monitor/MonitorType.ts +2 -1
  111. package/Types/Monitor/SSLMonitor/SslMonitorResponse.ts +17 -12
  112. package/Types/Monitor/SnmpMonitor/CdpNeighbor.ts +13 -0
  113. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +37 -3
  114. package/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.ts +46 -0
  115. package/Types/Monitor/SnmpMonitor/SnmpEntityInfo.ts +15 -0
  116. package/Types/Monitor/SnmpMonitor/SnmpInterface.ts +8 -0
  117. package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +17 -8
  118. package/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.ts +53 -0
  119. package/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.ts +43 -0
  120. package/Types/Monitor/SnmpMonitor/SnmpSystemInfo.ts +16 -0
  121. package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +119 -3
  122. package/Types/NetFlow/NetworkFlowRecord.ts +25 -0
  123. package/Types/Syslog/SyslogMessage.ts +18 -0
  124. package/Types/Telemetry/TelemetrySavedViewState.ts +9 -0
  125. package/Types/Telemetry/TelemetrySavedViewType.ts +12 -0
  126. package/UI/Components/Charts/Area/AreaChart.tsx +51 -0
  127. package/UI/Components/Charts/Bar/BarChart.tsx +51 -1
  128. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +97 -26
  129. package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +328 -1
  130. package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +115 -0
  131. package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +328 -1
  132. package/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.ts +7 -0
  133. package/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.ts +15 -0
  134. package/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.ts +13 -0
  135. package/UI/Components/Charts/Line/LineChart.tsx +51 -0
  136. package/UI/Components/Charts/Types/ReferenceRegionProps.ts +12 -0
  137. package/UI/Components/Charts/Types/TimeReferenceLineProps.ts +12 -0
  138. package/UI/Components/Charts/Types/XAxis/XAxisPrecision.ts +1 -0
  139. package/UI/Components/Charts/Utils/DataPoint.ts +0 -0
  140. package/UI/Components/Charts/Utils/TimeAnnotation.ts +169 -0
  141. package/UI/Components/Charts/Utils/XAxis.ts +28 -4
  142. package/UI/Components/Icon/Icon.tsx +33 -13
  143. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +9 -0
  144. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +67 -0
  145. package/UI/Components/Page/ModelPage.tsx +6 -1
  146. package/UI/Components/TelemetryViewer/components/SavedViewsDropdown.tsx +33 -4
  147. package/UI/Styles/Theme.css +10 -0
  148. package/UI/Utils/User.ts +41 -2
  149. package/Utils/Analytics.ts +8 -6
  150. package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +74 -0
  151. package/Utils/Metrics/MetricExplorerUrl.ts +771 -0
  152. package/Utils/Metrics/MetricFormulaEvaluator.ts +410 -46
  153. package/Utils/Monitor/NetworkTopologyUtil.ts +261 -49
  154. package/Utils/ValueFormatter.ts +22 -1
  155. package/build/dist/Models/AnalyticsModels/Index.js +13 -0
  156. package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
  157. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByContainer.js +159 -0
  158. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByContainer.js.map +1 -0
  159. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js +158 -0
  160. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js.map +1 -0
  161. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js +160 -0
  162. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js.map +1 -0
  163. package/build/dist/Models/AnalyticsModels/NetworkFlow.js +351 -0
  164. package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -0
  165. package/build/dist/Models/DatabaseModels/EnterpriseLicenseInstance.js +19 -0
  166. package/build/dist/Models/DatabaseModels/EnterpriseLicenseInstance.js.map +1 -1
  167. package/build/dist/Models/DatabaseModels/GlobalConfig.js +38 -0
  168. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  169. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  170. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  171. package/build/dist/Models/DatabaseModels/MarketingConversion.js +219 -0
  172. package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -0
  173. package/build/dist/Models/DatabaseModels/MetricSavedView.js +35 -0
  174. package/build/dist/Models/DatabaseModels/MetricSavedView.js.map +1 -1
  175. package/build/dist/Models/DatabaseModels/MetricType.js +76 -0
  176. package/build/dist/Models/DatabaseModels/MetricType.js.map +1 -1
  177. package/build/dist/Models/DatabaseModels/NetworkDevice.js +341 -0
  178. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  179. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +116 -0
  180. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  181. package/build/dist/Models/DatabaseModels/NetworkInterface.js +60 -0
  182. package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -1
  183. package/build/dist/Models/DatabaseModels/Project.js +38 -0
  184. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  185. package/build/dist/Models/DatabaseModels/User.js +38 -0
  186. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  187. package/build/dist/Server/API/BaseAnalyticsAPI.js +19 -0
  188. package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
  189. package/build/dist/Server/API/EnterpriseLicenseAPI.js +8 -0
  190. package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
  191. package/build/dist/Server/EnvironmentConfig.js +51 -0
  192. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  193. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.js +27 -0
  194. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.js.map +1 -0
  195. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.js +21 -0
  196. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.js.map +1 -0
  197. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.js +47 -0
  198. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.js.map +1 -0
  199. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.js +16 -0
  200. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.js.map +1 -0
  201. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.js +18 -0
  202. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.js.map +1 -0
  203. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.js +20 -0
  204. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.js.map +1 -0
  205. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
  206. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  207. package/build/dist/Server/Services/AnalyticsDatabaseService.js +58 -4
  208. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  209. package/build/dist/Server/Services/IncidentService.js +12 -0
  210. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  211. package/build/dist/Server/Services/Index.js +10 -0
  212. package/build/dist/Server/Services/Index.js.map +1 -1
  213. package/build/dist/Server/Services/MarketingConversionService.js +9 -0
  214. package/build/dist/Server/Services/MarketingConversionService.js.map +1 -0
  215. package/build/dist/Server/Services/MetricItemAggMV1mByContainerService.js +29 -0
  216. package/build/dist/Server/Services/MetricItemAggMV1mByContainerService.js.map +1 -0
  217. package/build/dist/Server/Services/MetricItemAggMV1mByK8sClusterService.js +29 -0
  218. package/build/dist/Server/Services/MetricItemAggMV1mByK8sClusterService.js.map +1 -0
  219. package/build/dist/Server/Services/MetricItemAggMV1mByServiceService.js +29 -0
  220. package/build/dist/Server/Services/MetricItemAggMV1mByServiceService.js.map +1 -0
  221. package/build/dist/Server/Services/MetricService.js +761 -125
  222. package/build/dist/Server/Services/MetricService.js.map +1 -1
  223. package/build/dist/Server/Services/MonitorService.js +18 -5
  224. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  225. package/build/dist/Server/Services/NetworkDeviceOwnerTeamService.js +44 -0
  226. package/build/dist/Server/Services/NetworkDeviceOwnerTeamService.js.map +1 -1
  227. package/build/dist/Server/Services/NetworkDeviceOwnerUserService.js +88 -0
  228. package/build/dist/Server/Services/NetworkDeviceOwnerUserService.js.map +1 -1
  229. package/build/dist/Server/Services/NetworkFlowService.js +9 -0
  230. package/build/dist/Server/Services/NetworkFlowService.js.map +1 -0
  231. package/build/dist/Server/Services/OnCallDutyPolicyService.js +15 -6
  232. package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
  233. package/build/dist/Server/Services/ProjectService.js +107 -6
  234. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  235. package/build/dist/Server/Services/SpanService.js +8 -6
  236. package/build/dist/Server/Services/SpanService.js.map +1 -1
  237. package/build/dist/Server/Services/StatusPageService.js +10 -0
  238. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  239. package/build/dist/Server/Services/TeamMemberService.js +11 -0
  240. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  241. package/build/dist/Server/Services/UserService.js +52 -0
  242. package/build/dist/Server/Services/UserService.js.map +1 -1
  243. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +33 -7
  244. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
  245. package/build/dist/Server/Utils/Attribution.js +74 -0
  246. package/build/dist/Server/Utils/Attribution.js.map +1 -0
  247. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +40 -0
  248. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -0
  249. package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js +20 -0
  250. package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js.map +1 -0
  251. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +177 -0
  252. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -0
  253. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +113 -0
  254. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -0
  255. package/build/dist/Server/Utils/Marketing/Providers/Meta.js +109 -0
  256. package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -0
  257. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +130 -0
  258. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -0
  259. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +126 -0
  260. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -0
  261. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +53 -9
  262. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  263. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +21 -10
  264. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  265. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +54 -11
  266. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  267. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +43 -3
  268. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  269. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +68 -0
  270. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  271. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +15 -0
  272. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  273. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +100 -15
  274. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  275. package/build/dist/Server/Utils/ProductAnalytics.js +111 -0
  276. package/build/dist/Server/Utils/ProductAnalytics.js.map +1 -0
  277. package/build/dist/Server/Utils/Telemetry/Telemetry.js +32 -5
  278. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  279. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +17 -0
  280. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  281. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +11 -0
  282. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
  283. package/build/dist/Types/BaseDatabase/AggregationInterval.js +11 -0
  284. package/build/dist/Types/BaseDatabase/AggregationInterval.js.map +1 -1
  285. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js +33 -5
  286. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js.map +1 -1
  287. package/build/dist/Types/Email/EmailTemplateType.js +2 -0
  288. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  289. package/build/dist/Types/Marketing/MarketingConversion.js +13 -0
  290. package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -0
  291. package/build/dist/Types/Monitor/MonitorMetricType.js +7 -0
  292. package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
  293. package/build/dist/Types/Monitor/MonitorStep.js +6 -0
  294. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  295. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js +3 -0
  296. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -1
  297. package/build/dist/Types/Monitor/MonitorType.js +2 -1
  298. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  299. package/build/dist/Types/Monitor/SnmpMonitor/CdpNeighbor.js +2 -0
  300. package/build/dist/Types/Monitor/SnmpMonitor/CdpNeighbor.js.map +1 -0
  301. package/build/dist/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.js +41 -0
  302. package/build/dist/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.js.map +1 -1
  303. package/build/dist/Types/Monitor/SnmpMonitor/SnmpEntityInfo.js +2 -0
  304. package/build/dist/Types/Monitor/SnmpMonitor/SnmpEntityInfo.js.map +1 -0
  305. package/build/dist/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.js +48 -0
  306. package/build/dist/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.js.map +1 -1
  307. package/build/dist/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.js +38 -0
  308. package/build/dist/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.js.map +1 -1
  309. package/build/dist/Types/Monitor/SnmpMonitor/SnmpSystemInfo.js +2 -0
  310. package/build/dist/Types/Monitor/SnmpMonitor/SnmpSystemInfo.js.map +1 -0
  311. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +96 -3
  312. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -1
  313. package/build/dist/Types/NetFlow/NetworkFlowRecord.js +2 -0
  314. package/build/dist/Types/NetFlow/NetworkFlowRecord.js.map +1 -0
  315. package/build/dist/Types/Syslog/SyslogMessage.js +2 -0
  316. package/build/dist/Types/Syslog/SyslogMessage.js.map +1 -0
  317. package/build/dist/Types/Telemetry/TelemetrySavedViewState.js +0 -7
  318. package/build/dist/Types/Telemetry/TelemetrySavedViewState.js.map +1 -1
  319. package/build/dist/Types/Telemetry/TelemetrySavedViewType.js +13 -0
  320. package/build/dist/Types/Telemetry/TelemetrySavedViewType.js.map +1 -0
  321. package/build/dist/UI/Components/Charts/Area/AreaChart.js +25 -1
  322. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  323. package/build/dist/UI/Components/Charts/Bar/BarChart.js +26 -2
  324. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  325. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +36 -12
  326. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  327. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +208 -6
  328. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
  329. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +52 -3
  330. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
  331. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +208 -6
  332. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
  333. package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js +6 -1
  334. package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js.map +1 -1
  335. package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.js +2 -0
  336. package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.js.map +1 -0
  337. package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.js +2 -0
  338. package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.js.map +1 -0
  339. package/build/dist/UI/Components/Charts/Line/LineChart.js +25 -1
  340. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  341. package/build/dist/UI/Components/Charts/Types/ReferenceRegionProps.js +2 -0
  342. package/build/dist/UI/Components/Charts/Types/ReferenceRegionProps.js.map +1 -0
  343. package/build/dist/UI/Components/Charts/Types/TimeReferenceLineProps.js +2 -0
  344. package/build/dist/UI/Components/Charts/Types/TimeReferenceLineProps.js.map +1 -0
  345. package/build/dist/UI/Components/Charts/Types/XAxis/XAxisPrecision.js +1 -0
  346. package/build/dist/UI/Components/Charts/Types/XAxis/XAxisPrecision.js.map +1 -1
  347. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +0 -0
  348. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  349. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +121 -0
  350. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -0
  351. package/build/dist/UI/Components/Charts/Utils/XAxis.js +27 -4
  352. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  353. package/build/dist/UI/Components/Icon/Icon.js +15 -8
  354. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  355. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  356. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +58 -0
  357. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  358. package/build/dist/UI/Components/Page/ModelPage.js +7 -1
  359. package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
  360. package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js +10 -4
  361. package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js.map +1 -1
  362. package/build/dist/UI/Utils/User.js +35 -2
  363. package/build/dist/UI/Utils/User.js.map +1 -1
  364. package/build/dist/Utils/Analytics.js +8 -5
  365. package/build/dist/Utils/Analytics.js.map +1 -1
  366. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +57 -0
  367. package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
  368. package/build/dist/Utils/Metrics/MetricExplorerUrl.js +418 -0
  369. package/build/dist/Utils/Metrics/MetricExplorerUrl.js.map +1 -0
  370. package/build/dist/Utils/Metrics/MetricFormulaEvaluator.js +296 -37
  371. package/build/dist/Utils/Metrics/MetricFormulaEvaluator.js.map +1 -1
  372. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +176 -40
  373. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  374. package/build/dist/Utils/ValueFormatter.js +20 -1
  375. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  376. package/package.json +2 -2
@@ -0,0 +1,169 @@
1
+ import ChartReferenceRegionProps from "../Types/ReferenceRegionProps";
2
+ import ChartTimeReferenceLineProps from "../Types/TimeReferenceLineProps";
3
+ import FormattedReferenceRegion from "../ChartLibrary/Types/FormattedReferenceRegion";
4
+ import FormattedTimeReferenceLine from "../ChartLibrary/Types/FormattedTimeReferenceLine";
5
+ import { XAxis } from "../Types/XAxis/XAxis";
6
+ import XAxisUtil from "./XAxis";
7
+
8
+ interface AxisBuckets {
9
+ intervals: Array<Date>;
10
+ labels: Array<string>;
11
+ labelSet: Set<string>;
12
+ formatter: (value: Date) => string;
13
+ }
14
+
15
+ export default class TimeAnnotationUtil {
16
+ private static getAxisBuckets(xAxis: XAxis): AxisBuckets {
17
+ const intervals: Array<Date> = XAxisUtil.getPrecisionIntervals({
18
+ xAxisMin: xAxis.options.min,
19
+ xAxisMax: xAxis.options.max,
20
+ });
21
+ const formatter: (value: Date) => string = XAxisUtil.getFormatter({
22
+ xAxisMin: xAxis.options.min,
23
+ xAxisMax: xAxis.options.max,
24
+ });
25
+ const labels: Array<string> = intervals.map((interval: Date) => {
26
+ return formatter(interval);
27
+ });
28
+ return { intervals, labels, labelSet: new Set(labels), formatter };
29
+ }
30
+
31
+ /*
32
+ * End of the charted window: last bucket start plus one bucket width
33
+ * (buckets extend past their start date).
34
+ */
35
+ private static getWindowEndInMs(intervals: Array<Date>): number {
36
+ const lastInterval: Date | undefined = intervals[intervals.length - 1];
37
+ if (!lastInterval) {
38
+ return Number.NEGATIVE_INFINITY;
39
+ }
40
+ const secondToLastInterval: Date | undefined =
41
+ intervals[intervals.length - 2];
42
+ const bucketWidthInMs: number = secondToLastInterval
43
+ ? lastInterval.getTime() - secondToLastInterval.getTime()
44
+ : 0;
45
+ return lastInterval.getTime() + bucketWidthInMs;
46
+ }
47
+
48
+ /*
49
+ * Largest interval index whose bucket start is <= date, or null when
50
+ * the date falls before the first bucket.
51
+ */
52
+ private static getBucketIndexForDate(
53
+ intervals: Array<Date>,
54
+ date: Date,
55
+ ): number | null {
56
+ let bucketIndex: number | null = null;
57
+ for (let i: number = 0; i < intervals.length; i++) {
58
+ if (intervals[i]!.getTime() <= date.getTime()) {
59
+ bucketIndex = i;
60
+ } else {
61
+ break;
62
+ }
63
+ }
64
+ return bucketIndex;
65
+ }
66
+
67
+ /*
68
+ * Resolve a date to a bucket label that is guaranteed to exist on the
69
+ * categorical x-axis. Prefer formatter output — series datapoints are
70
+ * bucketed by the exact same formatter, so annotations land where data
71
+ * with the same timestamp lands. The formatter floors to wall-clock
72
+ * boundaries while buckets start at the raw window start, so its output
73
+ * can match no bucket; fall back to the bucket containing the date.
74
+ * Returns null when the date is outside the charted window.
75
+ */
76
+ private static resolveBucketLabel(data: {
77
+ date: Date;
78
+ buckets: AxisBuckets;
79
+ }): string | null {
80
+ const { intervals, labels, labelSet, formatter } = data.buckets;
81
+
82
+ const firstInterval: Date | undefined = intervals[0];
83
+ if (!firstInterval || data.date.getTime() < firstInterval.getTime()) {
84
+ return null;
85
+ }
86
+ if (data.date.getTime() > this.getWindowEndInMs(intervals)) {
87
+ return null;
88
+ }
89
+
90
+ const formatted: string = formatter(data.date);
91
+ if (labelSet.has(formatted)) {
92
+ return formatted;
93
+ }
94
+
95
+ const bucketIndex: number | null = this.getBucketIndexForDate(
96
+ intervals,
97
+ data.date,
98
+ );
99
+ if (bucketIndex === null) {
100
+ return null;
101
+ }
102
+ return labels[bucketIndex] ?? null;
103
+ }
104
+
105
+ public static formatTimeReferenceLines(data: {
106
+ timeReferenceLines: Array<ChartTimeReferenceLineProps>;
107
+ xAxis: XAxis;
108
+ }): Array<FormattedTimeReferenceLine> {
109
+ const buckets: AxisBuckets = this.getAxisBuckets(data.xAxis);
110
+
111
+ const formatted: Array<FormattedTimeReferenceLine> = [];
112
+ for (const timeReferenceLine of data.timeReferenceLines) {
113
+ const formattedX: string | null = this.resolveBucketLabel({
114
+ date: timeReferenceLine.date,
115
+ buckets,
116
+ });
117
+ if (formattedX === null) {
118
+ continue; // outside the charted window
119
+ }
120
+ formatted.push({ formattedX, original: timeReferenceLine });
121
+ }
122
+ return formatted;
123
+ }
124
+
125
+ public static formatReferenceRegions(data: {
126
+ referenceRegions: Array<ChartReferenceRegionProps>;
127
+ xAxis: XAxis;
128
+ }): Array<FormattedReferenceRegion> {
129
+ const buckets: AxisBuckets = this.getAxisBuckets(data.xAxis);
130
+ const firstInterval: Date | undefined = buckets.intervals[0];
131
+ const lastLabel: string | undefined =
132
+ buckets.labels[buckets.labels.length - 1];
133
+ if (!firstInterval || lastLabel === undefined) {
134
+ return [];
135
+ }
136
+ const windowEndInMs: number = this.getWindowEndInMs(buckets.intervals);
137
+
138
+ const formatted: Array<FormattedReferenceRegion> = [];
139
+ for (const referenceRegion of data.referenceRegions) {
140
+ const startInMs: number = Math.min(
141
+ referenceRegion.startDate.getTime(),
142
+ referenceRegion.endDate.getTime(),
143
+ );
144
+ const endInMs: number = Math.max(
145
+ referenceRegion.startDate.getTime(),
146
+ referenceRegion.endDate.getTime(),
147
+ );
148
+
149
+ // Entirely outside the charted window — nothing to draw.
150
+ if (endInMs < firstInterval.getTime() || startInMs > windowEndInMs) {
151
+ continue;
152
+ }
153
+
154
+ /*
155
+ * A region overlapping the window edge clamps to the nearest
156
+ * in-window bucket rather than vanishing.
157
+ */
158
+ const formattedX1: string =
159
+ this.resolveBucketLabel({ date: new Date(startInMs), buckets }) ||
160
+ buckets.labels[0]!;
161
+ const formattedX2: string =
162
+ this.resolveBucketLabel({ date: new Date(endInMs), buckets }) ||
163
+ lastLabel;
164
+
165
+ formatted.push({ formattedX1, formattedX2, original: referenceRegion });
166
+ }
167
+ return formatted;
168
+ }
169
+ }
@@ -32,10 +32,12 @@ export default class XAxisUtil {
32
32
  const totalMonths: number = totalDays / 30;
33
33
 
34
34
  /*
35
- * Mirror the server's aggregation interval (see
36
- * AggregateUtil.getAggregationInterval) so the chart renders one
37
- * point per backend bucket instead of re-bucketing them into
38
- * coarser groups. Previously a 1h range was rendered with EVERY_
35
+ * Mirror the server's aggregation interval ladder (see
36
+ * AggregationIntervalUtil.getAggregationIntervalForWindow: 3h
37
+ * Minute, 12h FiveMinutes, 24h FifteenMinutes, 3d
38
+ * ThirtyMinutes, 7d Hour, ...) so the chart renders one point
39
+ * per backend bucket instead of re-bucketing them into coarser
40
+ * groups. Previously a 1h range was rendered with EVERY_
39
41
  * FIVE_MINUTES (~12 points) even though the server returned 60
40
42
  * per-minute rows. Recharts thins the X-axis label set via
41
43
  * `interval="equidistantPreserveStart"`, so high point counts do
@@ -56,6 +58,15 @@ export default class XAxisUtil {
56
58
  if (totalHours <= 3) {
57
59
  return XAxisPrecision.EVERY_MINUTE;
58
60
  }
61
+ if (totalHours <= 12) {
62
+ return XAxisPrecision.EVERY_FIVE_MINUTES;
63
+ }
64
+ if (totalHours <= 24) {
65
+ return XAxisPrecision.EVERY_FIFTEEN_MINUTES;
66
+ }
67
+ if (totalDays <= 3) {
68
+ return XAxisPrecision.EVERY_THIRTY_MINUTES;
69
+ }
59
70
  if (totalDays <= 7) {
60
71
  return XAxisPrecision.EVERY_HOUR;
61
72
  }
@@ -116,6 +127,9 @@ export default class XAxisUtil {
116
127
  case XAxisPrecision.EVERY_TEN_MINUTES:
117
128
  currentDate.setMinutes(currentDate.getMinutes() + 10);
118
129
  break;
130
+ case XAxisPrecision.EVERY_FIFTEEN_MINUTES:
131
+ currentDate.setMinutes(currentDate.getMinutes() + 15);
132
+ break;
119
133
  case XAxisPrecision.EVERY_THIRTY_MINUTES:
120
134
  currentDate.setMinutes(currentDate.getMinutes() + 30);
121
135
  break;
@@ -239,6 +253,16 @@ export default class XAxisUtil {
239
253
  const roundedMinutes: number = Math.floor(minutes / 10) * 10;
240
254
  roundedValue.setMinutes(roundedMinutes, 0, 0);
241
255
 
256
+ return OneUptimeDate.getLocalTimeString(roundedValue);
257
+ };
258
+ case XAxisPrecision.EVERY_FIFTEEN_MINUTES:
259
+ // round down to nearest 15 minutes
260
+ return (value: Date) => {
261
+ const roundedValue: Date = this.cloneDate(value);
262
+ const minutes: number = roundedValue.getMinutes();
263
+ const roundedMinutes: number = Math.floor(minutes / 15) * 15;
264
+ roundedValue.setMinutes(roundedMinutes, 0, 0);
265
+
242
266
  return OneUptimeDate.getLocalTimeString(roundedValue);
243
267
  };
244
268
  case XAxisPrecision.EVERY_THIRTY_MINUTES:
@@ -2938,21 +2938,41 @@ const Icon: FunctionComponent<ComponentProps> = ({
2938
2938
  );
2939
2939
  } else if (icon === IconProp.Podman) {
2940
2940
  /*
2941
- * Podman mark — a clean side-profile silhouette of Podman's seal mascot:
2942
- * head raised with a visible eye, an arched back, and trailing tail
2943
- * flippers. The official emblem (a finely detailed seal inside a hexagonal
2944
- * frame) collapses into an illegible blob at small sizes, so this reads as
2945
- * a recognizable little sea creature down to ~16px and sits well beside the
2946
- * other resource brand logos (Docker / Proxmox / Ceph). The eye is punched
2947
- * out via the even-odd fill rule.
2941
+ * Podman mark — the seal mascot's face inside the octagon from Podman's
2942
+ * emblem. The official artwork (a mother seal flanked by two pups, with
2943
+ * whiskers and water lines, all inside the octagon) turns to mush below
2944
+ * ~48px, so this keeps only the cues that survive at icon sizes: the
2945
+ * octagonal frame, the brow arches, the eyes and the round muzzle. The
2946
+ * octagon doubles as the head outline so there is a single silhouette
2947
+ * rather than two nested rings, and its straight edges stay crisp down to
2948
+ * 16px next to the other resource brand logos (Docker / Proxmox / Ceph).
2948
2949
  */
2949
2950
  return getSvgWrapper(
2950
- <path
2951
- fill="currentColor"
2952
- stroke="none"
2953
- fillRule="evenodd"
2954
- d="M6.6 8.4C6.2 6.6 7.4 5 9.2 4.9c1.6-.1 2.9 1 3.5 2.2.7-.5 1.7-.7 2.5-.2.6.36.8 1.06.5 1.6 1.9 1.3 3.2 3.4 3.6 5.9.9-.15 1.9.15 2.3.95.35.75-.2 1.45-1.1 1.7-1.5.42-3.2-.15-4.1-1.5-.3.95-.9 1.75-1.7 2.25 1.2.5 2 1.2 1.6 2-.3.6-1.2.7-2.2.4-1.7-.5-3-1.9-3.4-3.6-.9.9-2.2 1.4-3.5 1.3-1-.1-1.5-.8-1.2-1.5.25-.6.9-.9 1.6-1-1-1.5-1.5-3.4-1.4-5.3-.6-.3-1.05-.85-1.1-1.55ZM8.4 8a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"
2955
- />,
2951
+ <>
2952
+ {/* Octagonal frame of the emblem, doubling as the seal's head */}
2953
+ <path
2954
+ strokeLinejoin="round"
2955
+ d="M15.79 2.85H8.21L2.85 8.21v7.58l5.36 5.36h7.58l5.36-5.36V8.21Z"
2956
+ />
2957
+ {/* Brow arches */}
2958
+ <path
2959
+ strokeWidth="1.2"
2960
+ strokeLinecap="round"
2961
+ d="M7.7 8.3C8.2 7.7 9.2 7.6 9.9 8M16.3 8.3C15.8 7.7 14.8 7.6 14.1 8"
2962
+ />
2963
+ {/* Eyes */}
2964
+ <circle cx="9.1" cy="10.7" r="1.25" fill="currentColor" stroke="none" />
2965
+ <circle
2966
+ cx="14.9"
2967
+ cy="10.7"
2968
+ r="1.25"
2969
+ fill="currentColor"
2970
+ stroke="none"
2971
+ />
2972
+ {/* Muzzle and nose */}
2973
+ <circle cx="12" cy="15.2" r="2.6" />
2974
+ <circle cx="12" cy="14.35" r="0.6" fill="currentColor" stroke="none" />
2975
+ </>,
2956
2976
  );
2957
2977
  } else if (icon === IconProp.Proxmox) {
2958
2978
  // Proxmox official logo mark (Simple Icons, CC0) — single filled path.
@@ -10,6 +10,15 @@ import React, {
10
10
  import ReactMarkdown from "react-markdown";
11
11
  // https://github.com/remarkjs/remark-gfm
12
12
  import remarkGfm from "remark-gfm";
13
+ /*
14
+ * @types/react-syntax-highlighter declares every deep subpath below as ambient
15
+ * `declare module` blocks inside its single index.d.ts, and that file only enters the
16
+ * program when something resolves the bare specifier. Nothing else does, so without
17
+ * this line the deep imports fall back to untyped .js and every one of them errors
18
+ * TS7016. `import type` is erased at emit, so the deep imports below still tree-shake;
19
+ * importing the barrel as a value would drag in highlight.js and the full language set.
20
+ */
21
+ import type {} from "react-syntax-highlighter";
13
22
  import SyntaxHighlighter from "react-syntax-highlighter/dist/esm/prism-light";
14
23
  import { vscDarkPlus } from "react-syntax-highlighter/dist/esm/styles/prism";
15
24
  import javascript from "react-syntax-highlighter/dist/esm/languages/prism/javascript";
@@ -369,6 +369,73 @@ export default class TemplateVariablesCatalog {
369
369
  description:
370
370
  "Array of {oid, name, value, type}. Each named OID is also exposed directly — e.g. a `.sysUpTime` OID resolves as `{{sysUpTime}}`.",
371
371
  },
372
+ {
373
+ key: "sysName",
374
+ description: "Device name from the SNMP system group.",
375
+ example: "core-switch-01",
376
+ },
377
+ {
378
+ key: "sysDescr",
379
+ description: "Device description from the SNMP system group.",
380
+ example: "Cisco IOS Software, C2960X ...",
381
+ },
382
+ {
383
+ key: "sysObjectId",
384
+ description:
385
+ "Vendor's registered enterprise OID — the device fingerprint.",
386
+ example: "1.3.6.1.4.1.9.1.716",
387
+ },
388
+ {
389
+ key: "sysLocation",
390
+ description: "Device location from the SNMP system group.",
391
+ example: "DC1 Rack 42",
392
+ },
393
+ {
394
+ key: "downInterfaces",
395
+ description:
396
+ "Array of {name, alias, interfaceIndex} for interfaces that are administratively up but operationally down. Requires interface monitoring. Use `{{downInterfaces.0.name}}` or a `{{#each downInterfaces}}` loop.",
397
+ example: '[{"name":"Gi0/1","alias":"uplink","interfaceIndex":1}]',
398
+ },
399
+ {
400
+ key: "interfacesTotal",
401
+ description:
402
+ "Total number of interfaces walked. Requires interface monitoring.",
403
+ example: "48",
404
+ },
405
+ {
406
+ key: "interfacesUp",
407
+ description:
408
+ "Number of interfaces that are administratively and operationally up.",
409
+ example: "46",
410
+ },
411
+ {
412
+ key: "interfacesDown",
413
+ description:
414
+ "Number of interfaces that are administratively up but operationally down.",
415
+ example: "2",
416
+ },
417
+ {
418
+ key: "interfaceWalkFailure",
419
+ description:
420
+ "Error message when the interface walk failed, empty otherwise.",
421
+ },
422
+ {
423
+ key: "trapOid",
424
+ description:
425
+ "Trap OID — only set when this check was triggered by an SNMP trap.",
426
+ example: "1.3.6.1.6.3.1.1.5.3",
427
+ },
428
+ {
429
+ key: "trapSourceIp",
430
+ description:
431
+ "Source IP address the trap was received from — only set on trap-triggered checks.",
432
+ example: "10.0.0.1",
433
+ },
434
+ {
435
+ key: "trapVarbinds",
436
+ description:
437
+ "Array of {oid, value} varbinds carried by the trap — only set on trap-triggered checks.",
438
+ },
372
439
  ],
373
440
  };
374
441
 
@@ -96,8 +96,13 @@ const ModelPage: <TBaseModel extends BaseModel>(
96
96
  } catch (err) {
97
97
  setLabels([]);
98
98
  setError(API.getFriendlyMessage(err));
99
+ } finally {
100
+ /*
101
+ * Must run even on the early "item not found" return above —
102
+ * otherwise the page shows its loader forever instead of the error.
103
+ */
104
+ setIsLoading(false);
99
105
  }
100
- setIsLoading(false);
101
106
  };
102
107
 
103
108
  const [title, setTitle] = useState<string | undefined>(props.title);
@@ -1,6 +1,8 @@
1
1
  import React, { FunctionComponent, ReactElement } from "react";
2
2
  import { SavedViewOption } from "../types";
3
3
  import useComponentOutsideClick from "../../../Types/UseComponentOutsideClick";
4
+ import Icon from "../../Icon/Icon";
5
+ import IconProp from "../../../../Types/Icon/IconProp";
4
6
 
5
7
  export interface SavedViewsDropdownProps {
6
8
  savedViews: Array<SavedViewOption>;
@@ -10,10 +12,13 @@ export interface SavedViewsDropdownProps {
10
12
  onEdit?: ((viewId: string) => void) | undefined;
11
13
  onDelete?: ((viewId: string) => void) | undefined;
12
14
  onUpdateCurrent?: (() => void) | undefined;
15
+ triggerClassName?: string | undefined;
16
+ showTriggerIcon?: boolean | undefined;
17
+ dropdownAlignment?: "left" | "right" | undefined;
13
18
  }
14
19
 
15
20
  const triggerButtonClassName: string =
16
- "inline-flex items-center gap-1.5 rounded-md border border-gray-200 bg-white px-2.5 py-1.5 text-xs font-medium text-gray-700 shadow-sm transition-colors hover:border-gray-300 hover:bg-gray-50";
21
+ "inline-flex items-center gap-1.5 rounded-md border border-gray-200 bg-white px-2.5 py-1.5 text-xs font-medium text-gray-700 shadow-sm transition-colors hover:border-gray-300 hover:bg-gray-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-400";
17
22
 
18
23
  const SavedViewsDropdown: FunctionComponent<SavedViewsDropdownProps> = (
19
24
  props: SavedViewsDropdownProps,
@@ -31,23 +36,47 @@ const SavedViewsDropdown: FunctionComponent<SavedViewsDropdownProps> = (
31
36
  <div className="relative" ref={ref}>
32
37
  <button
33
38
  type="button"
34
- className={triggerButtonClassName}
39
+ className={`${triggerButtonClassName} ${props.triggerClassName || ""}`}
35
40
  onClick={() => {
36
41
  setIsComponentVisible(!isComponentVisible);
37
42
  }}
38
43
  aria-haspopup="dialog"
39
44
  aria-expanded={isComponentVisible}
40
45
  >
46
+ {props.showTriggerIcon ? (
47
+ <Icon
48
+ icon={IconProp.Bookmark}
49
+ className="h-3.5 w-3.5 text-gray-500"
50
+ />
51
+ ) : null}
41
52
  <span className="max-w-40 truncate">
42
53
  {selectedView?.name || "Saved Views"}
43
54
  </span>
44
- <span className="text-xs text-gray-400">
55
+ <span
56
+ className={`text-xs text-gray-400 ${
57
+ props.showTriggerIcon
58
+ ? "rounded-md bg-gray-100 px-1.5 py-0.5 text-[10px] font-semibold"
59
+ : ""
60
+ }`}
61
+ >
45
62
  {props.savedViews.length.toLocaleString()}
46
63
  </span>
64
+ {props.showTriggerIcon ? (
65
+ <Icon
66
+ icon={IconProp.ChevronDown}
67
+ className={`h-3 w-3 text-gray-400 transition-transform ${
68
+ isComponentVisible ? "rotate-180" : ""
69
+ }`}
70
+ />
71
+ ) : null}
47
72
  </button>
48
73
 
49
74
  {isComponentVisible && (
50
- <div className="absolute left-0 z-20 mt-2 w-72 rounded-lg border border-gray-200 bg-white shadow-xl">
75
+ <div
76
+ className={`absolute z-20 mt-2 w-72 rounded-lg border border-gray-200 bg-white shadow-xl ${
77
+ props.dropdownAlignment === "right" ? "right-0" : "left-0"
78
+ }`}
79
+ >
51
80
  {/* View list */}
52
81
  <div className="max-h-72 overflow-y-auto py-1">
53
82
  {props.savedViews.length === 0 && (
@@ -688,6 +688,11 @@ html.dark :is(
688
688
  color: #fcd34d;
689
689
  }
690
690
 
691
+ /* Hint-chip icons (metric viewer) use the lighter amber accent. */
692
+ html.dark .text-amber-500 {
693
+ color: #fbbf24;
694
+ }
695
+
691
696
  html.dark :is(
692
697
  .text-yellow-600,
693
698
  .text-yellow-700,
@@ -870,6 +875,11 @@ html.dark :is(
870
875
  --tw-ring-color: rgb(129 140 248 / 35%);
871
876
  }
872
877
 
878
+ /* Formula-card variable badges (metric viewer). */
879
+ html.dark .border-violet-200 {
880
+ border-color: rgb(129 140 248 / 45%);
881
+ }
882
+
873
883
  html.dark :is(
874
884
  .border-yellow-100,
875
885
  .border-yellow-200,
package/UI/Utils/User.ts CHANGED
@@ -213,15 +213,54 @@ export default class UserUtil {
213
213
  const result: Dictionary<string> = {};
214
214
 
215
215
  for (const key in localStorageItems) {
216
- if (!localStorageItems[key]) {
216
+ const value: string = localStorageItems[key] as string;
217
+
218
+ /*
219
+ * Older versions of the marketing site stored the literal strings
220
+ * "null" / "undefined" for missing utm params. Filter those out so
221
+ * they never end up on the User record.
222
+ */
223
+ if (!value || value === "null" || value === "undefined") {
217
224
  continue;
218
225
  }
219
226
 
220
227
  if (key.startsWith("utm")) {
221
- result[key] = localStorageItems[key] as string;
228
+ result[key] = value;
222
229
  }
223
230
  }
224
231
 
225
232
  return result;
226
233
  }
234
+
235
+ // Ad platform click IDs (gclid, fbclid, etc.) stored by the marketing site.
236
+ public static getAttributionClickIds(): JSONObject | null {
237
+ return UserUtil.parseJsonLocalStorageItem("clickIds");
238
+ }
239
+
240
+ // First attributed touch (utm params, click IDs, landing URL) — never overwritten.
241
+ public static getFirstTouchAttribution(): JSONObject | null {
242
+ return UserUtil.parseJsonLocalStorageItem("firstTouch");
243
+ }
244
+
245
+ private static parseJsonLocalStorageItem(key: string): JSONObject | null {
246
+ /*
247
+ * LocalStorage.getItem JSON-parses stored strings when it can, so this
248
+ * may already be an object; fall back to parsing the raw string.
249
+ */
250
+ let value: JSONValue = LocalStorage.getItem(key);
251
+
252
+ if (typeof value === "string") {
253
+ try {
254
+ value = JSON.parse(value);
255
+ } catch {
256
+ return null;
257
+ }
258
+ }
259
+
260
+ if (value && typeof value === "object" && !Array.isArray(value)) {
261
+ return value as JSONObject;
262
+ }
263
+
264
+ return null;
265
+ }
227
266
  }
@@ -33,14 +33,16 @@ export default class Analytics {
33
33
  }
34
34
 
35
35
  public capture(eventName: string, data?: JSONObject): void {
36
- if (!this.isInitialized) {
37
- return;
38
- }
39
-
40
36
  // PostHog tracking
41
- posthog.capture(eventName, data);
37
+ if (this.isInitialized) {
38
+ posthog.capture(eventName, data);
39
+ }
42
40
 
43
- // GA4 tracking via dataLayer (for Google Analytics conversion tracking)
41
+ /*
42
+ * GA4 tracking via dataLayer (for Google Analytics / Google Ads conversion
43
+ * tracking). This must not depend on PostHog being configured — GTM is
44
+ * loaded independently of ANALYTICS_KEY / ANALYTICS_HOST.
45
+ */
44
46
  if (typeof window !== "undefined" && (window as any).dataLayer) {
45
47
  (window as any).dataLayer.push({
46
48
  event: eventName,
@@ -13,6 +13,33 @@ export interface EnterpriseLicenseInstanceUsage {
13
13
  }
14
14
 
15
15
  export default class EnterpriseLicenseUsageUtil {
16
+ /*
17
+ * How many days before a license expires that expiry reminder emails
18
+ * start going out, unless overridden in GlobalConfig
19
+ * (enterpriseLicenseExpiryReminderDays).
20
+ */
21
+ public static readonly defaultExpiryReminderDays: number = 45;
22
+
23
+ /*
24
+ * Expired licenses keep getting a daily "expired" email for this many
25
+ * days after expiry, then go quiet — an abandoned license should not be
26
+ * emailed forever.
27
+ */
28
+ public static readonly expiredNotificationCutoffDays: number = 30;
29
+
30
+ /*
31
+ * License keys are shown/emailed masked — enough to identify the key
32
+ * without exposing it in full.
33
+ */
34
+ public static maskLicenseKey(licenseKey: string): string {
35
+ if (licenseKey.length <= 8) {
36
+ return "••••••••";
37
+ }
38
+
39
+ return `${licenseKey.substring(0, 4)}••••${licenseKey.substring(
40
+ licenseKey.length - 4,
41
+ )}`;
42
+ }
16
43
  /*
17
44
  * Instances that stopped reporting (for example a decommissioned staging
18
45
  * environment) stop counting towards the seat total after this many days,
@@ -25,6 +52,53 @@ export default class EnterpriseLicenseUsageUtil {
25
52
 
26
53
  public static readonly maxEmailHashesPerInstance: number = 200_000;
27
54
 
55
+ /*
56
+ * Master admin emails are used to contact the customer about license
57
+ * issues — a handful per instance is plenty, and the cap keeps a
58
+ * misbehaving client from storing an unbounded list.
59
+ */
60
+ public static readonly maxMasterAdminEmailsPerInstance: number = 50;
61
+
62
+ // Deliberately loose: rejects garbage, accepts anything email-shaped.
63
+ private static readonly emailRegex: RegExp = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
64
+
65
+ /*
66
+ * Normalizes a client-provided list of master admin emails: keeps only
67
+ * email-shaped strings, lowercases them, removes duplicates and caps the
68
+ * list size. Returns an empty array for anything that is not an array.
69
+ */
70
+ public static sanitizeMasterAdminEmails(value: unknown): Array<string> {
71
+ if (!Array.isArray(value)) {
72
+ return [];
73
+ }
74
+
75
+ const emails: Set<string> = new Set<string>();
76
+
77
+ for (const item of value) {
78
+ if (emails.size >= this.maxMasterAdminEmailsPerInstance) {
79
+ break;
80
+ }
81
+
82
+ if (typeof item !== "string") {
83
+ continue;
84
+ }
85
+
86
+ const normalized: string = item.trim().toLowerCase();
87
+
88
+ if (
89
+ !normalized ||
90
+ normalized.length > 320 ||
91
+ !this.emailRegex.test(normalized)
92
+ ) {
93
+ continue;
94
+ }
95
+
96
+ emails.add(normalized);
97
+ }
98
+
99
+ return Array.from(emails);
100
+ }
101
+
28
102
  /*
29
103
  * Normalizes a client-provided list of email hashes: keeps only valid
30
104
  * SHA-256 hex strings, lowercases them, removes duplicates and caps the