@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
@@ -0,0 +1,358 @@
1
+ import InfoCard from "../../../UI/Components/InfoCard/InfoCard";
2
+ /*
3
+ * The package entry, not the `/extend-expect` subpath the older tests use:
4
+ * the matchers are already registered by Tests/jest.setup.ts, and only this
5
+ * specifier resolves to the type augmentation that makes them visible to
6
+ * TypeScript.
7
+ */
8
+ import "@testing-library/jest-dom";
9
+ import { fireEvent, render, screen } from "@testing-library/react";
10
+ import React from "react";
11
+ import { describe, expect, jest, test } from "@jest/globals";
12
+
13
+ /*
14
+ * InfoCard is the stat card used across the product. Most of them are inert
15
+ * containers, a handful navigate somewhere when clicked, and the network
16
+ * summary strips use them as toggles that filter the table below.
17
+ *
18
+ * The three have to stay distinguishable to a screen reader and to the
19
+ * keyboard, and the distinctions are all driven off which props were passed —
20
+ * so that is what these cover, end to end through a real render.
21
+ */
22
+
23
+ /*
24
+ * The card's own root element. Taken off the render container rather than
25
+ * walked up from the title, because a card with no click handler has no role
26
+ * to query it by — which is exactly what several of these assert.
27
+ */
28
+ function getCard(): HTMLElement {
29
+ return document.body.firstElementChild!.firstElementChild as HTMLElement;
30
+ }
31
+
32
+ describe("InfoCard", () => {
33
+ describe("a card with no click handler", () => {
34
+ test("renders its title and value", () => {
35
+ render(<InfoCard title="Devices Up" value="12" />);
36
+
37
+ expect(screen.getByText("Devices Up")).toBeInTheDocument();
38
+ expect(screen.getByText("12")).toBeInTheDocument();
39
+ });
40
+
41
+ /*
42
+ * The majority of InfoCards in the product are read-only. Announcing one
43
+ * as a button would put a tab stop on every tile of every dashboard.
44
+ */
45
+ test("is not a button, and is not focusable", () => {
46
+ render(<InfoCard title="Devices Up" value="12" />);
47
+
48
+ expect(screen.queryByRole("button")).not.toBeInTheDocument();
49
+ expect(getCard()).not.toHaveAttribute("tabindex");
50
+ expect(getCard()).not.toHaveAttribute("aria-pressed");
51
+ expect(getCard()).not.toHaveAttribute("aria-label");
52
+ });
53
+
54
+ test("does not look clickable", () => {
55
+ render(<InfoCard title="Devices Up" value="12" />);
56
+
57
+ expect(getCard()).not.toHaveClass("cursor-pointer");
58
+ });
59
+ });
60
+
61
+ describe("a card that navigates when clicked", () => {
62
+ /*
63
+ * The pre-existing clickable cards — the Home overview stats, the
64
+ * Kubernetes and Proxmox summaries — all navigate. They pass onClick and
65
+ * no isSelected.
66
+ */
67
+ test("is a real button, reachable by keyboard", () => {
68
+ render(
69
+ <InfoCard
70
+ title="Devices Up"
71
+ value="12"
72
+ onClick={() => {
73
+ // no-op
74
+ }}
75
+ />,
76
+ );
77
+
78
+ const card: HTMLElement = screen.getByRole("button");
79
+ expect(card).toBeInTheDocument();
80
+ expect(card).toHaveAttribute("tabindex", "0");
81
+ expect(card).toHaveClass("cursor-pointer");
82
+ });
83
+
84
+ /*
85
+ * The regression this guards: `aria-pressed="false"` asserts the control
86
+ * is a toggle that is currently off. On a card that navigates away, that
87
+ * is a state activating it can never reach — the user is told to expect
88
+ * something the product never does.
89
+ */
90
+ test("is not announced as an unpressed toggle", () => {
91
+ render(
92
+ <InfoCard
93
+ title="Devices Up"
94
+ value="12"
95
+ onClick={() => {
96
+ // no-op
97
+ }}
98
+ />,
99
+ );
100
+
101
+ expect(screen.getByRole("button")).not.toHaveAttribute("aria-pressed");
102
+ });
103
+
104
+ test("keeps the plain border", () => {
105
+ render(
106
+ <InfoCard
107
+ title="Devices Up"
108
+ value="12"
109
+ onClick={() => {
110
+ // no-op
111
+ }}
112
+ />,
113
+ );
114
+
115
+ expect(screen.getByRole("button")).toHaveClass("border-gray-200");
116
+ });
117
+ });
118
+
119
+ describe("a card used as a toggle", () => {
120
+ test("announces itself as pressed when selected", () => {
121
+ render(
122
+ <InfoCard
123
+ title="Devices Up"
124
+ value="12"
125
+ isSelected={true}
126
+ onClick={() => {
127
+ // no-op
128
+ }}
129
+ />,
130
+ );
131
+
132
+ expect(screen.getByRole("button")).toHaveAttribute(
133
+ "aria-pressed",
134
+ "true",
135
+ );
136
+ });
137
+
138
+ /*
139
+ * Explicit `false` is a real state here — the tile exists, it is simply
140
+ * not the one the table is filtered by — so it must still announce as a
141
+ * toggle, unlike the navigation card above.
142
+ */
143
+ test("announces itself as unpressed when explicitly not selected", () => {
144
+ render(
145
+ <InfoCard
146
+ title="Devices Up"
147
+ value="12"
148
+ isSelected={false}
149
+ onClick={() => {
150
+ // no-op
151
+ }}
152
+ />,
153
+ );
154
+
155
+ expect(screen.getByRole("button")).toHaveAttribute(
156
+ "aria-pressed",
157
+ "false",
158
+ );
159
+ });
160
+
161
+ /*
162
+ * Tailwind emits both border-colour utilities at the same specificity, so
163
+ * a selected card that merely *added* a border colour would leave the
164
+ * winner up to stylesheet order. The class is swapped.
165
+ */
166
+ test("swaps its border rather than stacking a second one", () => {
167
+ render(
168
+ <InfoCard
169
+ title="Devices Up"
170
+ value="12"
171
+ isSelected={true}
172
+ onClick={() => {
173
+ // no-op
174
+ }}
175
+ />,
176
+ );
177
+
178
+ const card: HTMLElement = screen.getByRole("button");
179
+ expect(card).toHaveClass("border-indigo-500");
180
+ expect(card).not.toHaveClass("border-gray-200");
181
+ });
182
+
183
+ test("carries the caller's label for screen readers", () => {
184
+ render(
185
+ <InfoCard
186
+ title="Devices Up"
187
+ value="12"
188
+ isSelected={true}
189
+ ariaLabel="Devices Up: 12. Showing these in the list below."
190
+ onClick={() => {
191
+ // no-op
192
+ }}
193
+ />,
194
+ );
195
+
196
+ expect(
197
+ screen.getByRole("button", {
198
+ name: "Devices Up: 12. Showing these in the list below.",
199
+ }),
200
+ ).toBeInTheDocument();
201
+ });
202
+
203
+ // A label on an inert card would announce a control that is not there.
204
+ test("ignores the label when there is nothing to activate", () => {
205
+ render(
206
+ <InfoCard title="Devices Up" value="12" ariaLabel="Should not apply" />,
207
+ );
208
+
209
+ expect(getCard()).not.toHaveAttribute("aria-label");
210
+ });
211
+
212
+ // Selection styling is meaningless without a handler to toggle it.
213
+ test("a non-clickable card ignores isSelected", () => {
214
+ render(<InfoCard title="Devices Up" value="12" isSelected={true} />);
215
+
216
+ expect(getCard()).toHaveClass("border-gray-200");
217
+ expect(getCard()).not.toHaveAttribute("aria-pressed");
218
+ });
219
+ });
220
+
221
+ describe("activation", () => {
222
+ test("a click fires the handler", () => {
223
+ const onClick: () => void = jest.fn();
224
+ render(<InfoCard title="Devices Up" value="12" onClick={onClick} />);
225
+
226
+ fireEvent.click(screen.getByRole("button"));
227
+
228
+ expect(onClick).toHaveBeenCalledTimes(1);
229
+ });
230
+
231
+ /*
232
+ * A div with an onClick is invisible to the keyboard. Enter and Space are
233
+ * what a real button responds to, and both have to work here or the tiles
234
+ * are mouse-only.
235
+ */
236
+ test("Enter fires the handler", () => {
237
+ const onClick: () => void = jest.fn();
238
+ render(<InfoCard title="Devices Up" value="12" onClick={onClick} />);
239
+
240
+ fireEvent.keyDown(screen.getByRole("button"), { key: "Enter" });
241
+
242
+ expect(onClick).toHaveBeenCalledTimes(1);
243
+ });
244
+
245
+ test("Space fires the handler", () => {
246
+ const onClick: () => void = jest.fn();
247
+ render(<InfoCard title="Devices Up" value="12" onClick={onClick} />);
248
+
249
+ fireEvent.keyDown(screen.getByRole("button"), { key: " " });
250
+
251
+ expect(onClick).toHaveBeenCalledTimes(1);
252
+ });
253
+
254
+ /*
255
+ * Space scrolls the page by default. Without preventDefault, activating a
256
+ * tile from the keyboard would also jump the view down a screen.
257
+ */
258
+ test("Space does not also scroll the page", () => {
259
+ render(
260
+ <InfoCard
261
+ title="Devices Up"
262
+ value="12"
263
+ onClick={() => {
264
+ // no-op
265
+ }}
266
+ />,
267
+ );
268
+
269
+ // fireEvent returns false when the handler called preventDefault.
270
+ const notCancelled: boolean = fireEvent.keyDown(
271
+ screen.getByRole("button"),
272
+ { key: " ", cancelable: true },
273
+ );
274
+
275
+ expect(notCancelled).toBe(false);
276
+ });
277
+
278
+ test("Enter does not swallow the default either way it is used", () => {
279
+ render(
280
+ <InfoCard
281
+ title="Devices Up"
282
+ value="12"
283
+ onClick={() => {
284
+ // no-op
285
+ }}
286
+ />,
287
+ );
288
+
289
+ expect(
290
+ fireEvent.keyDown(screen.getByRole("button"), {
291
+ key: "Enter",
292
+ cancelable: true,
293
+ }),
294
+ ).toBe(false);
295
+ });
296
+
297
+ test.each([["Tab"], ["Escape"], ["a"], ["ArrowDown"], ["Shift"]])(
298
+ "%s does not activate it",
299
+ (key: string) => {
300
+ const onClick: () => void = jest.fn();
301
+ render(<InfoCard title="Devices Up" value="12" onClick={onClick} />);
302
+
303
+ const notCancelled: boolean = fireEvent.keyDown(
304
+ screen.getByRole("button"),
305
+ { key: key, cancelable: true },
306
+ );
307
+
308
+ expect(onClick).not.toHaveBeenCalled();
309
+ // And the key still does whatever it normally does.
310
+ expect(notCancelled).toBe(true);
311
+ },
312
+ );
313
+ });
314
+
315
+ describe("styling passthrough", () => {
316
+ test("the caller's className still lands on the card", () => {
317
+ render(<InfoCard title="Devices Up" value="12" className="col-span-2" />);
318
+
319
+ expect(getCard()).toHaveClass("col-span-2");
320
+ });
321
+
322
+ test("the caller's text class still wraps the value", () => {
323
+ render(
324
+ <InfoCard
325
+ title="Devices Up"
326
+ value="12"
327
+ textClassName="text-emerald-600"
328
+ />,
329
+ );
330
+
331
+ expect(screen.getByText("12")).toHaveClass("text-emerald-600");
332
+ });
333
+
334
+ /*
335
+ * A keyboard user has to be able to see which card they are on — the
336
+ * focus ring is the only cue, since the card has no other focus styling.
337
+ */
338
+ test("a clickable card shows a focus ring", () => {
339
+ render(
340
+ <InfoCard
341
+ title="Devices Up"
342
+ value="12"
343
+ onClick={() => {
344
+ // no-op
345
+ }}
346
+ />,
347
+ );
348
+
349
+ expect(screen.getByRole("button")).toHaveClass("focus-visible:ring-2");
350
+ });
351
+
352
+ test("an inert card does not", () => {
353
+ render(<InfoCard title="Devices Up" value="12" />);
354
+
355
+ expect(getCard()).not.toHaveClass("focus-visible:ring-2");
356
+ });
357
+ });
358
+ });
@@ -0,0 +1,138 @@
1
+ import LogTimeRangePicker, {
2
+ LOG_TIME_RANGE_DROPDOWN_WIDTH_IN_PX,
3
+ } from "../../../UI/Components/LogsViewer/components/LogTimeRangePicker";
4
+ import RangeStartAndEndDateTime from "../../../Types/Time/RangeStartAndEndDateTime";
5
+ import TimeRange from "../../../Types/Time/TimeRange";
6
+ import "@testing-library/jest-dom/extend-expect";
7
+ import { cleanup, fireEvent, render, screen } from "@testing-library/react";
8
+ import React from "react";
9
+ import {
10
+ afterEach,
11
+ beforeEach,
12
+ describe,
13
+ expect,
14
+ jest,
15
+ test,
16
+ } from "@jest/globals";
17
+
18
+ const BUTTON_TEST_ID: string = "log-time-range-picker-button";
19
+ const DROPDOWN_TEST_ID: string = "log-time-range-picker-dropdown";
20
+
21
+ const ORIGINAL_INNER_WIDTH: number = window.innerWidth;
22
+ const originalGetBoundingClientRect: () => DOMRect =
23
+ Element.prototype.getBoundingClientRect;
24
+
25
+ function setViewportWidth(width: number): void {
26
+ Object.defineProperty(window, "innerWidth", {
27
+ configurable: true,
28
+ writable: true,
29
+ value: width,
30
+ });
31
+ }
32
+
33
+ function stubTriggerRect(left: number, right: number): void {
34
+ Element.prototype.getBoundingClientRect = function (this: Element): DOMRect {
35
+ if (
36
+ this instanceof HTMLElement &&
37
+ this.getAttribute("data-testid") === BUTTON_TEST_ID
38
+ ) {
39
+ return {
40
+ left: left,
41
+ right: right,
42
+ top: 40,
43
+ bottom: 68,
44
+ width: right - left,
45
+ height: 28,
46
+ x: left,
47
+ y: 40,
48
+ toJSON: (): Record<string, unknown> => {
49
+ return {};
50
+ },
51
+ } as DOMRect;
52
+ }
53
+
54
+ return originalGetBoundingClientRect.call(this);
55
+ };
56
+ }
57
+
58
+ function openDropdown(value: RangeStartAndEndDateTime): HTMLElement {
59
+ render(<LogTimeRangePicker value={value} onChange={jest.fn()} />);
60
+ fireEvent.click(screen.getByTestId(BUTTON_TEST_ID));
61
+ return screen.getByTestId(DROPDOWN_TEST_ID);
62
+ }
63
+
64
+ function hasClass(element: HTMLElement, className: string): boolean {
65
+ return element.classList.contains(className);
66
+ }
67
+
68
+ describe("LogTimeRangePicker", () => {
69
+ beforeEach(() => {
70
+ setViewportWidth(1440);
71
+ stubTriggerRect(64, 180);
72
+ });
73
+
74
+ afterEach(() => {
75
+ cleanup();
76
+ Element.prototype.getBoundingClientRect = originalGetBoundingClientRect;
77
+ setViewportWidth(ORIGINAL_INNER_WIDTH);
78
+ });
79
+
80
+ test("opens rightwards when the trigger sits at the left of the toolbar", () => {
81
+ const dropdown: HTMLElement = openDropdown({
82
+ range: TimeRange.PAST_ONE_HOUR,
83
+ });
84
+
85
+ expect(hasClass(dropdown, "left-0")).toBe(true);
86
+ expect(hasClass(dropdown, "right-0")).toBe(false);
87
+ expect(dropdown.getAttribute("data-align")).toBe("left");
88
+ });
89
+
90
+ test("flips to right alignment when the trigger is near the right edge", () => {
91
+ stubTriggerRect(1310, 1430);
92
+
93
+ const dropdown: HTMLElement = openDropdown({
94
+ range: TimeRange.PAST_ONE_HOUR,
95
+ });
96
+
97
+ expect(hasClass(dropdown, "right-0")).toBe(true);
98
+ expect(hasClass(dropdown, "left-0")).toBe(false);
99
+ expect(dropdown.getAttribute("data-align")).toBe("right");
100
+ });
101
+
102
+ test("stays left aligned on a narrow mobile viewport", () => {
103
+ setViewportWidth(375);
104
+ stubTriggerRect(12, 128);
105
+
106
+ expect(
107
+ hasClass(openDropdown({ range: TimeRange.PAST_ONE_HOUR }), "left-0"),
108
+ ).toBe(true);
109
+ });
110
+
111
+ test("caps the panel width so it cannot exceed the viewport", () => {
112
+ expect(
113
+ hasClass(
114
+ openDropdown({ range: TimeRange.PAST_ONE_HOUR }),
115
+ "max-w-[calc(100vw-1rem)]",
116
+ ),
117
+ ).toBe(true);
118
+ });
119
+
120
+ test("exports a width constant that matches the rendered w-72 panel", () => {
121
+ expect(LOG_TIME_RANGE_DROPDOWN_WIDTH_IN_PX).toBe(288);
122
+ expect(
123
+ hasClass(openDropdown({ range: TimeRange.PAST_ONE_HOUR }), "w-72"),
124
+ ).toBe(true);
125
+ });
126
+
127
+ test("keeps the panel anchored below the trigger", () => {
128
+ const dropdown: HTMLElement = openDropdown({
129
+ range: TimeRange.PAST_ONE_HOUR,
130
+ });
131
+
132
+ expect(hasClass(dropdown, "absolute")).toBe(true);
133
+ expect(hasClass(dropdown, "top-full")).toBe(true);
134
+ expect(
135
+ dropdown.parentElement?.classList.contains("relative") ?? false,
136
+ ).toBe(true);
137
+ });
138
+ });
@@ -2,9 +2,13 @@ import { ButtonStyleType } from "../../../UI/Components/Button/Button";
2
2
  import ButtonType from "../../../UI/Components/Button/ButtonTypes";
3
3
  import Modal, { ModalWidth } from "../../../UI/Components/Modal/Modal";
4
4
  import { describe, expect, it, test } from "@jest/globals";
5
- import "@testing-library/jest-dom/extend-expect";
5
+ /*
6
+ * The main entry, not "/extend-expect": the latter no longer ships type
7
+ * declarations, so every jest-dom matcher in this file fails to typecheck and
8
+ * the whole suite is skipped before a single assertion runs.
9
+ */
10
+ import "@testing-library/jest-dom";
6
11
  import { fireEvent, render } from "@testing-library/react";
7
- import IconProp from "../../../Types/Icon/IconProp";
8
12
  import React from "react";
9
13
  import getJestMockFunction, { MockFunction } from "../../../Tests/MockType";
10
14
 
@@ -338,16 +342,50 @@ describe("Modal", () => {
338
342
  expect(submitButton).toBeDisabled();
339
343
  });
340
344
 
341
- it("displays the icon when icon is set", () => {
345
+ /*
346
+ * The header carries the title, the description and the close button, and
347
+ * nothing else. A decorative icon beside the title said nothing the title did
348
+ * not already say, so there is no longer anywhere for one to be rendered.
349
+ */
350
+ it("renders no decorative icon in the header", () => {
342
351
  const onSubmitMock: MockFunction = getJestMockFunction();
343
352
 
353
+ const { queryByTestId, getByTestId } = render(
354
+ <Modal
355
+ title="Test Modal"
356
+ description="Test modal description"
357
+ onSubmit={onSubmitMock}
358
+ onClose={getJestMockFunction()}
359
+ >
360
+ <div>Modal content</div>
361
+ </Modal>,
362
+ );
363
+
364
+ expect(queryByTestId("icon")).not.toBeInTheDocument();
365
+
366
+ // The rest of the header is untouched.
367
+ expect(getByTestId("modal-title")).toHaveTextContent("Test Modal");
368
+ expect(getByTestId("modal-description")).toHaveTextContent(
369
+ "Test modal description",
370
+ );
371
+ expect(getByTestId("close-button")).toBeInTheDocument();
372
+ });
373
+
374
+ it("keeps the title as the first thing inside the header", () => {
344
375
  const { getByTestId } = render(
345
- <Modal title="Test Modal" onSubmit={onSubmitMock} icon={IconProp.SMS}>
376
+ <Modal title="Test Modal" onSubmit={getJestMockFunction()}>
346
377
  <div>Modal content</div>
347
378
  </Modal>,
348
379
  );
349
380
 
350
- expect(getByTestId("icon")).toBeInTheDocument();
381
+ const title: HTMLElement = getByTestId("modal-title");
382
+ const header: HTMLElement = title.parentElement!.parentElement!;
383
+
384
+ /*
385
+ * With the icon gone the title block is the header's first child. Anything
386
+ * else in that slot would push the title out of line with the body.
387
+ */
388
+ expect(header.firstElementChild).toContainElement(title);
351
389
  });
352
390
 
353
391
  it("displays the submit button with the default style when submitButtonStyleType is not set", () => {