@oneuptime/common 11.7.2 → 11.7.4

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 (414) hide show
  1. package/Models/AnalyticsModels/KubernetesCostAllocation.ts +103 -0
  2. package/Models/DatabaseModels/AlertEpisodeStateTimeline.ts +1 -0
  3. package/Models/DatabaseModels/AlertStateTimeline.ts +1 -0
  4. package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
  5. package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
  6. package/Models/DatabaseModels/Index.ts +5 -0
  7. package/Models/DatabaseModels/LogDropFilter.ts +89 -0
  8. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +13 -3
  9. package/Models/DatabaseModels/RecommendationDismissal.ts +463 -0
  10. package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
  11. package/Models/DatabaseModels/StatusPageGroup.ts +95 -0
  12. package/Models/DatabaseModels/TableView.ts +40 -0
  13. package/Models/DatabaseModels/TraceDropFilter.ts +89 -0
  14. package/Models/DatabaseModels/WorkflowVariable.ts +5 -1
  15. package/Server/API/AlertAPI.ts +32 -17
  16. package/Server/API/BaseAPI.ts +31 -2
  17. package/Server/API/BaseAnalyticsAPI.ts +36 -2
  18. package/Server/API/CommonAPI.ts +57 -0
  19. package/Server/API/IncidentAPI.ts +60 -33
  20. package/Server/API/IncidentEpisodeAPI.ts +31 -16
  21. package/Server/API/MonitorAPI.ts +30 -0
  22. package/Server/API/MonitorTemplateAPI.ts +8 -0
  23. package/Server/API/ProbeAPI.ts +196 -15
  24. package/Server/API/ProjectAPI.ts +79 -1
  25. package/Server/API/ScheduledMaintenanceAPI.ts +33 -18
  26. package/Server/API/StatusPageAPI.ts +74 -37
  27. package/Server/API/WorkspaceNotificationRuleAPI.ts +34 -4
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.ts +13 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.ts +527 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.ts +31 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.ts +55 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.ts +53 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  34. package/Server/Services/AlertEpisodeService.ts +47 -0
  35. package/Server/Services/AlertService.ts +125 -0
  36. package/Server/Services/BillingService.ts +98 -0
  37. package/Server/Services/DatabaseService.ts +184 -20
  38. package/Server/Services/IncidentEpisodeService.ts +47 -0
  39. package/Server/Services/IncidentService.ts +123 -0
  40. package/Server/Services/IncidentTemplateService.ts +123 -1
  41. package/Server/Services/Index.ts +2 -0
  42. package/Server/Services/LogDropFilterService.ts +133 -0
  43. package/Server/Services/MonitorProbeService.ts +94 -4
  44. package/Server/Services/MonitorService.ts +48 -43
  45. package/Server/Services/NetworkDeviceDiscoveryScanService.ts +70 -0
  46. package/Server/Services/ProbeService.ts +66 -0
  47. package/Server/Services/ProjectService.ts +131 -7
  48. package/Server/Services/RecommendationDismissalService.ts +52 -0
  49. package/Server/Services/RunbookAgentJobService.ts +68 -7
  50. package/Server/Services/ScheduledMaintenanceService.ts +103 -0
  51. package/Server/Services/ScheduledMaintenanceTemplateService.ts +90 -0
  52. package/Server/Services/StatusPageGroupService.ts +186 -0
  53. package/Server/Services/TraceDropFilterService.ts +133 -0
  54. package/Server/Types/Workflow/Components/API/Delete.ts +12 -0
  55. package/Server/Types/Workflow/Components/API/Get.ts +12 -0
  56. package/Server/Types/Workflow/Components/API/Patch.ts +12 -0
  57. package/Server/Types/Workflow/Components/API/Post.ts +12 -0
  58. package/Server/Types/Workflow/Components/API/Put.ts +13 -0
  59. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +212 -0
  60. package/Server/Utils/DropFilterValidation.ts +127 -0
  61. package/Server/Utils/Errors.ts +5 -0
  62. package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
  63. package/Server/Utils/Monitor/MonitorIncident.ts +31 -2
  64. package/Server/Utils/Telemetry/AppMetrics.ts +31 -0
  65. package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +16 -0
  66. package/Tests/Models/DatabaseModels/MonitorProbeColumnAccessControl.test.ts +196 -0
  67. package/Tests/Models/RecommendationDismissalModel.test.ts +269 -0
  68. package/Tests/Server/API/BaseAPIUpdatePayloadValidation.test.ts +320 -0
  69. package/Tests/Server/API/BaseAnalyticsAPIUpdatePayloadValidation.test.ts +293 -0
  70. package/Tests/Server/API/CommonAPIAuthGuard.test.ts +164 -0
  71. package/Tests/Server/API/ProbeAPI.test.ts +422 -53
  72. package/Tests/Server/API/ProjectAPI.test.ts +180 -0
  73. package/Tests/Server/API/ProjectAPIExtendTrialBillingDisabled.test.ts +138 -0
  74. package/Tests/Server/API/ProjectScopedCustomRouteAuth.test.ts +458 -0
  75. package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +359 -0
  76. package/Tests/Server/Infrastructure/ProcessSignalDelivery.test.ts +427 -0
  77. package/Tests/Server/Services/BillingServiceExtendTrial.test.ts +439 -0
  78. package/Tests/Server/Services/CrossProjectReferenceWriteGuard.test.ts +810 -0
  79. package/Tests/Server/Services/DatabaseServiceAtomicAddToColumns.test.ts +269 -0
  80. package/Tests/Server/Services/DatabaseServiceEmptyUpdate.test.ts +277 -0
  81. package/Tests/Server/Services/DatabaseServiceSortColumnSelect.test.ts +201 -0
  82. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +81 -23
  83. package/Tests/Server/Services/DropFilterSaveValidation.test.ts +398 -0
  84. package/Tests/Server/Services/MonitorProbeDeleteHooks.test.ts +280 -0
  85. package/Tests/Server/Services/MonitorProbeServiceProbeTenancy.test.ts +304 -0
  86. package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +262 -0
  87. package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +614 -0
  88. package/Tests/Server/Services/RecommendationDismissalService.test.ts +306 -0
  89. package/Tests/Server/Services/RepairCrossProjectIncidentReferencesMigration.test.ts +528 -0
  90. package/Tests/Server/Services/StatusPageGroupNesting.test.ts +395 -0
  91. package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +26 -21
  92. package/Tests/Server/Types/Database/Permissions/WorkflowVariableColumnPermission.test.ts +227 -0
  93. package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +285 -0
  94. package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +463 -0
  95. package/Tests/Server/Utils/DropFilterValidation.test.ts +269 -0
  96. package/Tests/Server/Utils/Telemetry/SpanUtil.test.ts +94 -0
  97. package/Tests/Types/DateUserTimezone.test.ts +52 -0
  98. package/Tests/Types/JSONFunctions.test.ts +103 -1
  99. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +177 -9
  100. package/Tests/Types/Monitor/MonitorStepDnsMonitor.test.ts +105 -0
  101. package/Tests/Types/Monitor/MonitorStepDnssecMonitor.test.ts +131 -0
  102. package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +60 -0
  103. package/Tests/Types/Monitor/MonitorStepExternalStatusPageMonitor.test.ts +82 -0
  104. package/Tests/Types/Monitor/MonitorStepInfrastructureMonitors.test.ts +268 -0
  105. package/Tests/Types/Monitor/MonitorStepMetricMonitor.test.ts +386 -0
  106. package/Tests/Types/Monitor/MonitorStepProfileMonitor.test.ts +185 -0
  107. package/Tests/Types/Monitor/MonitorStepSnmpMonitor.test.ts +156 -0
  108. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +371 -0
  109. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +901 -0
  110. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +607 -0
  111. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +754 -0
  112. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +960 -0
  113. package/Tests/Types/RollingTime/RollingTimeUtil.test.ts +186 -0
  114. package/Tests/Types/Runbook/RunbookStepTimeout.test.ts +410 -0
  115. package/Tests/Types/Telemetry/DropFilterSampling.test.ts +241 -0
  116. package/Tests/Types/Workspace/NotificationRuleConditionUtil.test.ts +353 -0
  117. package/Tests/Types/Workspace/NotificationRuleUtil.test.ts +566 -0
  118. package/Tests/UI/Components/CodeEditor.test.tsx +174 -0
  119. package/Tests/UI/Components/ErrorBoundary.test.tsx +555 -24
  120. package/Tests/UI/Components/InfoCard.test.tsx +358 -0
  121. package/Tests/UI/Components/LogTimeRangePicker.test.tsx +138 -0
  122. package/Tests/UI/Components/Modal.test.tsx +43 -5
  123. package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +679 -0
  124. package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +397 -0
  125. package/Tests/UI/Components/ModelTable/ColumnCustomizationModal.test.tsx +999 -0
  126. package/Tests/UI/Components/ModelTable/ColumnPreference.test.ts +1678 -0
  127. package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1094 -0
  128. package/Tests/UI/Components/Runbook/StepTimeoutInput.test.tsx +386 -0
  129. package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +671 -0
  130. package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +404 -0
  131. package/Tests/UI/Utils/DropdownAlignment.test.ts +306 -0
  132. package/Tests/UI/Utils/TableFilterUrlState.test.ts +292 -0
  133. package/Tests/Utils/Monitor/MonitorSummaryProbeUtil.test.ts +263 -0
  134. package/Tests/Utils/NetworkDiscovery/ScanTargetUtil.test.ts +583 -0
  135. package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +1072 -0
  136. package/Tests/Utils/StatusPage/GroupTree.test.ts +583 -0
  137. package/Tests/Utils/StatusPage/ResourceUptime.test.ts +411 -0
  138. package/Tests/Utils/UserPreferences.test.ts +563 -0
  139. package/Types/Date.ts +15 -6
  140. package/Types/JSONFunctions.ts +7 -2
  141. package/Types/Kubernetes/KubernetesCostIngest.ts +37 -1
  142. package/Types/Monitor/KubernetesAlertTemplates.ts +205 -0
  143. package/Types/Monitor/MonitorStep.ts +10 -1
  144. package/Types/Monitor/MonitorStepMetricMonitor.ts +46 -1
  145. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +413 -0
  146. package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +168 -0
  147. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +175 -0
  148. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +743 -0
  149. package/Types/Permission.ts +45 -0
  150. package/Types/Recommendation/RecommendationType.ts +20 -0
  151. package/Types/Runbook/RunbookExecutionDeadline.ts +129 -0
  152. package/Types/Runbook/RunbookStepTimeout.ts +202 -0
  153. package/Types/Telemetry/DropFilterSampling.ts +92 -0
  154. package/UI/Components/AI/GenerateFromAIModal.tsx +0 -2
  155. package/UI/Components/Accordion/Accordion.tsx +10 -2
  156. package/UI/Components/BulkUpdate/BulkLabelActions.tsx +0 -1
  157. package/UI/Components/CodeEditor/CodeEditor.tsx +34 -20
  158. package/UI/Components/Date/RangeStartAndEndDateView.tsx +0 -1
  159. package/UI/Components/EditionLabel/EditionLabel.tsx +1 -27
  160. package/UI/Components/Error/PageError.tsx +0 -4
  161. package/UI/Components/ErrorBoundary.tsx +252 -15
  162. package/UI/Components/InfoCard/InfoCard.tsx +58 -1
  163. package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +34 -1
  164. package/UI/Components/MasterPage/MasterPage.tsx +65 -0
  165. package/UI/Components/Modal/Modal.tsx +16 -60
  166. package/UI/Components/ModelFormModal/ModelFormModal.tsx +0 -8
  167. package/UI/Components/ModelTable/BaseModelTable.tsx +503 -71
  168. package/UI/Components/ModelTable/Column.ts +17 -0
  169. package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +523 -0
  170. package/UI/Components/ModelTable/ColumnPreference.ts +482 -0
  171. package/UI/Components/ModelTable/CustomFieldColumns.tsx +326 -0
  172. package/UI/Components/ModelTable/TableView.tsx +24 -2
  173. package/UI/Components/ModelTable/useCustomFieldColumns.ts +150 -0
  174. package/UI/Components/Runbook/StepTimeoutInput.tsx +173 -0
  175. package/UI/Components/SideMenu/SideMenu.tsx +24 -4
  176. package/UI/Components/StatusPage/ResourceGroupSection.tsx +231 -0
  177. package/UI/Components/Table/Table.tsx +14 -1
  178. package/UI/Components/Table/TableRow.tsx +180 -175
  179. package/UI/Components/Table/Types/Column.ts +2 -0
  180. package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +34 -1
  181. package/UI/Utils/DropdownAlignment.ts +162 -0
  182. package/UI/Utils/TableFilterUrlState.ts +59 -20
  183. package/Utils/API.ts +106 -2
  184. package/Utils/Monitor/MonitorSummaryProbeUtil.ts +130 -0
  185. package/Utils/NetworkDiscovery/ScanTargetUtil.ts +434 -0
  186. package/Utils/StatusPage/GroupNestingLayout.ts +343 -0
  187. package/Utils/StatusPage/GroupTree.ts +307 -0
  188. package/Utils/StatusPage/ResourceUptime.ts +90 -17
  189. package/Utils/UserPreferences.ts +53 -0
  190. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +86 -0
  191. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -1
  192. package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js +1 -0
  193. package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js.map +1 -1
  194. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +1 -0
  195. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -1
  196. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
  197. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
  198. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
  199. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  200. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  201. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  202. package/build/dist/Models/DatabaseModels/LogDropFilter.js +91 -0
  203. package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
  204. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +14 -4
  205. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  206. package/build/dist/Models/DatabaseModels/RecommendationDismissal.js +484 -0
  207. package/build/dist/Models/DatabaseModels/RecommendationDismissal.js.map +1 -0
  208. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
  209. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
  210. package/build/dist/Models/DatabaseModels/StatusPageGroup.js +94 -0
  211. package/build/dist/Models/DatabaseModels/StatusPageGroup.js.map +1 -1
  212. package/build/dist/Models/DatabaseModels/TableView.js +40 -0
  213. package/build/dist/Models/DatabaseModels/TableView.js.map +1 -1
  214. package/build/dist/Models/DatabaseModels/TraceDropFilter.js +91 -0
  215. package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
  216. package/build/dist/Models/DatabaseModels/WorkflowVariable.js +5 -1
  217. package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
  218. package/build/dist/Server/API/AlertAPI.js +22 -13
  219. package/build/dist/Server/API/AlertAPI.js.map +1 -1
  220. package/build/dist/Server/API/BaseAPI.js +22 -1
  221. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  222. package/build/dist/Server/API/BaseAnalyticsAPI.js +24 -1
  223. package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
  224. package/build/dist/Server/API/CommonAPI.js +42 -0
  225. package/build/dist/Server/API/CommonAPI.js.map +1 -1
  226. package/build/dist/Server/API/IncidentAPI.js +43 -26
  227. package/build/dist/Server/API/IncidentAPI.js.map +1 -1
  228. package/build/dist/Server/API/IncidentEpisodeAPI.js +21 -12
  229. package/build/dist/Server/API/IncidentEpisodeAPI.js.map +1 -1
  230. package/build/dist/Server/API/MonitorAPI.js +23 -0
  231. package/build/dist/Server/API/MonitorAPI.js.map +1 -1
  232. package/build/dist/Server/API/MonitorTemplateAPI.js +4 -0
  233. package/build/dist/Server/API/MonitorTemplateAPI.js.map +1 -1
  234. package/build/dist/Server/API/ProbeAPI.js +131 -15
  235. package/build/dist/Server/API/ProbeAPI.js.map +1 -1
  236. package/build/dist/Server/API/ProjectAPI.js +62 -3
  237. package/build/dist/Server/API/ProjectAPI.js.map +1 -1
  238. package/build/dist/Server/API/ScheduledMaintenanceAPI.js +23 -14
  239. package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -1
  240. package/build/dist/Server/API/StatusPageAPI.js +61 -33
  241. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  242. package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js +26 -2
  243. package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js.map +1 -1
  244. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js +12 -0
  245. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js.map +1 -0
  246. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js +397 -0
  247. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js.map +1 -0
  248. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js +16 -0
  249. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js.map +1 -0
  250. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js +30 -0
  251. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js.map +1 -0
  252. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.js +34 -0
  253. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.js.map +1 -0
  254. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  255. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  256. package/build/dist/Server/Services/AlertEpisodeService.js +39 -0
  257. package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
  258. package/build/dist/Server/Services/AlertService.js +95 -0
  259. package/build/dist/Server/Services/AlertService.js.map +1 -1
  260. package/build/dist/Server/Services/BillingService.js +71 -0
  261. package/build/dist/Server/Services/BillingService.js.map +1 -1
  262. package/build/dist/Server/Services/DatabaseService.js +140 -17
  263. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  264. package/build/dist/Server/Services/IncidentEpisodeService.js +39 -0
  265. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  266. package/build/dist/Server/Services/IncidentService.js +100 -0
  267. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  268. package/build/dist/Server/Services/IncidentTemplateService.js +97 -0
  269. package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
  270. package/build/dist/Server/Services/Index.js +2 -0
  271. package/build/dist/Server/Services/Index.js.map +1 -1
  272. package/build/dist/Server/Services/LogDropFilterService.js +93 -0
  273. package/build/dist/Server/Services/LogDropFilterService.js.map +1 -1
  274. package/build/dist/Server/Services/MonitorProbeService.js +73 -5
  275. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  276. package/build/dist/Server/Services/MonitorService.js +34 -39
  277. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  278. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +71 -0
  279. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
  280. package/build/dist/Server/Services/ProbeService.js +64 -0
  281. package/build/dist/Server/Services/ProbeService.js.map +1 -1
  282. package/build/dist/Server/Services/ProjectService.js +103 -7
  283. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  284. package/build/dist/Server/Services/RecommendationDismissalService.js +50 -0
  285. package/build/dist/Server/Services/RecommendationDismissalService.js.map +1 -0
  286. package/build/dist/Server/Services/RunbookAgentJobService.js +63 -5
  287. package/build/dist/Server/Services/RunbookAgentJobService.js.map +1 -1
  288. package/build/dist/Server/Services/ScheduledMaintenanceService.js +83 -0
  289. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  290. package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js +65 -0
  291. package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js.map +1 -1
  292. package/build/dist/Server/Services/StatusPageGroupService.js +136 -0
  293. package/build/dist/Server/Services/StatusPageGroupService.js.map +1 -1
  294. package/build/dist/Server/Services/TraceDropFilterService.js +93 -0
  295. package/build/dist/Server/Services/TraceDropFilterService.js.map +1 -1
  296. package/build/dist/Server/Types/Workflow/Components/API/Delete.js +11 -0
  297. package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
  298. package/build/dist/Server/Types/Workflow/Components/API/Get.js +11 -0
  299. package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
  300. package/build/dist/Server/Types/Workflow/Components/API/Patch.js +11 -0
  301. package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
  302. package/build/dist/Server/Types/Workflow/Components/API/Post.js +11 -0
  303. package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
  304. package/build/dist/Server/Types/Workflow/Components/API/Put.js +12 -0
  305. package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
  306. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +132 -0
  307. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -0
  308. package/build/dist/Server/Utils/DropFilterValidation.js +80 -0
  309. package/build/dist/Server/Utils/DropFilterValidation.js.map +1 -0
  310. package/build/dist/Server/Utils/Errors.js +3 -0
  311. package/build/dist/Server/Utils/Errors.js.map +1 -1
  312. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +30 -12
  313. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  314. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +38 -18
  315. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  316. package/build/dist/Server/Utils/Telemetry/AppMetrics.js +26 -0
  317. package/build/dist/Server/Utils/Telemetry/AppMetrics.js.map +1 -1
  318. package/build/dist/Types/Date.js +14 -4
  319. package/build/dist/Types/Date.js.map +1 -1
  320. package/build/dist/Types/JSONFunctions.js +8 -3
  321. package/build/dist/Types/JSONFunctions.js.map +1 -1
  322. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -1
  323. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +192 -0
  324. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  325. package/build/dist/Types/Monitor/MonitorStep.js +6 -1
  326. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  327. package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js +32 -1
  328. package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js.map +1 -1
  329. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +294 -0
  330. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -0
  331. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +110 -0
  332. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -0
  333. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +58 -0
  334. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -0
  335. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +451 -0
  336. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -0
  337. package/build/dist/Types/Permission.js +40 -0
  338. package/build/dist/Types/Permission.js.map +1 -1
  339. package/build/dist/Types/Recommendation/RecommendationType.js +21 -0
  340. package/build/dist/Types/Recommendation/RecommendationType.js.map +1 -0
  341. package/build/dist/Types/Runbook/RunbookExecutionDeadline.js +93 -0
  342. package/build/dist/Types/Runbook/RunbookExecutionDeadline.js.map +1 -0
  343. package/build/dist/Types/Runbook/RunbookStepTimeout.js +142 -0
  344. package/build/dist/Types/Runbook/RunbookStepTimeout.js.map +1 -0
  345. package/build/dist/Types/Telemetry/DropFilterSampling.js +75 -0
  346. package/build/dist/Types/Telemetry/DropFilterSampling.js.map +1 -0
  347. package/build/dist/UI/Components/AI/GenerateFromAIModal.js +1 -2
  348. package/build/dist/UI/Components/AI/GenerateFromAIModal.js.map +1 -1
  349. package/build/dist/UI/Components/Accordion/Accordion.js +9 -2
  350. package/build/dist/UI/Components/Accordion/Accordion.js.map +1 -1
  351. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js +1 -1
  352. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js.map +1 -1
  353. package/build/dist/UI/Components/CodeEditor/CodeEditor.js +27 -14
  354. package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
  355. package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js +1 -1
  356. package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js.map +1 -1
  357. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +2 -20
  358. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  359. package/build/dist/UI/Components/Error/PageError.js +1 -3
  360. package/build/dist/UI/Components/Error/PageError.js.map +1 -1
  361. package/build/dist/UI/Components/ErrorBoundary.js +145 -11
  362. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  363. package/build/dist/UI/Components/InfoCard/InfoCard.js +28 -1
  364. package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
  365. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +13 -2
  366. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
  367. package/build/dist/UI/Components/MasterPage/MasterPage.js +50 -1
  368. package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
  369. package/build/dist/UI/Components/Modal/Modal.js +4 -32
  370. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  371. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
  372. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +308 -40
  373. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  374. package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +230 -0
  375. package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -0
  376. package/build/dist/UI/Components/ModelTable/ColumnPreference.js +258 -0
  377. package/build/dist/UI/Components/ModelTable/ColumnPreference.js.map +1 -0
  378. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +168 -0
  379. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -0
  380. package/build/dist/UI/Components/ModelTable/TableView.js +13 -2
  381. package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
  382. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +84 -0
  383. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -0
  384. package/build/dist/UI/Components/Runbook/StepTimeoutInput.js +101 -0
  385. package/build/dist/UI/Components/Runbook/StepTimeoutInput.js.map +1 -0
  386. package/build/dist/UI/Components/SideMenu/SideMenu.js +15 -5
  387. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  388. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +73 -0
  389. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -0
  390. package/build/dist/UI/Components/Table/Table.js +15 -2
  391. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  392. package/build/dist/UI/Components/Table/TableRow.js +11 -6
  393. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  394. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +13 -2
  395. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
  396. package/build/dist/UI/Utils/DropdownAlignment.js +98 -0
  397. package/build/dist/UI/Utils/DropdownAlignment.js.map +1 -0
  398. package/build/dist/UI/Utils/TableFilterUrlState.js +48 -15
  399. package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
  400. package/build/dist/Utils/API.js +39 -2
  401. package/build/dist/Utils/API.js.map +1 -1
  402. package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js +97 -0
  403. package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js.map +1 -0
  404. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +330 -0
  405. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -0
  406. package/build/dist/Utils/StatusPage/GroupNestingLayout.js +280 -0
  407. package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -0
  408. package/build/dist/Utils/StatusPage/GroupTree.js +214 -0
  409. package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -0
  410. package/build/dist/Utils/StatusPage/ResourceUptime.js +60 -16
  411. package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
  412. package/build/dist/Utils/UserPreferences.js +33 -0
  413. package/build/dist/Utils/UserPreferences.js.map +1 -1
  414. package/package.json +1 -1
@@ -1199,6 +1199,11 @@ enum Permission {
1199
1199
  EditNetworkSiteType = "EditNetworkSiteType",
1200
1200
  ReadNetworkSiteType = "ReadNetworkSiteType",
1201
1201
 
1202
+ CreateRecommendationDismissal = "CreateRecommendationDismissal",
1203
+ DeleteRecommendationDismissal = "DeleteRecommendationDismissal",
1204
+ EditRecommendationDismissal = "EditRecommendationDismissal",
1205
+ ReadRecommendationDismissal = "ReadRecommendationDismissal",
1206
+
1202
1207
  CreateNetworkEndpoint = "CreateNetworkEndpoint",
1203
1208
  DeleteNetworkEndpoint = "DeleteNetworkEndpoint",
1204
1209
  EditNetworkEndpoint = "EditNetworkEndpoint",
@@ -7704,6 +7709,46 @@ export class PermissionHelper {
7704
7709
  isRolePermission: false,
7705
7710
  group: PermissionGroup.Monitor,
7706
7711
  },
7712
+ {
7713
+ permission: Permission.CreateRecommendationDismissal,
7714
+ title: "Create Recommendation Dismissal",
7715
+ description:
7716
+ "This permission can dismiss recommendations in this project.",
7717
+ isAssignableToTenant: true,
7718
+ isAccessControlPermission: false,
7719
+ isRolePermission: false,
7720
+ group: PermissionGroup.Monitor,
7721
+ },
7722
+ {
7723
+ permission: Permission.DeleteRecommendationDismissal,
7724
+ title: "Delete Recommendation Dismissal",
7725
+ description:
7726
+ "This permission can restore dismissed recommendations of this project.",
7727
+ isAssignableToTenant: true,
7728
+ isAccessControlPermission: true,
7729
+ isRolePermission: false,
7730
+ group: PermissionGroup.Monitor,
7731
+ },
7732
+ {
7733
+ permission: Permission.EditRecommendationDismissal,
7734
+ title: "Edit Recommendation Dismissal",
7735
+ description:
7736
+ "This permission can edit dismissed recommendations of this project.",
7737
+ isAssignableToTenant: true,
7738
+ isAccessControlPermission: true,
7739
+ isRolePermission: false,
7740
+ group: PermissionGroup.Monitor,
7741
+ },
7742
+ {
7743
+ permission: Permission.ReadRecommendationDismissal,
7744
+ title: "Read Recommendation Dismissal",
7745
+ description:
7746
+ "This permission can read dismissed recommendations of this project.",
7747
+ isAssignableToTenant: true,
7748
+ isAccessControlPermission: true,
7749
+ isRolePermission: false,
7750
+ group: PermissionGroup.Monitor,
7751
+ },
7707
7752
  {
7708
7753
  permission: Permission.CreateNetworkEndpoint,
7709
7754
  title: "Create Network Endpoint",
@@ -0,0 +1,20 @@
1
+ /*
2
+ * The kinds of recommendation OneUptime can surface.
3
+ *
4
+ * Recommendations are suggestions OneUptime derives from telemetry it already
5
+ * has — "you have a Kubernetes cluster reporting HPA metrics but nothing
6
+ * watching whether an HPA is pinned at max replicas". Today the only kind is
7
+ * `Monitor` (create this monitor), but the surrounding machinery — the
8
+ * dismissal table, the side-menu count, the page shell — is deliberately keyed
9
+ * on this enum rather than on monitors, so a second kind (dashboards, cost
10
+ * savings, retention policies) needs no schema change and no new page.
11
+ *
12
+ * The values ARE persisted, in `RecommendationDismissal.recommendationType`.
13
+ * Renaming a member orphans every dismissal recorded under the old value, so
14
+ * treat these strings as a migration surface.
15
+ */
16
+ enum RecommendationType {
17
+ Monitor = "Monitor",
18
+ }
19
+
20
+ export default RecommendationType;
@@ -0,0 +1,129 @@
1
+ /*
2
+ * When a runbook execution stops being anybody's responsibility.
3
+ *
4
+ * An execution runs inside a single queue job on one Worker. If that Worker
5
+ * dies mid-step and the job is never redelivered — Redis lost it, the stall
6
+ * budget ran out, the handler threw somewhere unrecoverable — the row stays
7
+ * Running with nobody advancing it. Nothing else in the system would ever
8
+ * change it, so the reconciler needs a defensible answer to "has this been
9
+ * abandoned?".
10
+ *
11
+ * The answer is derived from the step that is currently Running: it cannot
12
+ * legitimately outlive the claim + execution window its author configured, so
13
+ * anything past that window plus a grace margin is abandoned. Deriving it per
14
+ * execution (rather than picking one global timeout) matters now that a step
15
+ * may be configured for anything from one second to one hour — a single
16
+ * threshold would either kill live hour-long restores or leave a one-second
17
+ * step hanging for an hour.
18
+ */
19
+
20
+ import {
21
+ BashStepConfig,
22
+ HttpRequestStepConfig,
23
+ JavaScriptStepConfig,
24
+ RunbookStep,
25
+ } from "./RunbookStep";
26
+ import { RunbookStepExecutionState } from "./RunbookStepExecution";
27
+ import RunbookStepExecutionStatus from "./RunbookStepExecutionStatus";
28
+ import RunbookStepType from "./RunbookStepType";
29
+ import {
30
+ MAX_STEP_EXECUTION_TIMEOUT_IN_MS,
31
+ resolveAgentClaimTimeoutInMs,
32
+ resolveStepExecutionTimeoutInMs,
33
+ } from "./RunbookStepTimeout";
34
+
35
+ /*
36
+ * Margin on top of a step's own window before the execution is declared
37
+ * abandoned. The Worker running the step gives up at claim + execution + 5s
38
+ * and then writes the failure itself, so this only has to outlast that write —
39
+ * five minutes leaves room for a slow database or a Worker that is briefly
40
+ * paused, and keeps the reconciler from racing a run that is still healthy.
41
+ */
42
+ export const STUCK_EXECUTION_GRACE_IN_MS: number = 5 * 60 * 1000;
43
+
44
+ /*
45
+ * Allowance for a step type whose runtime the author cannot bound — today
46
+ * that is the AI step, which runs as long as the model provider takes. The
47
+ * longest configurable step window is the least surprising ceiling to borrow.
48
+ */
49
+ export const UNBOUNDED_STEP_ALLOWANCE_IN_MS: number =
50
+ MAX_STEP_EXECUTION_TIMEOUT_IN_MS;
51
+
52
+ /*
53
+ * The longest a single step can legitimately occupy its Worker. Agent steps
54
+ * spend the claim window waiting for an agent to pick the job up and the
55
+ * execution window actually running, so they get both.
56
+ */
57
+ export function getStepMaxRuntimeInMs(step: RunbookStep): number {
58
+ switch (step.type) {
59
+ case RunbookStepType.Bash:
60
+ case RunbookStepType.JavaScript: {
61
+ const config: BashStepConfig | JavaScriptStepConfig = step.config as
62
+ | BashStepConfig
63
+ | JavaScriptStepConfig;
64
+ return (
65
+ resolveAgentClaimTimeoutInMs(config.claimTimeoutInMs) +
66
+ resolveStepExecutionTimeoutInMs(config.timeoutInMs)
67
+ );
68
+ }
69
+
70
+ case RunbookStepType.HttpRequest: {
71
+ const config: HttpRequestStepConfig =
72
+ step.config as HttpRequestStepConfig;
73
+ return resolveStepExecutionTimeoutInMs(config.timeoutInMs);
74
+ }
75
+
76
+ /*
77
+ * Manual steps park the execution as WaitingForManualStep rather than
78
+ * Running, so one found Running is a torn write, not a wait. It gets no
79
+ * allowance — the grace margin alone decides.
80
+ */
81
+ case RunbookStepType.Manual:
82
+ return 0;
83
+
84
+ default:
85
+ return UNBOUNDED_STEP_ALLOWANCE_IN_MS;
86
+ }
87
+ }
88
+
89
+ /*
90
+ * Deadline for an execution currently in the Running state.
91
+ *
92
+ * Anchored on the running step's own startedAt where possible. Two fallbacks
93
+ * use the execution's updatedAt instead:
94
+ *
95
+ * - A step is Running but carries no usable startedAt. The state machine
96
+ * stamps startedAt and persists in the same write, so updatedAt is the same
97
+ * instant; the step still gets its full allowance.
98
+ * - No step is Running at all. The Worker died between steps, so nothing is
99
+ * executing and no allowance is owed — only the grace margin.
100
+ */
101
+ export function getRunningExecutionDeadline(data: {
102
+ stepExecutions: Array<RunbookStepExecutionState>;
103
+ executionUpdatedAt: Date;
104
+ }): Date {
105
+ const runningStep: RunbookStepExecutionState | undefined =
106
+ data.stepExecutions.find((stepExecution: RunbookStepExecutionState) => {
107
+ return stepExecution.status === RunbookStepExecutionStatus.Running;
108
+ });
109
+
110
+ if (!runningStep) {
111
+ return new Date(
112
+ data.executionUpdatedAt.getTime() + STUCK_EXECUTION_GRACE_IN_MS,
113
+ );
114
+ }
115
+
116
+ const startedAtMs: number = runningStep.startedAt
117
+ ? new Date(runningStep.startedAt).getTime()
118
+ : NaN;
119
+
120
+ const anchorMs: number = isFinite(startedAtMs)
121
+ ? startedAtMs
122
+ : data.executionUpdatedAt.getTime();
123
+
124
+ return new Date(
125
+ anchorMs +
126
+ getStepMaxRuntimeInMs(runningStep.step) +
127
+ STUCK_EXECUTION_GRACE_IN_MS,
128
+ );
129
+ }
@@ -0,0 +1,202 @@
1
+ /*
2
+ * Timeouts are configured per step and stored on the step config in
3
+ * milliseconds. Both the dashboard (which edits them) and the Worker (which
4
+ * enforces them) resolve values through this module so a step never runs with
5
+ * a bound the author could not see, and never with one that would pin a
6
+ * Worker slot open indefinitely.
7
+ */
8
+
9
+ // How long the step itself may run before it is killed.
10
+ export const DEFAULT_STEP_EXECUTION_TIMEOUT_IN_MS: number = 30 * 1000;
11
+ export const MIN_STEP_EXECUTION_TIMEOUT_IN_MS: number = 1000;
12
+ export const MAX_STEP_EXECUTION_TIMEOUT_IN_MS: number = 60 * 60 * 1000;
13
+
14
+ /*
15
+ * How long the Worker waits for the selected agent to claim the job. Only
16
+ * meaningful for Bash and JavaScript steps, which never run on the Worker.
17
+ */
18
+ export const DEFAULT_AGENT_CLAIM_TIMEOUT_IN_MS: number = 2 * 60 * 1000;
19
+ export const MIN_AGENT_CLAIM_TIMEOUT_IN_MS: number = 1000;
20
+ export const MAX_AGENT_CLAIM_TIMEOUT_IN_MS: number = 60 * 60 * 1000;
21
+
22
+ export interface TimeoutBounds {
23
+ defaultInMs: number;
24
+ minInMs: number;
25
+ maxInMs: number;
26
+ }
27
+
28
+ export const STEP_EXECUTION_TIMEOUT_BOUNDS: TimeoutBounds = {
29
+ defaultInMs: DEFAULT_STEP_EXECUTION_TIMEOUT_IN_MS,
30
+ minInMs: MIN_STEP_EXECUTION_TIMEOUT_IN_MS,
31
+ maxInMs: MAX_STEP_EXECUTION_TIMEOUT_IN_MS,
32
+ };
33
+
34
+ export const AGENT_CLAIM_TIMEOUT_BOUNDS: TimeoutBounds = {
35
+ defaultInMs: DEFAULT_AGENT_CLAIM_TIMEOUT_IN_MS,
36
+ minInMs: MIN_AGENT_CLAIM_TIMEOUT_IN_MS,
37
+ maxInMs: MAX_AGENT_CLAIM_TIMEOUT_IN_MS,
38
+ };
39
+
40
+ /*
41
+ * Resolve a configured timeout to the value execution should actually use.
42
+ *
43
+ * Anything unusable — unset, blank, non-numeric, zero or negative — falls back
44
+ * to the default rather than failing the step, because a runbook that runs
45
+ * with the documented default is more useful during an incident than one that
46
+ * refuses to run at all. Usable values are rounded to whole milliseconds and
47
+ * clamped into range.
48
+ */
49
+ export function resolveTimeoutInMs(
50
+ value: number | string | null | undefined,
51
+ bounds: TimeoutBounds,
52
+ ): number {
53
+ if (value === null || value === undefined || value === "") {
54
+ return bounds.defaultInMs;
55
+ }
56
+
57
+ const parsed: number = typeof value === "number" ? value : Number(value);
58
+
59
+ if (!isFinite(parsed) || parsed <= 0) {
60
+ return bounds.defaultInMs;
61
+ }
62
+
63
+ return Math.min(Math.max(Math.round(parsed), bounds.minInMs), bounds.maxInMs);
64
+ }
65
+
66
+ export function resolveStepExecutionTimeoutInMs(
67
+ value: number | string | null | undefined,
68
+ ): number {
69
+ return resolveTimeoutInMs(value, STEP_EXECUTION_TIMEOUT_BOUNDS);
70
+ }
71
+
72
+ export function resolveAgentClaimTimeoutInMs(
73
+ value: number | string | null | undefined,
74
+ ): number {
75
+ return resolveTimeoutInMs(value, AGENT_CLAIM_TIMEOUT_BOUNDS);
76
+ }
77
+
78
+ /*
79
+ * Milliseconds are the storage unit; seconds are what people think in. The
80
+ * two helpers below bridge the step editor's seconds input and the stored
81
+ * value. An empty input means "unset" — the step then uses the default — so
82
+ * it round-trips to undefined rather than to zero.
83
+ */
84
+ export function timeoutInMsToSecondsInputValue(
85
+ value: number | null | undefined,
86
+ ): string {
87
+ if (value === null || value === undefined || !isFinite(Number(value))) {
88
+ return "";
89
+ }
90
+
91
+ const seconds: number = Number(value) / 1000;
92
+
93
+ if (seconds <= 0) {
94
+ return "";
95
+ }
96
+
97
+ // Sub-second values would render as "0" and read as "no timeout"; keep the decimal.
98
+ return String(Math.round(seconds * 1000) / 1000);
99
+ }
100
+
101
+ export function secondsInputValueToTimeoutInMs(
102
+ value: string,
103
+ ): number | undefined {
104
+ const trimmed: string = (value || "").trim();
105
+
106
+ if (!trimmed) {
107
+ return undefined;
108
+ }
109
+
110
+ const seconds: number = Number(trimmed);
111
+
112
+ if (!isFinite(seconds) || seconds <= 0) {
113
+ return undefined;
114
+ }
115
+
116
+ const inMs: number = Math.round(seconds * 1000);
117
+
118
+ /*
119
+ * Sub-half-millisecond input rounds to zero. Zero is not a timeout, so it
120
+ * reports as unset like any other unusable value — storing a literal 0 would
121
+ * put a number in the step config that means nothing.
122
+ */
123
+ if (inMs <= 0) {
124
+ return undefined;
125
+ }
126
+
127
+ return inMs;
128
+ }
129
+
130
+ /*
131
+ * Shown when the field holds something that is not a number at all. Lives here
132
+ * rather than in the editor so the message the browser's own parse failure
133
+ * produces is the same one this validator produces.
134
+ */
135
+ export const NON_NUMERIC_TIMEOUT_MESSAGE: string = "Enter a number of seconds.";
136
+
137
+ /*
138
+ * Validation message for the step editor. Returns null when the input is
139
+ * acceptable — including when it is blank, which simply means "use the
140
+ * default". Out-of-range values are still saved and then clamped at run time;
141
+ * the message is what tells the author that will happen.
142
+ */
143
+ export function getTimeoutValidationError(
144
+ value: string,
145
+ bounds: TimeoutBounds,
146
+ ): string | null {
147
+ const trimmed: string = (value || "").trim();
148
+
149
+ if (!trimmed) {
150
+ return null;
151
+ }
152
+
153
+ const seconds: number = Number(trimmed);
154
+
155
+ if (!isFinite(seconds)) {
156
+ return NON_NUMERIC_TIMEOUT_MESSAGE;
157
+ }
158
+
159
+ const inMs: number = Math.round(seconds * 1000);
160
+
161
+ /*
162
+ * Zero, negatives, and anything that rounds down to zero milliseconds are
163
+ * not timeouts. They fall back to the default rather than being clamped up,
164
+ * so they get the same message.
165
+ */
166
+ if (seconds <= 0 || inMs <= 0) {
167
+ return "Timeout must be greater than 0 seconds.";
168
+ }
169
+
170
+ if (inMs < bounds.minInMs) {
171
+ return `Minimum is ${bounds.minInMs / 1000} second${
172
+ bounds.minInMs === 1000 ? "" : "s"
173
+ }.`;
174
+ }
175
+
176
+ if (inMs > bounds.maxInMs) {
177
+ return `Maximum is ${bounds.maxInMs / 1000} seconds (${
178
+ bounds.maxInMs / 60000
179
+ } minutes).`;
180
+ }
181
+
182
+ return null;
183
+ }
184
+
185
+ /*
186
+ * True when the input is a usable number that sits outside the bounds — the
187
+ * only case where run time will clamp it. Unusable input (blank, zero, junk)
188
+ * falls back to the default instead, which is the opposite end of the range,
189
+ * so the editor must not promise clamping there.
190
+ */
191
+ export function willTimeoutBeClamped(
192
+ value: string,
193
+ bounds: TimeoutBounds,
194
+ ): boolean {
195
+ const inMs: number | undefined = secondsInputValueToTimeoutInMs(value);
196
+
197
+ if (inMs === undefined) {
198
+ return false;
199
+ }
200
+
201
+ return inMs < bounds.minInMs || inMs > bounds.maxInMs;
202
+ }
@@ -0,0 +1,92 @@
1
+ /*
2
+ * Sampling decision shared by the log and trace drop-filter engines.
3
+ *
4
+ * This used to be `filter.samplePercentage || 50` duplicated in two
5
+ * services, which had three separate problems:
6
+ *
7
+ * 1. `samplePercentage` is nullable with no default and the form field
8
+ * was optional, so an UNSET percentage silently became "throw away
9
+ * half of every matching record" — while the view page rendered the
10
+ * same unset value as "0% kept".
11
+ * 2. A stored `0` was indistinguishable from unset, so it also kept 50%.
12
+ * 3. The two copies could drift.
13
+ *
14
+ * The fix is to fail SAFE: a percentage we cannot honour makes the filter a
15
+ * no-op rather than a data shredder. Callers that want "discard everything
16
+ * matching" have an explicit `drop` action for that.
17
+ *
18
+ * Note on the `0` case specifically. A literal reading of `0` is "keep 0%",
19
+ * i.e. drop every matching record — but `0` NEVER meant that in any shipped
20
+ * version (it kept half), so honouring it now would start deleting data
21
+ * that used to survive. Treating it as misconfigured is strictly less
22
+ * destructive than both the old behaviour and the literal reading, and
23
+ * save-time validation (Common/Server/Utils/DropFilterValidation.ts) stops
24
+ * new rows from getting there at all.
25
+ */
26
+
27
+ // Keep everything: the fail-safe value for a percentage we can't honour.
28
+ export const KEEP_ALL_PERCENTAGE: number = 100;
29
+
30
+ /*
31
+ * The range a human is allowed to save. Enforced at the API boundary by
32
+ * Common/Server/Utils/DropFilterValidation.ts and mirrored in the dashboard
33
+ * form; kept here so the validator, the form and the engine cannot drift
34
+ * apart on what counts as a usable percentage.
35
+ */
36
+ export const MIN_SAMPLE_PERCENTAGE: number = 1;
37
+ export const MAX_SAMPLE_PERCENTAGE: number = 99;
38
+
39
+ /*
40
+ * Whether a stored value is one the engine will actually sample on. The
41
+ * dashboard uses this to render "not configured" instead of the "0% kept"
42
+ * it used to show for an unset percentage — a display that directly
43
+ * contradicted the engine's old behaviour of keeping half.
44
+ */
45
+ export function isSamplePercentageConfigured(
46
+ samplePercentage: number | undefined | null,
47
+ ): boolean {
48
+ return resolveSamplePercentage(samplePercentage) < KEEP_ALL_PERCENTAGE;
49
+ }
50
+
51
+ /*
52
+ * Normalize a stored `samplePercentage` into a percentage-to-KEEP.
53
+ *
54
+ * Anything that is not a finite number in the exclusive range (0, 100) is
55
+ * misconfigured and resolves to "keep everything".
56
+ */
57
+ export function resolveSamplePercentage(
58
+ samplePercentage: number | undefined | null,
59
+ ): number {
60
+ if (
61
+ typeof samplePercentage !== "number" ||
62
+ !Number.isFinite(samplePercentage)
63
+ ) {
64
+ return KEEP_ALL_PERCENTAGE;
65
+ }
66
+
67
+ if (samplePercentage <= 0 || samplePercentage >= KEEP_ALL_PERCENTAGE) {
68
+ return KEEP_ALL_PERCENTAGE;
69
+ }
70
+
71
+ return samplePercentage;
72
+ }
73
+
74
+ /*
75
+ * True when a sample-action filter should discard this record.
76
+ *
77
+ * `random` is injectable so the decision is testable without stubbing
78
+ * global Math.random. It is only consulted when the percentage actually
79
+ * calls for sampling, so a keep-everything filter costs no entropy.
80
+ */
81
+ export function shouldDropBySampling(
82
+ samplePercentage: number | undefined | null,
83
+ random: () => number = Math.random,
84
+ ): boolean {
85
+ const keepPercentage: number = resolveSamplePercentage(samplePercentage);
86
+
87
+ if (keepPercentage >= KEEP_ALL_PERCENTAGE) {
88
+ return false;
89
+ }
90
+
91
+ return random() * 100 >= keepPercentage;
92
+ }
@@ -9,7 +9,6 @@ import AILoader from "./AILoader";
9
9
  import Alert, { AlertType } from "../Alerts/Alert";
10
10
  import ButtonType from "../Button/ButtonTypes";
11
11
  import { ButtonStyleType } from "../Button/Button";
12
- import IconProp from "../../../Types/Icon/IconProp";
13
12
  import Dropdown, { DropdownOption, DropdownValue } from "../Dropdown/Dropdown";
14
13
  import MarkdownEditor from "../Markdown.tsx/MarkdownEditor";
15
14
 
@@ -112,7 +111,6 @@ const GenerateFromAIModal: FunctionComponent<GenerateFromAIModalProps> = (
112
111
  disableSubmitButton={isGenerating}
113
112
  onSubmit={handleGenerate}
114
113
  modalWidth={ModalWidth.Large}
115
- icon={IconProp.Bolt}
116
114
  >
117
115
  <>
118
116
  {error && (
@@ -32,13 +32,21 @@ const Accordion: FunctionComponent<ComponentProps> = (
32
32
  }
33
33
  }, [props.isInitiallyExpanded]);
34
34
 
35
+ /*
36
+ * A title-less accordion has nothing to click, so it stays open. Keyed on
37
+ * whether there is a title rather than on the title itself: callers may pass
38
+ * an element, and a fresh element on every parent render would otherwise
39
+ * collapse an accordion the visitor had just opened.
40
+ */
41
+ const hasTitle: boolean = Boolean(props.title);
42
+
35
43
  useEffect(() => {
36
- if (!props.title) {
44
+ if (!hasTitle) {
37
45
  setIsOpen(true);
38
46
  } else if (!props.isInitiallyExpanded) {
39
47
  setIsOpen(false);
40
48
  }
41
- }, [props.title]);
49
+ }, [hasTitle]);
42
50
 
43
51
  useEffect(() => {
44
52
  if (props.onClick) {
@@ -370,7 +370,6 @@ function useBulkLabelActions<T extends BaseModel>(
370
370
  <Modal
371
371
  title="No Labels to Remove"
372
372
  description="The selected items don't have any labels to remove."
373
- icon={IconProp.Label}
374
373
  onClose={closeRemoveModal}
375
374
  closeButtonText="Close"
376
375
  >
@@ -32,6 +32,22 @@ export interface ComponentProps {
32
32
  ariaLabelledby?: string | undefined;
33
33
  }
34
34
 
35
+ /*
36
+ * Callers hand us `any` through Form's currentValues, so a non-string can
37
+ * still reach a prop typed as string.
38
+ */
39
+ function toEditorText(value: string | undefined): string {
40
+ if (value === undefined || value === null) {
41
+ return "";
42
+ }
43
+
44
+ if (typeof value !== "string") {
45
+ return JSON.stringify(value, null, 4);
46
+ }
47
+
48
+ return value;
49
+ }
50
+
35
51
  const CodeEditor: FunctionComponent<ComponentProps> = (
36
52
  props: ComponentProps,
37
53
  ): ReactElement => {
@@ -42,15 +58,25 @@ const CodeEditor: FunctionComponent<ComponentProps> = (
42
58
  const editorRef: React.MutableRefObject<any> = useRef<any>(null);
43
59
  const theme: Theme = useTheme();
44
60
 
45
- useEffect(() => {
46
- let value: string | undefined = props.value;
47
-
48
- if (value && typeof value !== "string") {
49
- value = JSON.stringify(value, null, 4);
50
- }
61
+ /*
62
+ * `value` is the controlled prop; `initialValue` only seeds an uncontrolled
63
+ * editor. Both used to be synced from their own useEffect, and because
64
+ * effects run in declaration order the `initialValue` one ran last on mount
65
+ * and reset the state to "" - so a caller that passed only `value` mounted
66
+ * an empty editor even though it had text to show. Seed the state on the
67
+ * first render and keep the precedence in a single effect.
68
+ */
69
+ const [value, setValue] = useState<string>(() => {
70
+ return toEditorText(props.value ?? props.initialValue);
71
+ });
51
72
 
52
- setValue(value || "");
53
- }, [props.value]);
73
+ useEffect(() => {
74
+ setValue(
75
+ toEditorText(
76
+ props.value === undefined ? props.initialValue : props.value,
77
+ ),
78
+ );
79
+ }, [props.value, props.initialValue]);
54
80
 
55
81
  useEffect(() => {
56
82
  if (props.placeholder) {
@@ -95,8 +121,6 @@ const CodeEditor: FunctionComponent<ComponentProps> = (
95
121
  "block w-full rounded-md border bg-white py-2 pl-3 pr-3 text-sm placeholder-gray-500 focus:border-red-500 focus:text-gray-900 focus:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-red-500 sm:text-sm border-red-300 pr-10 text-red-900 placeholder-red-300 focus:border-red-500 focus:outline-none focus:ring-red-500";
96
122
  }
97
123
 
98
- const [value, setValue] = useState<string>("");
99
-
100
124
  // Handle spell check configuration for Monaco Editor
101
125
  useEffect(() => {
102
126
  if (editorRef.current && props.type === CodeType.Markdown) {
@@ -112,16 +136,6 @@ const CodeEditor: FunctionComponent<ComponentProps> = (
112
136
  }
113
137
  }, [props.disableSpellCheck, props.type]);
114
138
 
115
- useEffect(() => {
116
- let initialValue: string | undefined = props.initialValue;
117
-
118
- if (initialValue && typeof initialValue !== "string") {
119
- initialValue = JSON.stringify(initialValue, null, 4);
120
- }
121
-
122
- setValue(initialValue || "");
123
- }, [props.initialValue]);
124
-
125
139
  return (
126
140
  <div
127
141
  data-testid={props.dataTestId}
@@ -103,7 +103,6 @@ const DashboardStartAndEndDateView: FunctionComponent<ComponentProps> = (
103
103
  <Modal
104
104
  title="Select Time Range"
105
105
  description="Choose a quick range or set an exact start and end date & time."
106
- icon={IconProp.Clock}
107
106
  modalWidth={ModalWidth.Medium}
108
107
  submitButtonText="Apply"
109
108
  disableSubmitButton={!isSelectionValid(tempStartAndEndDate)}
@@ -1,5 +1,5 @@
1
1
  import Modal, { ModalWidth } from "../Modal/Modal";
2
- import Icon, { IconType } from "../Icon/Icon";
2
+ import Icon from "../Icon/Icon";
3
3
  import IconProp from "../../../Types/Icon/IconProp";
4
4
  import Input from "../Input/Input";
5
5
  import Button, { ButtonStyleType } from "../Button/Button";
@@ -759,30 +759,6 @@ const EditionLabel: FunctionComponent<ComponentProps> = (
759
759
  globalConfig?.enterpriseLicenseKey,
760
760
  ]);
761
761
 
762
- const modalIcon: IconProp = useMemo(() => {
763
- if (!IS_ENTERPRISE_EDITION || isConfigLoading) {
764
- return IconProp.Cube;
765
- }
766
-
767
- if (!licenseValid || isUserLimitBreached) {
768
- return IconProp.Alert;
769
- }
770
-
771
- return IconProp.ShieldCheck;
772
- }, [isConfigLoading, licenseValid, isUserLimitBreached]);
773
-
774
- const modalIconType: IconType = useMemo(() => {
775
- if (!IS_ENTERPRISE_EDITION || isConfigLoading) {
776
- return IconType.Info;
777
- }
778
-
779
- if (!licenseValid || isUserLimitBreached) {
780
- return IconType.Danger;
781
- }
782
-
783
- return IconType.Success;
784
- }, [isConfigLoading, licenseValid, isUserLimitBreached]);
785
-
786
762
  const modalDescription: string = useMemo(() => {
787
763
  if (!IS_ENTERPRISE_EDITION) {
788
764
  return "You are running the free, open-source build of OneUptime.";
@@ -1326,8 +1302,6 @@ const EditionLabel: FunctionComponent<ComponentProps> = (
1326
1302
  <Modal
1327
1303
  title={editionName}
1328
1304
  description={modalDescription}
1329
- icon={modalIcon}
1330
- iconType={modalIconType}
1331
1305
  rightElement={modalRightElement}
1332
1306
  submitButtonText={modalSubmitButtonText}
1333
1307
  closeButtonText="Close"