@oneuptime/common 14.0.2 → 14.0.5

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 (765) hide show
  1. package/Models/DatabaseModels/Alert.ts +55 -0
  2. package/Models/DatabaseModels/AlertFeed.ts +2 -0
  3. package/Models/DatabaseModels/DatabaseServer.ts +1650 -0
  4. package/Models/DatabaseModels/DatabaseServerEndpoint.ts +540 -0
  5. package/Models/DatabaseModels/DatabaseServerFeed.ts +625 -0
  6. package/Models/DatabaseModels/DatabaseServerLabelRule.ts +514 -0
  7. package/Models/DatabaseModels/DatabaseServerOwnerRule.ts +596 -0
  8. package/Models/DatabaseModels/DatabaseServerOwnerTeam.ts +491 -0
  9. package/Models/DatabaseModels/DatabaseServerOwnerUser.ts +490 -0
  10. package/Models/DatabaseModels/Incident.ts +55 -0
  11. package/Models/DatabaseModels/IncidentAlert.ts +540 -0
  12. package/Models/DatabaseModels/IncidentFeed.ts +2 -0
  13. package/Models/DatabaseModels/Index.ts +18 -0
  14. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +26 -0
  15. package/Models/DatabaseModels/Project.ts +60 -0
  16. package/Models/DatabaseModels/RumApplication.ts +52 -1
  17. package/Models/DatabaseModels/ScheduledMaintenance.ts +55 -0
  18. package/Models/DatabaseModels/TelemetryException.ts +2 -0
  19. package/Models/DatabaseModels/UserProjectSsoConsent.ts +146 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.ts +28 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.ts +89 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.ts +673 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.ts +51 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  25. package/Server/Middleware/MultipartFormData.ts +1 -1
  26. package/Server/Middleware/TelemetryIngest.ts +15 -8
  27. package/Server/Services/AlertReminderRuleService.ts +100 -24
  28. package/Server/Services/DatabaseServerEndpointService.ts +895 -0
  29. package/Server/Services/DatabaseServerFeedService.ts +128 -0
  30. package/Server/Services/DatabaseServerLabelRuleEngineService.ts +340 -0
  31. package/Server/Services/DatabaseServerLabelRuleService.ts +14 -0
  32. package/Server/Services/DatabaseServerOwnerRuleEngineService.ts +425 -0
  33. package/Server/Services/DatabaseServerOwnerRuleService.ts +14 -0
  34. package/Server/Services/DatabaseServerOwnerTeamService.ts +180 -0
  35. package/Server/Services/DatabaseServerOwnerUserService.ts +173 -0
  36. package/Server/Services/DatabaseServerService.ts +4546 -0
  37. package/Server/Services/DatabaseService.ts +14 -8
  38. package/Server/Services/DockerResourceService.ts +43 -2
  39. package/Server/Services/IncidentAlertService.ts +1811 -0
  40. package/Server/Services/IncidentReminderRuleService.ts +103 -23
  41. package/Server/Services/IncidentService.ts +210 -10
  42. package/Server/Services/IncidentStateTimelineService.ts +24 -0
  43. package/Server/Services/Index.ts +18 -0
  44. package/Server/Services/InventoryItemService.ts +113 -5
  45. package/Server/Services/IoTDeviceService.ts +145 -37
  46. package/Server/Services/OpenTelemetryIngestService.ts +19 -0
  47. package/Server/Services/PodmanResourceService.ts +43 -2
  48. package/Server/Services/ScheduledMaintenanceReminderRuleService.ts +107 -23
  49. package/Server/Services/ServiceService.ts +1 -1
  50. package/Server/Services/TelemetryUsageBillingService.ts +29 -2
  51. package/Server/Services/UserProjectSsoConsentService.ts +74 -0
  52. package/Server/Services/UserService.ts +14 -1
  53. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +18 -0
  54. package/Server/Types/Database/QueryHelper.ts +30 -1
  55. package/Server/Utils/AI/Toolbox/ResourceTools.ts +69 -1
  56. package/Server/Utils/Database/AffectedResourceRelations.ts +6 -0
  57. package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +188 -6
  58. package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
  59. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +2262 -755
  60. package/Server/Utils/Monitor/MonitorIncident.ts +28 -1
  61. package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +268 -6
  62. package/Server/Utils/Monitor/MonitorResource.ts +47 -11
  63. package/Server/Utils/Monitor/MonitorResourceContext.ts +1 -0
  64. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +239 -21
  65. package/Server/Utils/Monitor/PerSeriesResolutionRootCause.ts +43 -0
  66. package/Server/Utils/Monitor/SeriesResourceLabels.ts +291 -0
  67. package/Server/Utils/Monitor/SeriesResourceLinker.ts +111 -12
  68. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +25 -0
  69. package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +24 -2
  70. package/Server/Utils/StartServer.ts +26 -6
  71. package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +2 -0
  72. package/Server/Utils/Telemetry/DatabaseEndpointDiscovery.ts +688 -0
  73. package/Server/Utils/Telemetry/EntityRegistry.ts +5 -1
  74. package/Server/Utils/Telemetry/LogExceptionExtractor.ts +18 -1
  75. package/Server/Utils/Telemetry/ResourceEntityFilter.ts +175 -12
  76. package/Server/Utils/Telemetry/ResourceFacetResolver.ts +12 -0
  77. package/Server/Utils/Telemetry/ServiceDependencyDiscovery.ts +606 -36
  78. package/Server/Utils/Telemetry/Telemetry.ts +16 -0
  79. package/Server/Utils/Telemetry/TelemetryEntity.ts +22 -22
  80. package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +16 -10
  81. package/Tests/App/Accounts/SignedInRedirect.test.tsx +241 -0
  82. package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +221 -4
  83. package/Tests/App/Dashboard/AIInsightsResourcePageContext.test.ts +42 -0
  84. package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +100 -0
  85. package/Tests/App/Dashboard/AffectedResourcesPicker.test.tsx +86 -0
  86. package/Tests/App/Dashboard/AffectedResourcesPickerHiddenTypes.test.tsx +2 -0
  87. package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +19 -0
  88. package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +14 -0
  89. package/Tests/App/Dashboard/BulkIncidentLinkActions.test.tsx +869 -0
  90. package/Tests/App/Dashboard/CephMetricTooltips.test.tsx +1777 -0
  91. package/Tests/App/Dashboard/CloudFleetSummary.test.ts +8 -0
  92. package/Tests/App/Dashboard/CloudMetricTooltips.test.tsx +887 -0
  93. package/Tests/App/Dashboard/ContainerHostMetricTooltips.test.tsx +1309 -0
  94. package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +26 -1
  95. package/Tests/App/Dashboard/DashboardAppSsoError.test.tsx +501 -0
  96. package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +64 -1
  97. package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +178 -18
  98. package/Tests/App/Dashboard/DashboardMasterPageSsoRedirect.test.tsx +444 -0
  99. package/Tests/App/Dashboard/DashboardNavBarForeignHiddenRule.test.tsx +573 -0
  100. package/Tests/App/Dashboard/DatabaseChartAxes.test.tsx +431 -0
  101. package/Tests/App/Dashboard/DatabaseContainerDetailBadge.test.tsx +249 -0
  102. package/Tests/App/Dashboard/DatabaseDashboardE2EFixes.test.ts +681 -0
  103. package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +1801 -0
  104. package/Tests/App/Dashboard/DatabaseFleetSummaryRefresh.test.tsx +280 -0
  105. package/Tests/App/Dashboard/DatabaseFormHelpers.test.tsx +321 -0
  106. package/Tests/App/Dashboard/DatabaseMetricMonitorLink.test.tsx +795 -0
  107. package/Tests/App/Dashboard/DatabaseOverviewHeader.test.tsx +580 -0
  108. package/Tests/App/Dashboard/DatabaseRecommendationsEngineMetrics.test.ts +270 -0
  109. package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +1486 -0
  110. package/Tests/App/Dashboard/DatabaseServerEngineMetricsFilter.test.ts +223 -0
  111. package/Tests/App/Dashboard/DatabaseServerPresentation.test.ts +435 -0
  112. package/Tests/App/Dashboard/DatabaseServerSummary.test.ts +186 -0
  113. package/Tests/App/Dashboard/DatabaseServerTelemetryQueries.test.ts +1553 -0
  114. package/Tests/App/Dashboard/DatabaseTableTruncation.test.tsx +326 -0
  115. package/Tests/App/Dashboard/DatabaseTelemetryScope.test.ts +512 -0
  116. package/Tests/App/Dashboard/DatabaseTelemetryTabs.test.tsx +774 -0
  117. package/Tests/App/Dashboard/DatabaseViewLayout.test.tsx +233 -0
  118. package/Tests/App/Dashboard/DatabaseWorkloadBadge.test.tsx +972 -0
  119. package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +5 -0
  120. package/Tests/App/Dashboard/DiscoveryReviewUnnamedHostHint.test.tsx +1061 -0
  121. package/Tests/App/Dashboard/DiscoveryScanLivePage.test.tsx +39 -0
  122. package/Tests/App/Dashboard/DockerSwarmClustersListTooltips.test.tsx +414 -0
  123. package/Tests/App/Dashboard/DockerSwarmMetricTooltips.test.ts +796 -0
  124. package/Tests/App/Dashboard/DockerSwarmOverviewTooltips.test.tsx +747 -0
  125. package/Tests/App/Dashboard/EventOverlayScope.test.ts +147 -0
  126. package/Tests/App/Dashboard/EventOverlayScopeHook.test.tsx +1 -0
  127. package/Tests/App/Dashboard/ExceptionMonitorEnvironmentFilter.test.tsx +38 -18
  128. package/Tests/App/Dashboard/HostDetailViewTooltips.test.tsx +725 -0
  129. package/Tests/App/Dashboard/HostListColumnTooltips.test.tsx +472 -0
  130. package/Tests/App/Dashboard/HostMetricTooltips.test.ts +709 -0
  131. package/Tests/App/Dashboard/HostOverviewTooltips.test.tsx +698 -0
  132. package/Tests/App/Dashboard/HostTooltipHarness.ts +124 -0
  133. package/Tests/App/Dashboard/HostsListTooltips.test.tsx +395 -0
  134. package/Tests/App/Dashboard/IncidentAlertLinkDialog.test.tsx +691 -0
  135. package/Tests/App/Dashboard/IncidentAlertLinkHelpers.test.ts +458 -0
  136. package/Tests/App/Dashboard/IncidentAlertLinkPages.test.tsx +828 -0
  137. package/Tests/App/Dashboard/IncidentAlertLinkSideMenus.test.tsx +231 -0
  138. package/Tests/App/Dashboard/IncidentCreateFromAlerts.test.tsx +689 -0
  139. package/Tests/App/Dashboard/IoTMetricTooltips.test.tsx +1123 -0
  140. package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +837 -0
  141. package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +699 -0
  142. package/Tests/App/Dashboard/KubernetesContainersTabTooltips.test.tsx +320 -0
  143. package/Tests/App/Dashboard/KubernetesCostTooltips.test.tsx +502 -0
  144. package/Tests/App/Dashboard/KubernetesInsightsTooltips.test.tsx +222 -0
  145. package/Tests/App/Dashboard/KubernetesResourceMetricTooltips.test.ts +561 -0
  146. package/Tests/App/Dashboard/KubernetesResourcePagesTooltips.test.tsx +1168 -0
  147. package/Tests/App/Dashboard/LinkIncidentAlertModal.test.tsx +154 -0
  148. package/Tests/App/Dashboard/LogsResourceFacetChips.test.tsx +1 -0
  149. package/Tests/App/Dashboard/MetricDescriptionRules.ts +170 -0
  150. package/Tests/App/Dashboard/MetricDescriptionsCatalog.test.ts +206 -0
  151. package/Tests/App/Dashboard/MetricDescriptionsConsistency.test.ts +275 -0
  152. package/Tests/App/Dashboard/MetricsViewerDrillDown.test.tsx +310 -0
  153. package/Tests/App/Dashboard/MetricsViewerEntityScopedRows.test.tsx +495 -0
  154. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +132 -1
  155. package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +5 -0
  156. package/Tests/App/Dashboard/NetworkDeviceTooltips.test.tsx +852 -0
  157. package/Tests/App/Dashboard/NetworkDiagnosticsTooltips.test.tsx +556 -0
  158. package/Tests/App/Dashboard/NetworkMetricTooltips.test.ts +1348 -0
  159. package/Tests/App/Dashboard/NetworkSiteTooltips.test.tsx +679 -0
  160. package/Tests/App/Dashboard/ProductOrientation.test.tsx +4 -3
  161. package/Tests/App/Dashboard/ProxmoxMetricTooltips.test.ts +592 -0
  162. package/Tests/App/Dashboard/ProxmoxOverviewTooltips.test.tsx +1002 -0
  163. package/Tests/App/Dashboard/ProxmoxResourcePageTooltips.test.tsx +923 -0
  164. package/Tests/App/Dashboard/RecommendationsLoadedContext.test.tsx +349 -0
  165. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +62 -0
  166. package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
  167. package/Tests/App/Dashboard/ResourceFeedPagesFilterSort.test.tsx +14 -0
  168. package/Tests/App/Dashboard/ResourceOverviewTileTooltips.test.tsx +1066 -0
  169. package/Tests/App/Dashboard/RumOverviewPage.test.tsx +1195 -0
  170. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +2 -0
  171. package/Tests/App/Dashboard/ServerlessMetricTooltips.test.tsx +474 -0
  172. package/Tests/App/Dashboard/ServiceMapDatabaseLink.test.tsx +1085 -0
  173. package/Tests/App/Dashboard/ServiceMetricTooltips.test.tsx +772 -0
  174. package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +56 -1
  175. package/Tests/App/Dashboard/TelemetryMetricsSignals.test.ts +1207 -0
  176. package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +10 -0
  177. package/Tests/App/Dashboard/TelemetryResourceTabTooltips.test.tsx +437 -0
  178. package/Tests/App/Dashboard/TracesResourceFacets.test.tsx +2 -1
  179. package/Tests/App/Dashboard/VMwareMetricTooltips.test.ts +801 -0
  180. package/Tests/App/Dashboard/VMwareOverviewTooltips.test.tsx +601 -0
  181. package/Tests/App/Dashboard/VMwareResourcePagesTooltips.test.tsx +646 -0
  182. package/Tests/App/Dashboard/VMwareTooltipHarness.ts +145 -0
  183. package/Tests/App/StatusPage/StatusPageHeaderForeignHiddenRule.test.tsx +284 -0
  184. package/Tests/ClassStrings.ts +178 -0
  185. package/Tests/Fixtures/MobilePasskeyUser.json +1 -2
  186. package/Tests/ForeignHiddenRuleGuard.ts +2152 -0
  187. package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +2250 -0
  188. package/Tests/Models/DatabaseModels/IncidentAlertModel.test.ts +554 -0
  189. package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +24 -5
  190. package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +117 -0
  191. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
  192. package/Tests/RenderedMarkup.ts +518 -0
  193. package/Tests/ResponsiveVisibility.test.ts +490 -4
  194. package/Tests/ResponsiveVisibility.ts +505 -52
  195. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
  196. package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +541 -0
  197. package/Tests/Server/Infrastructure/Postgres/AddIncidentAlertMigration.test.ts +341 -0
  198. package/Tests/Server/Infrastructure/Postgres/AddSessionReplaySameOriginTracePropagationMigration.test.ts +247 -0
  199. package/Tests/Server/Infrastructure/Postgres/AddUserProjectSsoConsentMigration.test.ts +234 -0
  200. package/Tests/Server/Services/ContainerSnapshotUpsertPostgres.test.ts +319 -0
  201. package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +13 -0
  202. package/Tests/Server/Services/DatabaseServerEndpointService.test.ts +2033 -0
  203. package/Tests/Server/Services/DatabaseServerFeedAndOwnerServices.test.ts +529 -0
  204. package/Tests/Server/Services/DatabaseServerLifecycle.test.ts +3302 -0
  205. package/Tests/Server/Services/DatabaseServerRegistries.test.ts +603 -0
  206. package/Tests/Server/Services/DatabaseServerRuleEngines.test.ts +754 -0
  207. package/Tests/Server/Services/DatabaseServerService.test.ts +3558 -0
  208. package/Tests/Server/Services/DatabaseServerSqlPostgres.test.ts +2045 -0
  209. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedPostgres.test.ts +362 -0
  210. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedReply.test.ts +210 -0
  211. package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +18 -0
  212. package/Tests/Server/Services/IncidentAlertPostgres.test.ts +903 -0
  213. package/Tests/Server/Services/IncidentAlertRegistration.test.ts +96 -0
  214. package/Tests/Server/Services/IncidentAlertService.test.ts +2225 -0
  215. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +2 -0
  216. package/Tests/Server/Services/IncidentAlertStateCascade.test.ts +970 -0
  217. package/Tests/Server/Services/IncidentCreateFromAlerts.test.ts +1284 -0
  218. package/Tests/Server/Services/IncomingCallPolicyEscalationRuleTarget.test.ts +225 -0
  219. package/Tests/Server/Services/InventoryItemDisplayName.test.ts +280 -2
  220. package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +8 -2
  221. package/Tests/Server/Services/IoTDeviceLatestMetricsPostgres.test.ts +689 -0
  222. package/Tests/Server/Services/IoTDeviceService.test.ts +379 -0
  223. package/Tests/Server/Services/LatestMetricsValuesShape.test.ts +360 -0
  224. package/Tests/Server/Services/LlmModelPriceService.test.ts +402 -0
  225. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +7 -1
  226. package/Tests/Server/Services/OwnerRowUniqueness.test.ts +61 -9
  227. package/Tests/Server/Services/ReminderRuleLookupPostgres.test.ts +2250 -0
  228. package/Tests/Server/Services/ReminderRuleRefreshOpenSubjectsPaging.test.ts +653 -0
  229. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +68 -20
  230. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +3 -3
  231. package/Tests/Server/Services/TelemetryResourceFacetCounting.test.ts +9 -0
  232. package/Tests/Server/Services/UserProjectSsoConsentPostgres.test.ts +153 -0
  233. package/Tests/Server/Services/UserProjectSsoConsentService.test.ts +192 -0
  234. package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +71 -0
  235. package/Tests/Server/Services/UserSignupIdTakeoverPostgres.test.ts +238 -0
  236. package/Tests/Server/Services/WorkspaceNotificationSummaryHelpers.test.ts +592 -0
  237. package/Tests/Server/Types/Billing/PayAsYouGoMeteredAuthorization.test.ts +3 -0
  238. package/Tests/Server/Types/Database/EventOverlayScopePostgres.test.ts +1 -0
  239. package/Tests/Server/Types/Database/FeedEventTypeFilterQuery.test.ts +11 -0
  240. package/Tests/Server/Types/Database/Permissions/InfrastructureOwnershipScope.test.ts +8 -0
  241. package/Tests/Server/Types/Database/QueryHelperBooleanForCriteriaBackedRule.test.ts +1094 -0
  242. package/Tests/Server/Utils/AI/ResourceTools.test.ts +134 -0
  243. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +41 -0
  244. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +279 -9
  245. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaDisplayContext.test.ts +933 -0
  246. package/Tests/Server/Utils/Monitor/DatabaseMaintenanceSuppression.test.ts +582 -0
  247. package/Tests/Server/Utils/Monitor/DatabaseServerMonitorLinking.test.ts +753 -0
  248. package/Tests/Server/Utils/Monitor/MonitorActionTimestamps.test.ts +1 -0
  249. package/Tests/Server/Utils/Monitor/MonitorAlertCriteriaReferences.test.ts +1 -0
  250. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +119 -0
  251. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +60 -25
  252. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorAffectedResourceEdgeCases.test.ts +1719 -0
  253. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesAffectedResources.test.ts +1447 -0
  254. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesRatioEmail.test.ts +352 -0
  255. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformMetricUnits.test.ts +717 -0
  256. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformRawScan.test.ts +2125 -0
  257. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformSeriesAffectedResources.test.ts +1288 -0
  258. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +1 -0
  259. package/Tests/Server/Utils/Monitor/MonitorIncidentCriteriaReferences.test.ts +1 -0
  260. package/Tests/Server/Utils/Monitor/MonitorIncidentMemberRoleMembership.test.ts +1 -0
  261. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +88 -0
  262. package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +205 -0
  263. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +62 -0
  264. package/Tests/Server/Utils/Monitor/MonitorResourceDatabaseMaintenance.test.ts +803 -0
  265. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +133 -3
  266. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +1 -0
  267. package/Tests/Server/Utils/Monitor/PerSeriesRecoveryResolution.test.ts +472 -1
  268. package/Tests/Server/Utils/Monitor/PerSeriesSecondEntityAlerting.test.ts +1 -0
  269. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +236 -2
  270. package/Tests/Server/Utils/SeriesResourceLabels.test.ts +70 -0
  271. package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +103 -0
  272. package/Tests/Server/Utils/StartServerProtobufContentType.test.ts +54 -0
  273. package/Tests/Server/Utils/Telemetry/DatabaseEndpointDiscovery.test.ts +1895 -0
  274. package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +7 -0
  275. package/Tests/Server/Utils/Telemetry/LogExceptionExtractorSeverityGate.test.ts +90 -0
  276. package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +570 -0
  277. package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +97 -2
  278. package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +1337 -0
  279. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +295 -0
  280. package/Tests/Types/AI/AIResourceContext.test.ts +30 -0
  281. package/Tests/Types/DatabaseServer/DatabaseContainerClassifier.test.ts +3644 -0
  282. package/Tests/Types/DatabaseServer/DatabaseContainerCommand.test.ts +340 -0
  283. package/Tests/Types/DatabaseServer/DatabaseContainerCommandCorpus.ts +826 -0
  284. package/Tests/Types/DatabaseServer/DatabaseContainerCommandPostgres.test.ts +150 -0
  285. package/Tests/Types/DatabaseServer/DatabaseEndpoint.test.ts +2657 -0
  286. package/Tests/Types/DatabaseServer/DatabaseServerDiscoverySource.test.ts +64 -0
  287. package/Tests/Types/DatabaseServer/DatabaseServerEntityKeys.test.ts +952 -0
  288. package/Tests/Types/DatabaseServer/DatabaseServerMetricCatalog.test.ts +1161 -0
  289. package/Tests/Types/DatabaseServer/DatabaseSystem.test.ts +1514 -0
  290. package/Tests/Types/DatabaseServer/DatabaseTelemetryResolver.test.ts +1558 -0
  291. package/Tests/Types/Monitor/CephAlertTemplates.test.ts +255 -6
  292. package/Tests/Types/Monitor/DatabaseAlertTemplates.test.ts +2254 -0
  293. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +298 -0
  294. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +271 -0
  295. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +253 -9
  296. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +13 -5
  297. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +4 -2
  298. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +111 -2
  299. package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +61 -0
  300. package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +114 -0
  301. package/Tests/Types/Monitor/Utils/KubernetesAgentEmittedMetrics.ts +181 -0
  302. package/Tests/Types/NetworkDevice/DiscoveredHostNamingStatus.test.ts +401 -0
  303. package/Tests/Types/Rum/WebVitals.test.ts +173 -0
  304. package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +4 -1
  305. package/Tests/Types/Telemetry/ResourceFacetCatalog.test.ts +24 -2
  306. package/Tests/UI/Components/Card.test.tsx +93 -2
  307. package/Tests/UI/Components/FeedOptions.test.ts +6 -0
  308. package/Tests/UI/Components/FeedOptionsButton.test.tsx +8 -1
  309. package/Tests/UI/Components/FieldLabelInfoCardTooltip.test.tsx +413 -0
  310. package/Tests/UI/Components/ForeignHiddenRuleResilience.test.tsx +1147 -0
  311. package/Tests/UI/Components/HeaderRightRail.test.tsx +41 -1
  312. package/Tests/UI/Components/InfoTooltip.test.tsx +242 -0
  313. package/Tests/UI/Components/LogsEntityNames.test.ts +16 -1
  314. package/Tests/UI/Components/LogsFacetSidebarHiddenFacets.test.tsx +7 -3
  315. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +207 -3
  316. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDeleteVerb.test.tsx +367 -0
  317. package/Tests/UI/Components/ModelTable/BaseModelTableCreateButtonTitle.test.tsx +275 -0
  318. package/Tests/UI/Components/ResourceFacetConfigs.test.ts +2 -1
  319. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  320. package/Tests/UI/Components/SrOnlyForeignRule.test.tsx +994 -0
  321. package/Tests/UI/Components/StatusPage/ResourceListSelection.test.tsx +34 -1
  322. package/Tests/UI/Components/TableHeaderTooltip.test.tsx +662 -0
  323. package/Tests/UI/Components/TelemetryFacetSidebarHiddenFacets.test.tsx +4 -1
  324. package/Tests/UI/ForeignHiddenRuleGuard.test.ts +1951 -0
  325. package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +166 -9
  326. package/Tests/UI/Rum/RecordingHealthTooltips.test.tsx +447 -0
  327. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +164 -0
  328. package/Tests/UI/Rum/ReplayFrameCapture.test.ts +6750 -0
  329. package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +19 -1
  330. package/Tests/UI/Rum/ReplayRail.test.tsx +723 -12
  331. package/Tests/UI/Rum/ReplayRailDetail.test.tsx +86 -0
  332. package/Tests/UI/Rum/ReplayScreenshot.test.ts +2124 -0
  333. package/Tests/UI/Rum/ReplayScreenshotActions.test.tsx +3288 -0
  334. package/Tests/UI/Rum/ReplayStage.test.tsx +62 -0
  335. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +983 -2
  336. package/Tests/UI/Rum/ReplayTabSwitcher.test.tsx +19 -1
  337. package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +149 -0
  338. package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +107 -6
  339. package/Tests/UI/Rum/SessionReplayUsersTableTooltips.test.tsx +330 -0
  340. package/Tests/UI/Rum/UserFlowTooltips.test.tsx +886 -0
  341. package/Tests/UI/TailwindPlayCdnForeignHiddenRule.test.ts +1005 -0
  342. package/Tests/UI/ThemeGroupHoverReveal.test.ts +847 -0
  343. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +80 -0
  344. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +23 -0
  345. package/Tests/UI/Utils/ModelAPISsoRedirect.test.ts +127 -0
  346. package/Tests/UI/Utils/Navigation.test.ts +102 -0
  347. package/Tests/UI/Utils/PermissionGate.test.ts +76 -0
  348. package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +23 -0
  349. package/Tests/Utils/Incident/IncidentFromAlerts.test.ts +696 -0
  350. package/Tests/Utils/LabelRuleImportExport.test.ts +5 -0
  351. package/Tests/Utils/MetricUnitUtil.test.ts +227 -2
  352. package/Tests/Utils/Monitor/MetricValueFormatter.test.ts +288 -2
  353. package/Tests/Utils/Monitor/PlatformResourceIdentityAndUnits.test.ts +1559 -0
  354. package/Tests/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.test.ts +2546 -0
  355. package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +315 -0
  356. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +336 -1
  357. package/Tests/Utils/NetworkDiscovery/NetbiosNameUtil.test.ts +244 -0
  358. package/Tests/Utils/Rum/SessionTraceState.test.ts +239 -0
  359. package/Tests/Utils/ValueFormatter.test.ts +50 -0
  360. package/Tests/tsconfig.json +16 -0
  361. package/Types/AI/AIResourceContext.ts +7 -0
  362. package/Types/Dashboard/DashboardTemplates.ts +2 -1
  363. package/Types/DatabaseServer/DatabaseConnectionSpan.ts +77 -0
  364. package/Types/DatabaseServer/DatabaseContainerClassifier.ts +2068 -0
  365. package/Types/DatabaseServer/DatabaseContainerCommand.ts +801 -0
  366. package/Types/DatabaseServer/DatabaseEndpoint.ts +1943 -0
  367. package/Types/DatabaseServer/DatabaseServerDiscoverySource.ts +68 -0
  368. package/Types/DatabaseServer/DatabaseServerMetricCatalog.ts +966 -0
  369. package/Types/DatabaseServer/DatabaseSystem.ts +2124 -0
  370. package/Types/DatabaseServer/DatabaseTelemetryResolver.ts +555 -0
  371. package/Types/Email/EmailTemplateType.ts +1 -0
  372. package/Types/Incident/IncidentAlertLink.ts +38 -0
  373. package/Types/Monitor/CephAlertTemplates.ts +18 -0
  374. package/Types/Monitor/DatabaseAlertTemplates.ts +2020 -0
  375. package/Types/Monitor/KubernetesAlertTemplates.ts +64 -24
  376. package/Types/Monitor/KubernetesMetricCatalog.ts +118 -19
  377. package/Types/Monitor/MetricMonitor/MetricCriteriaContext.ts +14 -0
  378. package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +93 -10
  379. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +109 -8
  380. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +36 -7
  381. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +43 -2
  382. package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +41 -6
  383. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +26 -0
  384. package/Types/NetworkDevice/DiscoveredHostNamingStatus.ts +147 -0
  385. package/Types/Permission.ts +315 -0
  386. package/Types/Probe/ProbeApiIngestResponse.ts +8 -0
  387. package/Types/Rules/RuleCriteriaFieldRegistry.ts +10 -0
  388. package/Types/Rules/RuleRun.ts +12 -0
  389. package/Types/Rum/SessionReplay.ts +25 -6
  390. package/Types/Rum/WebVitals.ts +52 -0
  391. package/Types/Telemetry/EntityType.ts +23 -0
  392. package/Types/Telemetry/ResourceFacetCatalog.ts +14 -0
  393. package/Types/Telemetry/ServiceType.ts +8 -0
  394. package/UI/Components/Banner/Banner.tsx +1 -1
  395. package/UI/Components/Card/Card.tsx +1 -1
  396. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +2 -2
  397. package/UI/Components/Charts/Line/LineChart.tsx +7 -0
  398. package/UI/Components/CommandPalette/CommandPalette.tsx +1 -1
  399. package/UI/Components/Date/StartAndEndDate.tsx +5 -5
  400. package/UI/Components/Detail/FieldLabel.tsx +8 -0
  401. package/UI/Components/Diagram/HorizontalStepChain.tsx +1 -1
  402. package/UI/Components/Feed/FeedOptionsButton.tsx +1 -1
  403. package/UI/Components/Forms/BasicForm.tsx +1 -1
  404. package/UI/Components/Header/Header.tsx +1 -1
  405. package/UI/Components/Header/HeaderIconDropdownButton.tsx +1 -1
  406. package/UI/Components/HeaderAlert/HeaderAlert.tsx +1 -1
  407. package/UI/Components/InfoCard/InfoCard.tsx +47 -1
  408. package/UI/Components/LogsViewer/components/FacetValueRow.tsx +1 -1
  409. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +1 -1
  410. package/UI/Components/Modal/ModalFooter.tsx +1 -1
  411. package/UI/Components/ModelDetail/CardModelDetail.tsx +2 -2
  412. package/UI/Components/ModelTable/BaseModelTable.tsx +99 -21
  413. package/UI/Components/ModelTable/Column.ts +5 -0
  414. package/UI/Components/Navbar/NavBar.tsx +9 -2
  415. package/UI/Components/Navbar/NavBarMenuModal.tsx +2 -2
  416. package/UI/Components/Page/Page.tsx +1 -1
  417. package/UI/Components/Pagination/Pagination.tsx +3 -3
  418. package/UI/Components/ProgressButtons/ProgressButtonItem.tsx +1 -1
  419. package/UI/Components/SideMenu/SideMenu.tsx +4 -1
  420. package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +4 -2
  421. package/UI/Components/StatusPage/ResourceList.tsx +6 -6
  422. package/UI/Components/Table/TableHeader.tsx +47 -2
  423. package/UI/Components/Table/Types/Column.ts +7 -0
  424. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +1 -1
  425. package/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.tsx +1 -1
  426. package/UI/Components/Tooltip/InfoTooltip.tsx +78 -0
  427. package/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.tsx +1 -1
  428. package/UI/Components/Workflow/ComponentsModal.tsx +2 -2
  429. package/UI/Components/Workflow/StepTraceViewer.tsx +1 -1
  430. package/UI/Styles/Theme.css +8 -1
  431. package/UI/Utils/Navigation.ts +89 -42
  432. package/UI/Utils/PermissionGate.ts +11 -2
  433. package/UI/Utils/Telemetry/TelemetryEntityNames.ts +7 -0
  434. package/UI/Utils/TelemetryService.ts +4 -3
  435. package/Utils/Incident/IncidentFromAlerts.ts +516 -0
  436. package/Utils/LabelRuleImportExport.ts +2 -0
  437. package/Utils/MetricUnitUtil.ts +103 -11
  438. package/Utils/Monitor/MetricValueFormatter.ts +66 -13
  439. package/Utils/Monitor/PlatformMetricUnitUtil.ts +215 -0
  440. package/Utils/Monitor/PlatformResourceIdentity.ts +514 -0
  441. package/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.ts +425 -0
  442. package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +32 -0
  443. package/Utils/NetworkDiscovery/NetbiosNameUtil.ts +73 -0
  444. package/Utils/Rum/SessionTraceState.ts +212 -0
  445. package/Utils/Telemetry/DatabaseServerEntityKeys.ts +275 -0
  446. package/Utils/Telemetry/EntityKey.ts +176 -0
  447. package/Utils/ValueFormatter.ts +16 -0
  448. package/build/dist/Models/DatabaseModels/Alert.js +54 -0
  449. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  450. package/build/dist/Models/DatabaseModels/AlertFeed.js +2 -0
  451. package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
  452. package/build/dist/Models/DatabaseModels/DatabaseServer.js +1683 -0
  453. package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -0
  454. package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js +559 -0
  455. package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js.map +1 -0
  456. package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js +648 -0
  457. package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js.map +1 -0
  458. package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js +522 -0
  459. package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js.map +1 -0
  460. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js +603 -0
  461. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js.map +1 -0
  462. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js +506 -0
  463. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js.map +1 -0
  464. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js +505 -0
  465. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js.map +1 -0
  466. package/build/dist/Models/DatabaseModels/Incident.js +54 -0
  467. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  468. package/build/dist/Models/DatabaseModels/IncidentAlert.js +553 -0
  469. package/build/dist/Models/DatabaseModels/IncidentAlert.js.map +1 -0
  470. package/build/dist/Models/DatabaseModels/IncidentFeed.js +2 -0
  471. package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
  472. package/build/dist/Models/DatabaseModels/Index.js +18 -0
  473. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  474. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  475. package/build/dist/Models/DatabaseModels/Project.js +62 -0
  476. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  477. package/build/dist/Models/DatabaseModels/RumApplication.js +53 -1
  478. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  479. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +54 -0
  480. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  481. package/build/dist/Models/DatabaseModels/TelemetryException.js +2 -0
  482. package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
  483. package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js +162 -0
  484. package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js.map +1 -0
  485. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js +20 -0
  486. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js.map +1 -0
  487. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js +42 -0
  488. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js.map +1 -0
  489. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js +240 -0
  490. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js.map +1 -0
  491. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js +26 -0
  492. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js.map +1 -0
  493. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  494. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  495. package/build/dist/Server/Middleware/MultipartFormData.js +1 -1
  496. package/build/dist/Server/Middleware/TelemetryIngest.js +15 -8
  497. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  498. package/build/dist/Server/Services/AlertReminderRuleService.js +72 -23
  499. package/build/dist/Server/Services/AlertReminderRuleService.js.map +1 -1
  500. package/build/dist/Server/Services/DatabaseServerEndpointService.js +694 -0
  501. package/build/dist/Server/Services/DatabaseServerEndpointService.js.map +1 -0
  502. package/build/dist/Server/Services/DatabaseServerFeedService.js +110 -0
  503. package/build/dist/Server/Services/DatabaseServerFeedService.js.map +1 -0
  504. package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js +272 -0
  505. package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js.map +1 -0
  506. package/build/dist/Server/Services/DatabaseServerLabelRuleService.js +13 -0
  507. package/build/dist/Server/Services/DatabaseServerLabelRuleService.js.map +1 -0
  508. package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js +340 -0
  509. package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js.map +1 -0
  510. package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js +13 -0
  511. package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js.map +1 -0
  512. package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js +160 -0
  513. package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js.map +1 -0
  514. package/build/dist/Server/Services/DatabaseServerOwnerUserService.js +153 -0
  515. package/build/dist/Server/Services/DatabaseServerOwnerUserService.js.map +1 -0
  516. package/build/dist/Server/Services/DatabaseServerService.js +3272 -0
  517. package/build/dist/Server/Services/DatabaseServerService.js.map +1 -0
  518. package/build/dist/Server/Services/DatabaseService.js +8 -4
  519. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  520. package/build/dist/Server/Services/DockerResourceService.js +30 -3
  521. package/build/dist/Server/Services/DockerResourceService.js.map +1 -1
  522. package/build/dist/Server/Services/IncidentAlertService.js +1370 -0
  523. package/build/dist/Server/Services/IncidentAlertService.js.map +1 -0
  524. package/build/dist/Server/Services/IncidentReminderRuleService.js +73 -23
  525. package/build/dist/Server/Services/IncidentReminderRuleService.js.map +1 -1
  526. package/build/dist/Server/Services/IncidentService.js +164 -12
  527. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  528. package/build/dist/Server/Services/IncidentStateTimelineService.js +21 -0
  529. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  530. package/build/dist/Server/Services/Index.js +18 -0
  531. package/build/dist/Server/Services/Index.js.map +1 -1
  532. package/build/dist/Server/Services/InventoryItemService.js +88 -5
  533. package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
  534. package/build/dist/Server/Services/IoTDeviceService.js +111 -24
  535. package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
  536. package/build/dist/Server/Services/OpenTelemetryIngestService.js +24 -9
  537. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  538. package/build/dist/Server/Services/PodmanResourceService.js +30 -3
  539. package/build/dist/Server/Services/PodmanResourceService.js.map +1 -1
  540. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js +75 -23
  541. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js.map +1 -1
  542. package/build/dist/Server/Services/ServiceService.js +1 -1
  543. package/build/dist/Server/Services/ServiceService.js.map +1 -1
  544. package/build/dist/Server/Services/TelemetryUsageBillingService.js +23 -2
  545. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  546. package/build/dist/Server/Services/UserProjectSsoConsentService.js +79 -0
  547. package/build/dist/Server/Services/UserProjectSsoConsentService.js.map +1 -0
  548. package/build/dist/Server/Services/UserService.js +13 -1
  549. package/build/dist/Server/Services/UserService.js.map +1 -1
  550. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +18 -0
  551. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  552. package/build/dist/Server/Types/Database/QueryHelper.js +26 -1
  553. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  554. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js +46 -0
  555. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js.map +1 -1
  556. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js +6 -0
  557. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js.map +1 -1
  558. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +134 -13
  559. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js.map +1 -1
  560. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +22 -6
  561. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  562. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +1489 -524
  563. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  564. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
  565. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  566. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +196 -6
  567. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
  568. package/build/dist/Server/Utils/Monitor/MonitorResource.js +36 -9
  569. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  570. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +1 -0
  571. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -1
  572. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +175 -17
  573. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -1
  574. package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js +29 -0
  575. package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js.map +1 -0
  576. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +211 -0
  577. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
  578. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +82 -10
  579. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  580. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +25 -0
  581. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
  582. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +8 -0
  583. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
  584. package/build/dist/Server/Utils/StartServer.js +20 -4
  585. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  586. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +2 -0
  587. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -1
  588. package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js +442 -0
  589. package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js.map +1 -0
  590. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +5 -1
  591. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  592. package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js +15 -1
  593. package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js.map +1 -1
  594. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +121 -5
  595. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
  596. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +12 -0
  597. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
  598. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js +438 -36
  599. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js.map +1 -1
  600. package/build/dist/Server/Utils/Telemetry/Telemetry.js +12 -0
  601. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  602. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +17 -18
  603. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  604. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +16 -10
  605. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -1
  606. package/build/dist/Types/AI/AIResourceContext.js +7 -0
  607. package/build/dist/Types/AI/AIResourceContext.js.map +1 -1
  608. package/build/dist/Types/Dashboard/DashboardTemplates.js +2 -1
  609. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  610. package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js +71 -0
  611. package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js.map +1 -0
  612. package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js +1462 -0
  613. package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js.map +1 -0
  614. package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js +691 -0
  615. package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js.map +1 -0
  616. package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js +1407 -0
  617. package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js.map +1 -0
  618. package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js +60 -0
  619. package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js.map +1 -0
  620. package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js +804 -0
  621. package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js.map +1 -0
  622. package/build/dist/Types/DatabaseServer/DatabaseSystem.js +1860 -0
  623. package/build/dist/Types/DatabaseServer/DatabaseSystem.js.map +1 -0
  624. package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js +406 -0
  625. package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js.map +1 -0
  626. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  627. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  628. package/build/dist/Types/Incident/IncidentAlertLink.js +34 -0
  629. package/build/dist/Types/Incident/IncidentAlertLink.js.map +1 -0
  630. package/build/dist/Types/Monitor/CephAlertTemplates.js +18 -0
  631. package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
  632. package/build/dist/Types/Monitor/DatabaseAlertTemplates.js +1518 -0
  633. package/build/dist/Types/Monitor/DatabaseAlertTemplates.js.map +1 -0
  634. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +57 -24
  635. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  636. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +104 -18
  637. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
  638. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +80 -3
  639. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  640. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +10 -3
  641. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  642. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +29 -0
  643. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  644. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +21 -6
  645. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -1
  646. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +25 -0
  647. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -1
  648. package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js +136 -0
  649. package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js.map +1 -0
  650. package/build/dist/Types/Permission.js +276 -0
  651. package/build/dist/Types/Permission.js.map +1 -1
  652. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +10 -0
  653. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  654. package/build/dist/Types/Rules/RuleRun.js +4 -0
  655. package/build/dist/Types/Rules/RuleRun.js.map +1 -1
  656. package/build/dist/Types/Rum/WebVitals.js +25 -0
  657. package/build/dist/Types/Rum/WebVitals.js.map +1 -1
  658. package/build/dist/Types/Telemetry/EntityType.js +23 -0
  659. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  660. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js +14 -0
  661. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js.map +1 -1
  662. package/build/dist/Types/Telemetry/ServiceType.js +8 -0
  663. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  664. package/build/dist/UI/Components/Banner/Banner.js +1 -1
  665. package/build/dist/UI/Components/Banner/Banner.js.map +1 -1
  666. package/build/dist/UI/Components/Card/Card.js +1 -1
  667. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  668. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +2 -2
  669. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  670. package/build/dist/UI/Components/Charts/Line/LineChart.js +1 -1
  671. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  672. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +1 -1
  673. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
  674. package/build/dist/UI/Components/Date/StartAndEndDate.js +5 -5
  675. package/build/dist/UI/Components/Date/StartAndEndDate.js.map +1 -1
  676. package/build/dist/UI/Components/Detail/FieldLabel.js +2 -0
  677. package/build/dist/UI/Components/Detail/FieldLabel.js.map +1 -1
  678. package/build/dist/UI/Components/Diagram/HorizontalStepChain.js +1 -1
  679. package/build/dist/UI/Components/Diagram/HorizontalStepChain.js.map +1 -1
  680. package/build/dist/UI/Components/Feed/FeedOptionsButton.js +1 -1
  681. package/build/dist/UI/Components/Feed/FeedOptionsButton.js.map +1 -1
  682. package/build/dist/UI/Components/Forms/BasicForm.js +1 -1
  683. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  684. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +1 -1
  685. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
  686. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js +1 -1
  687. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js.map +1 -1
  688. package/build/dist/UI/Components/InfoCard/InfoCard.js +22 -1
  689. package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
  690. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js +1 -1
  691. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js.map +1 -1
  692. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +1 -1
  693. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  694. package/build/dist/UI/Components/Modal/ModalFooter.js +1 -1
  695. package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
  696. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +2 -2
  697. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  698. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +70 -18
  699. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  700. package/build/dist/UI/Components/Navbar/NavBar.js +9 -2
  701. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  702. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +2 -2
  703. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  704. package/build/dist/UI/Components/Page/Page.js +1 -1
  705. package/build/dist/UI/Components/Page/Page.js.map +1 -1
  706. package/build/dist/UI/Components/Pagination/Pagination.js +3 -3
  707. package/build/dist/UI/Components/Pagination/Pagination.js.map +1 -1
  708. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js +1 -1
  709. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js.map +1 -1
  710. package/build/dist/UI/Components/SideMenu/SideMenu.js +4 -1
  711. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  712. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +3 -1
  713. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -1
  714. package/build/dist/UI/Components/StatusPage/ResourceList.js +6 -6
  715. package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -1
  716. package/build/dist/UI/Components/Table/TableHeader.js +18 -2
  717. package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
  718. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +1 -1
  719. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  720. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js +1 -1
  721. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js.map +1 -1
  722. package/build/dist/UI/Components/Tooltip/InfoTooltip.js +28 -0
  723. package/build/dist/UI/Components/Tooltip/InfoTooltip.js.map +1 -0
  724. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js +1 -1
  725. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js.map +1 -1
  726. package/build/dist/UI/Components/Workflow/ComponentsModal.js +2 -2
  727. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  728. package/build/dist/UI/Components/Workflow/StepTraceViewer.js +1 -1
  729. package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -1
  730. package/build/dist/UI/Utils/Navigation.js +66 -33
  731. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  732. package/build/dist/UI/Utils/PermissionGate.js +4 -2
  733. package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
  734. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +7 -0
  735. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -1
  736. package/build/dist/UI/Utils/TelemetryService.js +3 -2
  737. package/build/dist/UI/Utils/TelemetryService.js.map +1 -1
  738. package/build/dist/Utils/Incident/IncidentFromAlerts.js +306 -0
  739. package/build/dist/Utils/Incident/IncidentFromAlerts.js.map +1 -0
  740. package/build/dist/Utils/LabelRuleImportExport.js +2 -0
  741. package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
  742. package/build/dist/Utils/MetricUnitUtil.js +77 -13
  743. package/build/dist/Utils/MetricUnitUtil.js.map +1 -1
  744. package/build/dist/Utils/Monitor/MetricValueFormatter.js +58 -13
  745. package/build/dist/Utils/Monitor/MetricValueFormatter.js.map +1 -1
  746. package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js +161 -0
  747. package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js.map +1 -0
  748. package/build/dist/Utils/Monitor/PlatformResourceIdentity.js +323 -0
  749. package/build/dist/Utils/Monitor/PlatformResourceIdentity.js.map +1 -0
  750. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js +270 -0
  751. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js.map +1 -0
  752. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +23 -0
  753. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -1
  754. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js +61 -0
  755. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js.map +1 -1
  756. package/build/dist/Utils/Rum/SessionTraceState.js +154 -0
  757. package/build/dist/Utils/Rum/SessionTraceState.js.map +1 -0
  758. package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js +178 -0
  759. package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js.map +1 -0
  760. package/build/dist/Utils/Telemetry/EntityKey.js +133 -0
  761. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  762. package/build/dist/Utils/ValueFormatter.js +15 -0
  763. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  764. package/package.json +1 -1
  765. package/tsconfig.tests.json +7 -5
@@ -0,0 +1,1147 @@
1
+ import "@testing-library/jest-dom";
2
+ import {
3
+ afterEach,
4
+ beforeAll,
5
+ beforeEach,
6
+ describe,
7
+ expect,
8
+ jest,
9
+ test,
10
+ } from "@jest/globals";
11
+ import {
12
+ cleanup,
13
+ fireEvent,
14
+ render,
15
+ screen,
16
+ waitFor,
17
+ } from "@testing-library/react";
18
+ import React from "react";
19
+ import { Location } from "react-router-dom";
20
+ import getJestMockFunction from "../../MockType";
21
+ import {
22
+ LAPTOP_WIDTH_IN_PX,
23
+ PHONE_WIDTH_IN_PX,
24
+ TABLET_WIDTH_IN_PX,
25
+ TAILWIND_BREAKPOINTS_IN_PX,
26
+ VisibilityOptions,
27
+ WIDE_DESKTOP_WIDTH_IN_PX,
28
+ describeVisibility,
29
+ resolveDisplay,
30
+ } from "../../ResponsiveVisibility";
31
+
32
+ /*
33
+ * The shared components under a foreign `.hidden` rule.
34
+ *
35
+ * A customer's dashboard showed no navigation bar at all — no Home, no
36
+ * Products — so an invited user could not reach a single product. Their
37
+ * browser carried `.hidden { display: none !important }`, a rule Bootstrap 3
38
+ * and HTML5 Boilerplate ship verbatim and that extensions and user stylesheets
39
+ * inject into every page they touch. Our markup hid desktop-only chrome with
40
+ * `hidden md:flex`: the bare `hidden` class is exactly what that rule matches,
41
+ * and `!important` (or merely being appended after Tailwind's <style>) beats
42
+ * `md:flex`, so the element vanished at every width, not just below md.
43
+ *
44
+ * The fix spells the phone half as `max-md:hidden md:flex`: identical on a
45
+ * clean page, and the element no longer carries the class the foreign rule
46
+ * targets. This file renders the real shared components the fix touched and
47
+ * checks, per component:
48
+ *
49
+ * - the desktop-only part is on screen at and above its breakpoint, on a
50
+ * clean page and with the foreign rule;
51
+ * - it is still off screen below the breakpoint, either way — the fix must
52
+ * not turn a phone layout into a desktop one;
53
+ * - a control: the component's pre-fix class string, rebuilt from the
54
+ * rendered markup and compared with the literal from the diff, is visible on
55
+ * a clean page and gone under the rule. That is the bug, written down, and
56
+ * it is what these assertions would have caught.
57
+ *
58
+ * jsdom has no stylesheet, so ResponsiveVisibility reads the class attributes
59
+ * and resolves `display` per width the way the Tailwind cascade does, and its
60
+ * `withForeignHiddenRule` option models the rule on the page.
61
+ */
62
+
63
+ /*
64
+ * CardModelDetail and BaseModelTable check permissions, read the current user
65
+ * and load their rows. None of that is what this file is about: the stubs
66
+ * below let both render their header buttons and nothing more.
67
+ */
68
+ jest.mock("../../../UI/Utils/Permission", () => {
69
+ return {
70
+ __esModule: true,
71
+ default: {
72
+ getAllPermissions: (): Array<unknown> => {
73
+ return ["ProjectAdmin"];
74
+ },
75
+ getProjectPermissions: (): null => {
76
+ return null;
77
+ },
78
+ getGlobalPermissions: (): null => {
79
+ return null;
80
+ },
81
+ },
82
+ };
83
+ });
84
+
85
+ jest.mock("../../../UI/Utils/User", () => {
86
+ return {
87
+ __esModule: true,
88
+ default: {
89
+ isMasterAdmin: (): boolean => {
90
+ return false;
91
+ },
92
+ getUserId: (): null => {
93
+ return null;
94
+ },
95
+ },
96
+ };
97
+ });
98
+
99
+ // Assertions read as the English words on screen.
100
+ jest.mock("../../../UI/Utils/Translation", () => {
101
+ return {
102
+ __esModule: true,
103
+ default: () => {
104
+ return {
105
+ translateString: (value: string | undefined): string | undefined => {
106
+ return value;
107
+ },
108
+ translateValue: (value: unknown): unknown => {
109
+ return value;
110
+ },
111
+ };
112
+ },
113
+ };
114
+ });
115
+
116
+ jest.mock("../../../UI/Utils/ModelAPI/ModelAPI", () => {
117
+ return {
118
+ __esModule: true,
119
+ default: {
120
+ getItem: async (): Promise<null> => {
121
+ return null;
122
+ },
123
+ getList: async (): Promise<{
124
+ data: Array<unknown>;
125
+ count: number;
126
+ skip: number;
127
+ limit: number;
128
+ }> => {
129
+ return { data: [], count: 0, skip: 0, limit: 10 };
130
+ },
131
+ },
132
+ };
133
+ });
134
+
135
+ import Banner from "../../../UI/Components/Banner/Banner";
136
+ import Card from "../../../UI/Components/Card/Card";
137
+ import HeaderIconDropdownButton from "../../../UI/Components/Header/HeaderIconDropdownButton";
138
+ import KeyboardKey from "../../../UI/Components/KeyboardShortcut/KeyboardKey";
139
+ import ModalFooter from "../../../UI/Components/Modal/ModalFooter";
140
+ import CardModelDetail from "../../../UI/Components/ModelDetail/CardModelDetail";
141
+ import BaseModelTable, {
142
+ BaseTableCallbacks,
143
+ ComponentProps as BaseModelTableProps,
144
+ } from "../../../UI/Components/ModelTable/BaseModelTable";
145
+ import Navbar, {
146
+ MoreMenuItem,
147
+ NavItem,
148
+ } from "../../../UI/Components/Navbar/NavBar";
149
+ import NavBarMenuModal from "../../../UI/Components/Navbar/NavBarMenuModal";
150
+ import Page from "../../../UI/Components/Page/Page";
151
+ import Pagination from "../../../UI/Components/Pagination/Pagination";
152
+ import SideMenu from "../../../UI/Components/SideMenu/SideMenu";
153
+ import FieldType from "../../../UI/Components/Types/FieldType";
154
+ import Navigation from "../../../UI/Utils/Navigation";
155
+ import PermissionGate from "../../../UI/Utils/PermissionGate";
156
+ import TableFilterUrlState from "../../../UI/Utils/TableFilterUrlState";
157
+ import Label from "../../../Models/DatabaseModels/Label";
158
+ import Monitor from "../../../Models/DatabaseModels/Monitor";
159
+ import Route from "../../../Types/API/Route";
160
+ import URL from "../../../Types/API/URL";
161
+ import ListResult from "../../../Types/BaseDatabase/ListResult";
162
+ import IconProp from "../../../Types/Icon/IconProp";
163
+ import { JSONObject } from "../../../Types/JSON";
164
+ import ObjectID from "../../../Types/ObjectID";
165
+
166
+ const FOREIGN_RULE: VisibilityOptions = { withForeignHiddenRule: true };
167
+
168
+ const SM_IN_PX: number = TAILWIND_BREAKPOINTS_IN_PX["sm"]!;
169
+ const MD_IN_PX: number = TAILWIND_BREAKPOINTS_IN_PX["md"]!;
170
+ const LG_IN_PX: number = TAILWIND_BREAKPOINTS_IN_PX["lg"]!;
171
+
172
+ /*
173
+ * Widths either side of the two breakpoints the fixed markup uses, including
174
+ * the last pixel before each one and the customer's own 1917px window.
175
+ */
176
+ const WIDTHS_BELOW_SM: Array<number> = [320, PHONE_WIDTH_IN_PX, SM_IN_PX - 1];
177
+ const WIDTHS_FROM_SM: Array<number> = [
178
+ SM_IN_PX,
179
+ TABLET_WIDTH_IN_PX,
180
+ LG_IN_PX,
181
+ LAPTOP_WIDTH_IN_PX,
182
+ WIDE_DESKTOP_WIDTH_IN_PX,
183
+ ];
184
+ const WIDTHS_BELOW_MD: Array<number> = [
185
+ PHONE_WIDTH_IN_PX,
186
+ SM_IN_PX,
187
+ MD_IN_PX - 1,
188
+ ];
189
+ const WIDTHS_FROM_MD: Array<number> = [
190
+ TABLET_WIDTH_IN_PX,
191
+ LG_IN_PX,
192
+ LAPTOP_WIDTH_IN_PX,
193
+ WIDE_DESKTOP_WIDTH_IN_PX,
194
+ ];
195
+
196
+ const ORIGINAL_INNER_WIDTH: number = window.innerWidth;
197
+
198
+ const PROJECT_ID: string = "10000000-0000-4000-8000-000000000001";
199
+
200
+ function setViewportWidth(width: number): void {
201
+ Object.defineProperty(window, "innerWidth", {
202
+ configurable: true,
203
+ writable: true,
204
+ value: width,
205
+ });
206
+ }
207
+
208
+ function goTo(pathname: string): void {
209
+ Navigation.setLocation({
210
+ pathname: pathname,
211
+ search: "",
212
+ hash: "",
213
+ state: null,
214
+ key: "test",
215
+ } as Location);
216
+ }
217
+
218
+ // Painted at each width: on a clean page, and with the foreign rule.
219
+ function expectOnScreenAt(
220
+ element: Element | null,
221
+ widths: Array<number>,
222
+ ): void {
223
+ for (const width of widths) {
224
+ expect(describeVisibility(element, width)).toBe(`visible at ${width}px`);
225
+ expect(describeVisibility(element, width, FOREIGN_RULE)).toBe(
226
+ `visible at ${width}px with a foreign .hidden rule on the page`,
227
+ );
228
+ }
229
+ }
230
+
231
+ /*
232
+ * Rendered, and still off screen at each width, rule or no rule. The explicit
233
+ * presence check keeps an element that was never rendered from passing as
234
+ * "hidden".
235
+ */
236
+ function expectOffScreenAt(
237
+ element: Element | null,
238
+ widths: Array<number>,
239
+ ): void {
240
+ expect(element).toBeInTheDocument();
241
+
242
+ for (const width of widths) {
243
+ expect(describeVisibility(element, width)).toContain(
244
+ `hidden at ${width}px`,
245
+ );
246
+ expect(describeVisibility(element, width, FOREIGN_RULE)).toContain(
247
+ `hidden at ${width}px`,
248
+ );
249
+ }
250
+ }
251
+
252
+ /*
253
+ * Every element under `root` that paints at some width on a clean page and at
254
+ * none once the foreign rule is there — markup that is only on screen because
255
+ * a responsive utility overrides a bare `hidden`. An element meant to be
256
+ * hidden at every width (a bare `hidden` with nothing overriding it) is hidden
257
+ * either way and is not listed.
258
+ */
259
+ function elementsLostToForeignRule(root: Element): Array<string> {
260
+ const widths: Array<number> = [
261
+ 320,
262
+ ...Object.values(TAILWIND_BREAKPOINTS_IN_PX),
263
+ ];
264
+
265
+ return Array.from(root.querySelectorAll("[class]"))
266
+ .filter((element: Element): boolean => {
267
+ const classAttribute: string | null = element.getAttribute("class");
268
+
269
+ return widths.some((width: number): boolean => {
270
+ return (
271
+ resolveDisplay(classAttribute, width) !== "hidden" &&
272
+ resolveDisplay(classAttribute, width, FOREIGN_RULE) === "hidden"
273
+ );
274
+ });
275
+ })
276
+ .map((element: Element): string => {
277
+ return `<${element.tagName.toLowerCase()} class="${element.getAttribute(
278
+ "class",
279
+ )}">`;
280
+ });
281
+ }
282
+
283
+ interface ClassChange {
284
+ // The class string exactly as the pre-fix source had it.
285
+ before: string;
286
+ // ... and exactly as it reads now.
287
+ after: string;
288
+ }
289
+
290
+ // The token the fix put where the bare `hidden` used to be.
291
+ const FIXED_HIDDEN_TOKEN: RegExp = /^max-(sm|md|lg|xl|2xl):hidden$/;
292
+
293
+ function tokensOf(classAttribute: string): Array<string> {
294
+ return classAttribute.split(/\s+/).filter(Boolean);
295
+ }
296
+
297
+ /*
298
+ * The pre-fix class attribute of `carrier`, rebuilt from what rendered by
299
+ * putting the diff's old string back where the new one is. It is checked to
300
+ * differ from the rendered attribute only by the swapped `hidden` token, so the
301
+ * control below runs against the markup that actually shipped, not against a
302
+ * paraphrase of it.
303
+ */
304
+ function preFixClassAttribute(carrier: Element, change: ClassChange): string {
305
+ const current: string = carrier.getAttribute("class") || "";
306
+
307
+ expect(current).toContain(change.after);
308
+
309
+ const preFix: string = current.replace(change.after, change.before);
310
+
311
+ expect(tokensOf(preFix)).toEqual(
312
+ tokensOf(current).map((token: string): string => {
313
+ return FIXED_HIDDEN_TOKEN.test(token) ? "hidden" : token;
314
+ }),
315
+ );
316
+
317
+ return preFix;
318
+ }
319
+
320
+ /*
321
+ * The control: a detached copy of `carrier` wearing its pre-fix classes. On a
322
+ * clean page it paints at every width it is meant for — which is why nothing
323
+ * flagged it — and with the foreign rule it paints at none of them.
324
+ */
325
+ function expectPreFixMarkupLostToForeignRule(
326
+ carrier: Element,
327
+ change: ClassChange,
328
+ widths: Array<number>,
329
+ ): void {
330
+ const preFix: string = preFixClassAttribute(carrier, change);
331
+ const copy: Element = carrier.cloneNode(false) as Element;
332
+ copy.setAttribute("class", preFix);
333
+
334
+ for (const width of widths) {
335
+ expect(describeVisibility(copy, width)).toBe(`visible at ${width}px`);
336
+ expect(describeVisibility(copy, width, FOREIGN_RULE)).toBe(
337
+ `hidden at ${width}px with a foreign .hidden rule on the page by <${copy.tagName.toLowerCase()} class="${preFix}">`,
338
+ );
339
+ }
340
+ }
341
+
342
+ describe("Shared components under a foreign .hidden rule", () => {
343
+ beforeAll(() => {
344
+ // The products menu scrolls its active option into view; jsdom has no layout.
345
+ Element.prototype.scrollIntoView = (): void => {};
346
+ });
347
+
348
+ beforeEach(() => {
349
+ goTo(`/dashboard/${PROJECT_ID}/home`);
350
+ window.localStorage.clear();
351
+ });
352
+
353
+ afterEach(() => {
354
+ cleanup();
355
+ setViewportWidth(ORIGINAL_INNER_WIDTH);
356
+ });
357
+
358
+ describe("NavBar", () => {
359
+ const home: NavItem = {
360
+ id: "home-nav-bar-item",
361
+ title: "Home",
362
+ icon: IconProp.Home,
363
+ route: new Route(`/dashboard/${PROJECT_ID}/home`),
364
+ };
365
+
366
+ const settings: NavItem = {
367
+ id: "settings-nav-bar-item",
368
+ title: "Project Settings",
369
+ icon: IconProp.Settings,
370
+ route: new Route(`/dashboard/${PROJECT_ID}/settings`),
371
+ };
372
+
373
+ const products: Array<MoreMenuItem> = [
374
+ {
375
+ title: "Monitors",
376
+ description: "Check uptime and availability.",
377
+ icon: IconProp.AltGlobe,
378
+ route: new Route(`/dashboard/${PROJECT_ID}/monitors`),
379
+ },
380
+ {
381
+ title: "Logs",
382
+ description: "Investigate application events.",
383
+ icon: IconProp.Logs,
384
+ route: new Route(`/dashboard/${PROJECT_ID}/logs`),
385
+ },
386
+ ];
387
+
388
+ const DESKTOP_ROW_CHANGE: ClassChange = {
389
+ before: "bg-white flex text-center items-center lg:py-2 hidden md:flex",
390
+ after:
391
+ "bg-white flex text-center items-center lg:py-2 max-md:hidden md:flex",
392
+ };
393
+
394
+ function renderNavbar(): ReturnType<typeof render> {
395
+ return render(
396
+ <Navbar
397
+ items={[home]}
398
+ moreMenuItems={products}
399
+ rightElement={settings}
400
+ />,
401
+ );
402
+ }
403
+
404
+ function productsButton(): HTMLElement | null {
405
+ return screen.getByText("Products").closest("button");
406
+ }
407
+
408
+ /*
409
+ * Rendered once per width with innerWidth set to it, so the desktop branch
410
+ * is the one the component itself picks there — this is the bar the
411
+ * customer's 1917px window should have shown.
412
+ */
413
+ test("the nav row, Home and the Products button are on screen from 768px up with the rule", () => {
414
+ for (const width of WIDTHS_FROM_MD) {
415
+ setViewportWidth(width);
416
+ const { unmount } = renderNavbar();
417
+
418
+ expect(screen.queryByTestId("mobile-nav-toggle")).toBeNull();
419
+ expectOnScreenAt(screen.getByTestId("nav-children"), [width]);
420
+ expectOnScreenAt(document.getElementById("home-nav-bar-item"), [width]);
421
+ expectOnScreenAt(productsButton(), [width]);
422
+
423
+ unmount();
424
+ }
425
+ });
426
+
427
+ test("the right-hand element's container, which shares the row's classes, survives the rule too", () => {
428
+ setViewportWidth(LAPTOP_WIDTH_IN_PX);
429
+ renderNavbar();
430
+
431
+ const rightElement: HTMLElement | null = screen
432
+ .getByText("Project Settings")
433
+ .closest("a");
434
+ const container: HTMLElement = rightElement!.parentElement!;
435
+
436
+ expect(container).not.toBe(screen.getByTestId("nav-children"));
437
+ expect(container.getAttribute("class")).toBe(DESKTOP_ROW_CHANGE.after);
438
+ expectOnScreenAt(rightElement, WIDTHS_FROM_MD);
439
+ });
440
+
441
+ /*
442
+ * The component starts out assuming a desktop and only switches to the
443
+ * phone branch once its effect has measured the window, so on a phone the
444
+ * very first paint is the desktop row. The class is what keeps that row
445
+ * off a narrow screen, and it still has to, rule or no rule.
446
+ */
447
+ test("the desktop row is still off screen below 768px", () => {
448
+ setViewportWidth(LAPTOP_WIDTH_IN_PX);
449
+ renderNavbar();
450
+
451
+ expectOffScreenAt(screen.getByTestId("nav-children"), WIDTHS_BELOW_MD);
452
+ expectOffScreenAt(
453
+ document.getElementById("home-nav-bar-item"),
454
+ WIDTHS_BELOW_MD,
455
+ );
456
+ expectOffScreenAt(productsButton(), WIDTHS_BELOW_MD);
457
+ });
458
+
459
+ test("the phone branch still shows its menu toggle with the rule, and only below 768px", () => {
460
+ setViewportWidth(PHONE_WIDTH_IN_PX);
461
+ renderNavbar();
462
+
463
+ const toggle: HTMLElement = screen.getByTestId("mobile-nav-toggle");
464
+
465
+ expect(screen.queryByTestId("nav-children")).toBeNull();
466
+ expectOnScreenAt(toggle, [320, PHONE_WIDTH_IN_PX, MD_IN_PX - 1]);
467
+ expectOffScreenAt(toggle, WIDTHS_FROM_MD);
468
+ });
469
+
470
+ test("nothing in either branch is only on screen by overriding a bare hidden", () => {
471
+ setViewportWidth(LAPTOP_WIDTH_IN_PX);
472
+ const { unmount } = renderNavbar();
473
+
474
+ expect(elementsLostToForeignRule(document.body)).toEqual([]);
475
+
476
+ unmount();
477
+ setViewportWidth(PHONE_WIDTH_IN_PX);
478
+ renderNavbar();
479
+
480
+ expect(elementsLostToForeignRule(document.body)).toEqual([]);
481
+ });
482
+
483
+ test("control: the pre-fix row class takes the whole bar away under the rule", () => {
484
+ setViewportWidth(WIDE_DESKTOP_WIDTH_IN_PX);
485
+ renderNavbar();
486
+
487
+ expectPreFixMarkupLostToForeignRule(
488
+ screen.getByTestId("nav-children"),
489
+ DESKTOP_ROW_CHANGE,
490
+ WIDTHS_FROM_MD,
491
+ );
492
+ });
493
+ });
494
+
495
+ describe("SideMenu", () => {
496
+ const ASIDE_CHANGE: ClassChange = {
497
+ before: "hidden md:block w-56 lg:w-64 flex-shrink-0 mb-10",
498
+ after: "max-md:hidden md:block w-56 lg:w-64 flex-shrink-0 mb-10",
499
+ };
500
+
501
+ function renderSideMenu(): void {
502
+ render(
503
+ <SideMenu
504
+ items={[
505
+ {
506
+ link: {
507
+ title: "Overview",
508
+ to: new Route(`/dashboard/${PROJECT_ID}/home`),
509
+ },
510
+ icon: IconProp.Home,
511
+ },
512
+ {
513
+ link: {
514
+ title: "Monitors",
515
+ to: new Route(`/dashboard/${PROJECT_ID}/monitors`),
516
+ },
517
+ icon: IconProp.AltGlobe,
518
+ },
519
+ ]}
520
+ />,
521
+ );
522
+ }
523
+
524
+ function desktopAside(): HTMLElement {
525
+ return screen.getByRole("navigation", { name: "Main navigation" });
526
+ }
527
+
528
+ test("the desktop menu and its links are on screen from 768px up with the rule", () => {
529
+ setViewportWidth(LAPTOP_WIDTH_IN_PX);
530
+ renderSideMenu();
531
+
532
+ expect(desktopAside().tagName).toBe("ASIDE");
533
+ expectOnScreenAt(desktopAside(), WIDTHS_FROM_MD);
534
+ expectOnScreenAt(screen.getByText("Monitors"), WIDTHS_FROM_MD);
535
+ expect(elementsLostToForeignRule(document.body)).toEqual([]);
536
+ });
537
+
538
+ test("the desktop menu is still off screen below 768px", () => {
539
+ setViewportWidth(LAPTOP_WIDTH_IN_PX);
540
+ renderSideMenu();
541
+
542
+ expectOffScreenAt(desktopAside(), WIDTHS_BELOW_MD);
543
+ });
544
+
545
+ test("the phone branch still shows its toggle with the rule", () => {
546
+ setViewportWidth(PHONE_WIDTH_IN_PX);
547
+ renderSideMenu();
548
+
549
+ const toggle: HTMLElement = screen.getByTestId("mobile-sidemenu-toggle");
550
+
551
+ expectOnScreenAt(toggle, [PHONE_WIDTH_IN_PX, MD_IN_PX - 1]);
552
+ expectOffScreenAt(toggle, WIDTHS_FROM_MD);
553
+ });
554
+
555
+ test("control: the pre-fix aside class takes the whole menu away under the rule", () => {
556
+ setViewportWidth(WIDE_DESKTOP_WIDTH_IN_PX);
557
+ renderSideMenu();
558
+
559
+ expectPreFixMarkupLostToForeignRule(
560
+ desktopAside(),
561
+ ASIDE_CHANGE,
562
+ WIDTHS_FROM_MD,
563
+ );
564
+ });
565
+ });
566
+
567
+ describe("Card description", () => {
568
+ const DESCRIPTION_CHANGE: ClassChange = {
569
+ before:
570
+ "mt-1.5 text-sm text-gray-500 w-full hidden md:block leading-relaxed",
571
+ after:
572
+ "mt-1.5 text-sm text-gray-500 w-full max-md:hidden md:block leading-relaxed",
573
+ };
574
+
575
+ test("is on screen from 768px up with the rule, and still off screen below it", () => {
576
+ render(<Card title="Monitors" description="Every monitor you own." />);
577
+
578
+ const description: HTMLElement = screen.getByTestId("card-description");
579
+
580
+ expectOnScreenAt(description, WIDTHS_FROM_MD);
581
+ expectOffScreenAt(description, WIDTHS_BELOW_MD);
582
+ // The title is not desktop-only and never was.
583
+ expectOnScreenAt(screen.getByText("Monitors"), [PHONE_WIDTH_IN_PX]);
584
+ expect(elementsLostToForeignRule(document.body)).toEqual([]);
585
+ });
586
+
587
+ test("control: the pre-fix description class is gone under the rule", () => {
588
+ render(<Card title="Monitors" description="Every monitor you own." />);
589
+
590
+ expectPreFixMarkupLostToForeignRule(
591
+ screen.getByTestId("card-description"),
592
+ DESCRIPTION_CHANGE,
593
+ WIDTHS_FROM_MD,
594
+ );
595
+ });
596
+ });
597
+
598
+ describe("Pagination", () => {
599
+ const PAGE_ITEM_CHANGE: ClassChange = {
600
+ before: "hidden sm:flex",
601
+ after: "max-sm:hidden sm:flex",
602
+ };
603
+
604
+ function renderPagination(hasMore?: boolean | undefined): void {
605
+ render(
606
+ <Pagination
607
+ currentPageNumber={1}
608
+ totalItemsCount={240}
609
+ itemsOnPage={10}
610
+ onNavigateToPage={getJestMockFunction()}
611
+ isLoading={false}
612
+ isError={false}
613
+ singularLabel="Monitor"
614
+ pluralLabel="Monitors"
615
+ hasMore={hasMore}
616
+ />,
617
+ );
618
+ }
619
+
620
+ test("the numbered pages and the ellipsis are on screen from 640px up with the rule", () => {
621
+ renderPagination();
622
+
623
+ for (const testId of [
624
+ "pagination-page-1",
625
+ "pagination-page-2",
626
+ "pagination-ellipsis-end",
627
+ "pagination-page-24",
628
+ ]) {
629
+ expectOnScreenAt(screen.getByTestId(testId), WIDTHS_FROM_SM);
630
+ }
631
+
632
+ expect(elementsLostToForeignRule(document.body)).toEqual([]);
633
+ });
634
+
635
+ test("below 640px the numbers still give way to the single page indicator", () => {
636
+ renderPagination();
637
+
638
+ expectOffScreenAt(
639
+ screen.getByTestId("pagination-page-2"),
640
+ WIDTHS_BELOW_SM,
641
+ );
642
+ expectOnScreenAt(
643
+ screen.getByTestId("pagination-current-page-indicator"),
644
+ WIDTHS_BELOW_SM,
645
+ );
646
+ expectOffScreenAt(
647
+ screen.getByTestId("pagination-current-page-indicator"),
648
+ WIDTHS_FROM_SM,
649
+ );
650
+ });
651
+
652
+ test("the has-more indicator is on screen from 640px up with the rule", () => {
653
+ renderPagination(true);
654
+
655
+ const indicator: HTMLElement = screen.getByTestId(
656
+ "pagination-current-page-indicator-desktop",
657
+ );
658
+
659
+ expectOnScreenAt(indicator, WIDTHS_FROM_SM);
660
+ expectOffScreenAt(indicator, WIDTHS_BELOW_SM);
661
+ });
662
+
663
+ test("control: the pre-fix page item class is gone under the rule", () => {
664
+ renderPagination();
665
+
666
+ expectPreFixMarkupLostToForeignRule(
667
+ screen.getByTestId("pagination-page-2").parentElement!,
668
+ PAGE_ITEM_CHANGE,
669
+ WIDTHS_FROM_SM,
670
+ );
671
+ });
672
+ });
673
+
674
+ describe("Page header labels", () => {
675
+ const LABELS_CHANGE: ClassChange = {
676
+ before:
677
+ "hidden sm:flex sm:flex-wrap sm:items-center sm:justify-end sm:gap-3",
678
+ after:
679
+ "max-sm:hidden sm:flex sm:flex-wrap sm:items-center sm:justify-end sm:gap-3",
680
+ };
681
+
682
+ function renderPage(): void {
683
+ const label: Label = new Label();
684
+ label.id = new ObjectID("33333333-3333-4333-8333-333333333330");
685
+ label.name = "Production";
686
+
687
+ render(
688
+ <Page title="Monitors" labels={[label]}>
689
+ <div>Body</div>
690
+ </Page>,
691
+ );
692
+ }
693
+
694
+ function labelsGroup(): HTMLElement {
695
+ return screen.getByText("Labels").parentElement!;
696
+ }
697
+
698
+ test("are on screen from 640px up with the rule, and still off screen below it", () => {
699
+ renderPage();
700
+
701
+ expectOnScreenAt(screen.getByText("Production"), WIDTHS_FROM_SM);
702
+ expectOffScreenAt(labelsGroup(), WIDTHS_BELOW_SM);
703
+ expectOnScreenAt(screen.getByText("Monitors"), [PHONE_WIDTH_IN_PX]);
704
+ expect(elementsLostToForeignRule(document.body)).toEqual([]);
705
+ });
706
+
707
+ test("control: the pre-fix labels class is gone under the rule", () => {
708
+ renderPage();
709
+
710
+ expectPreFixMarkupLostToForeignRule(
711
+ labelsGroup(),
712
+ LABELS_CHANGE,
713
+ WIDTHS_FROM_SM,
714
+ );
715
+ });
716
+ });
717
+
718
+ describe("HeaderIconDropdownButton shortcut keycaps", () => {
719
+ const KEYCAP_CHANGE: ClassChange = {
720
+ before: "ml-0.5 hidden sm:inline-flex",
721
+ after: "ml-0.5 max-sm:hidden sm:inline-flex",
722
+ };
723
+
724
+ function renderButton(): HTMLElement {
725
+ render(
726
+ <HeaderIconDropdownButton
727
+ name="Ask AI"
728
+ title="Ask AI"
729
+ icon={IconProp.Sparkles}
730
+ showDropdown={false}
731
+ shortcut={[KeyboardKey.Mod, "I"]}
732
+ />,
733
+ );
734
+
735
+ // The keycaps' wrapper is the KeyboardShortcut root, the <kbd>s' parent.
736
+ return screen.getByText("Ask AI").closest("button")!.querySelector("kbd")!
737
+ .parentElement!;
738
+ }
739
+
740
+ test("are on screen from 640px up with the rule, beside a label that never hides", () => {
741
+ const keycaps: HTMLElement = renderButton();
742
+
743
+ expectOnScreenAt(keycaps, WIDTHS_FROM_SM);
744
+ expectOffScreenAt(keycaps, WIDTHS_BELOW_SM);
745
+ expectOnScreenAt(screen.getByText("Ask AI"), [
746
+ ...WIDTHS_BELOW_SM,
747
+ ...WIDTHS_FROM_SM,
748
+ ]);
749
+ expect(elementsLostToForeignRule(document.body)).toEqual([]);
750
+ });
751
+
752
+ test("control: the pre-fix keycap class is gone under the rule", () => {
753
+ expectPreFixMarkupLostToForeignRule(
754
+ renderButton(),
755
+ KEYCAP_CHANGE,
756
+ WIDTHS_FROM_SM,
757
+ );
758
+ });
759
+ });
760
+
761
+ describe("NavBarMenuModal keyboard hints", () => {
762
+ const SHORTCUT_HINT_CHANGE: ClassChange = {
763
+ before: "hidden sm:inline-flex",
764
+ after: "max-sm:hidden sm:inline-flex",
765
+ };
766
+
767
+ const FOOTER_HINTS_CHANGE: ClassChange = {
768
+ before:
769
+ "hidden flex-shrink-0 items-center gap-2 text-xs text-gray-400 md:flex",
770
+ after:
771
+ "max-md:hidden flex-shrink-0 items-center gap-2 text-xs text-gray-400 md:flex",
772
+ };
773
+
774
+ const KEYBOARD_HINT: string =
775
+ "Use the arrow keys to move and Enter to open";
776
+
777
+ function renderModal(): void {
778
+ render(
779
+ <NavBarMenuModal
780
+ items={[
781
+ {
782
+ title: "Monitors",
783
+ description: "Check uptime and availability.",
784
+ icon: IconProp.AltGlobe,
785
+ route: new Route(`/dashboard/${PROJECT_ID}/monitors`),
786
+ },
787
+ ]}
788
+ footer={{
789
+ title: "OneUptime on GitHub",
790
+ description: "Star the project.",
791
+ link: URL.fromString("https://github.com/OneUptime/oneuptime"),
792
+ }}
793
+ keyboardHint={KEYBOARD_HINT}
794
+ onClose={getJestMockFunction()}
795
+ />,
796
+ );
797
+ }
798
+
799
+ // The Cmd/Ctrl+K keycaps sit in the search header, beside the input.
800
+ function commandKHint(): HTMLElement {
801
+ return screen.getByRole("combobox").parentElement!.querySelector("kbd")!
802
+ .parentElement!;
803
+ }
804
+
805
+ function footerHints(): HTMLElement {
806
+ return screen.getByLabelText(KEYBOARD_HINT);
807
+ }
808
+
809
+ test("the Cmd/Ctrl+K hint is on screen from 640px up with the rule", () => {
810
+ renderModal();
811
+
812
+ expectOnScreenAt(commandKHint(), WIDTHS_FROM_SM);
813
+ expectOffScreenAt(commandKHint(), WIDTHS_BELOW_SM);
814
+ });
815
+
816
+ test("the footer's arrow/Enter/Esc hints are on screen from 768px up with the rule", () => {
817
+ renderModal();
818
+
819
+ expectOnScreenAt(footerHints(), WIDTHS_FROM_MD);
820
+ expectOffScreenAt(footerHints(), WIDTHS_BELOW_MD);
821
+ expect(elementsLostToForeignRule(document.body)).toEqual([]);
822
+ });
823
+
824
+ test("control: both pre-fix hint classes are gone under the rule", () => {
825
+ renderModal();
826
+
827
+ expectPreFixMarkupLostToForeignRule(
828
+ commandKHint(),
829
+ SHORTCUT_HINT_CHANGE,
830
+ WIDTHS_FROM_SM,
831
+ );
832
+ expectPreFixMarkupLostToForeignRule(
833
+ footerHints(),
834
+ FOOTER_HINTS_CHANGE,
835
+ WIDTHS_FROM_MD,
836
+ );
837
+ });
838
+ });
839
+
840
+ describe("ModalFooter spacer", () => {
841
+ const SPACER_CHANGE: ClassChange = {
842
+ before: "hidden sm:block",
843
+ after: "max-sm:hidden sm:block",
844
+ };
845
+
846
+ /*
847
+ * With no left-hand element the footer puts an empty spacer first, and
848
+ * `justify-between` is what then pushes Cancel and Save to the right. Lose
849
+ * the spacer and the buttons slide over to the left edge of the modal.
850
+ */
851
+ function renderFooter(): HTMLElement {
852
+ render(
853
+ <ModalFooter
854
+ onClose={getJestMockFunction()}
855
+ onSubmit={getJestMockFunction()}
856
+ />,
857
+ );
858
+
859
+ return screen.getByTestId("modal-footer")
860
+ .firstElementChild as HTMLElement;
861
+ }
862
+
863
+ test("is in the row from 640px up with the rule, and out of it below", () => {
864
+ const spacer: HTMLElement = renderFooter();
865
+
866
+ expect(spacer).toBeEmptyDOMElement();
867
+ expectOnScreenAt(spacer, WIDTHS_FROM_SM);
868
+ expectOffScreenAt(spacer, WIDTHS_BELOW_SM);
869
+ expect(elementsLostToForeignRule(document.body)).toEqual([]);
870
+ });
871
+
872
+ test("control: the pre-fix spacer class is gone under the rule", () => {
873
+ expectPreFixMarkupLostToForeignRule(
874
+ renderFooter(),
875
+ SPACER_CHANGE,
876
+ WIDTHS_FROM_SM,
877
+ );
878
+ });
879
+ });
880
+
881
+ describe("Banner", () => {
882
+ const HIDE_ON_MOBILE_CHANGE: ClassChange = {
883
+ before: "hidden md:flex",
884
+ after: "max-md:hidden md:flex",
885
+ };
886
+
887
+ function renderBanner(hideOnMobile: boolean): HTMLElement {
888
+ render(
889
+ <Banner
890
+ title="New in OneUptime"
891
+ description="Try the redesigned status pages."
892
+ hideOnMobile={hideOnMobile}
893
+ />,
894
+ );
895
+
896
+ return screen.getByText("New in OneUptime").closest("div")!;
897
+ }
898
+
899
+ test("hideOnMobile keeps it on screen from 768px up with the rule, and off below", () => {
900
+ const banner: HTMLElement = renderBanner(true);
901
+
902
+ expectOnScreenAt(banner, WIDTHS_FROM_MD);
903
+ expectOffScreenAt(banner, WIDTHS_BELOW_MD);
904
+ expect(elementsLostToForeignRule(document.body)).toEqual([]);
905
+ });
906
+
907
+ test("without hideOnMobile it is on screen at every width", () => {
908
+ const banner: HTMLElement = renderBanner(false);
909
+
910
+ expectOnScreenAt(banner, [...WIDTHS_BELOW_MD, ...WIDTHS_FROM_MD]);
911
+ });
912
+
913
+ test("control: the pre-fix hideOnMobile classes are gone under the rule", () => {
914
+ expectPreFixMarkupLostToForeignRule(
915
+ renderBanner(true),
916
+ HIDE_ON_MOBILE_CHANGE,
917
+ WIDTHS_FROM_MD,
918
+ );
919
+ });
920
+ });
921
+
922
+ describe("CardModelDetail documentation and demo buttons", () => {
923
+ const BUTTON_CHANGE: ClassChange = {
924
+ before: "hidden md:flex",
925
+ after: "max-md:hidden md:flex",
926
+ };
927
+
928
+ function findButton(label: string): HTMLButtonElement | null {
929
+ return (
930
+ Array.from(document.querySelectorAll<HTMLButtonElement>("button")).find(
931
+ (button: HTMLButtonElement): boolean => {
932
+ return (button.textContent || "").trim() === label;
933
+ },
934
+ ) || null
935
+ );
936
+ }
937
+
938
+ async function renderCardModelDetail(): Promise<void> {
939
+ render(
940
+ <CardModelDetail<Monitor>
941
+ name="Monitor Details"
942
+ cardProps={{
943
+ title: "Monitor Details",
944
+ description: "Key facts about this monitor.",
945
+ }}
946
+ isEditable={false}
947
+ documentationLink={new Route("/docs/monitor")}
948
+ videoLink={URL.fromString("https://www.youtube.com/watch?v=demo")}
949
+ modelDetailProps={{
950
+ modelType: Monitor,
951
+ id: "monitor-detail",
952
+ modelId: new ObjectID("11111111-1111-4111-8111-111111111111"),
953
+ fields: [
954
+ {
955
+ field: { name: true },
956
+ title: "Name",
957
+ fieldType: FieldType.Text,
958
+ },
959
+ ],
960
+ }}
961
+ />,
962
+ );
963
+
964
+ await waitFor(() => {
965
+ expect(findButton("Watch Demo")).not.toBeNull();
966
+ });
967
+ }
968
+
969
+ beforeEach(() => {
970
+ PermissionGate.clearPermissionPropsCache();
971
+ });
972
+
973
+ test("are on screen from 768px up with the rule, and still off screen below it", async () => {
974
+ await renderCardModelDetail();
975
+
976
+ for (const label of ["View Documentation", "Watch Demo"]) {
977
+ expectOnScreenAt(findButton(label), WIDTHS_FROM_MD);
978
+ expectOffScreenAt(findButton(label), WIDTHS_BELOW_MD);
979
+ }
980
+
981
+ expect(elementsLostToForeignRule(document.body)).toEqual([]);
982
+ });
983
+
984
+ test("control: the pre-fix button class is gone under the rule", async () => {
985
+ await renderCardModelDetail();
986
+
987
+ for (const label of ["View Documentation", "Watch Demo"]) {
988
+ expectPreFixMarkupLostToForeignRule(
989
+ findButton(label)!,
990
+ BUTTON_CHANGE,
991
+ WIDTHS_FROM_MD,
992
+ );
993
+ }
994
+ });
995
+ });
996
+
997
+ describe("BaseModelTable header", () => {
998
+ const SEARCH_KEYCAP_CHANGE: ClassChange = {
999
+ before:
1000
+ "hidden flex-none select-none items-center rounded border border-gray-200 bg-gray-50 px-1.5 py-0.5 font-mono text-[10px] font-medium text-gray-500 sm:inline-flex",
1001
+ after:
1002
+ "max-sm:hidden flex-none select-none items-center rounded border border-gray-200 bg-gray-50 px-1.5 py-0.5 font-mono text-[10px] font-medium text-gray-500 sm:inline-flex",
1003
+ };
1004
+
1005
+ function makeProps(): BaseModelTableProps<Monitor> {
1006
+ const callbacks: BaseTableCallbacks<Monitor> = {
1007
+ deleteItem: async (): Promise<void> => {
1008
+ return undefined;
1009
+ },
1010
+ getModelFromJSON: (item: JSONObject): Monitor => {
1011
+ return item as unknown as Monitor;
1012
+ },
1013
+ getJSONFromModel: (item: Monitor): JSONObject => {
1014
+ return item as unknown as JSONObject;
1015
+ },
1016
+ addSlugToSelect: (select: unknown): unknown => {
1017
+ return select;
1018
+ },
1019
+ getList: async (data: {
1020
+ skip: number;
1021
+ limit: number;
1022
+ }): Promise<ListResult<Monitor>> => {
1023
+ return { data: [], count: 0, skip: data.skip, limit: data.limit };
1024
+ },
1025
+ toJSONArray: (): Array<JSONObject> => {
1026
+ return [];
1027
+ },
1028
+ updateById: async (): Promise<void> => {
1029
+ return undefined;
1030
+ },
1031
+ showCreateEditModal: (): React.ReactElement => {
1032
+ return <div data-testid="create-edit-modal" />;
1033
+ },
1034
+ } as unknown as BaseTableCallbacks<Monitor>;
1035
+
1036
+ return {
1037
+ modelType: Monitor,
1038
+ id: "foreign-hidden-rule-table",
1039
+ name: "Foreign Hidden Rule",
1040
+ userPreferencesKey: "foreign-hidden-rule-table",
1041
+ urlStateKey: "foreign-hidden-rule-table",
1042
+ columns: [
1043
+ { field: { name: true }, title: "Name", type: FieldType.Text },
1044
+ ],
1045
+ filters: [],
1046
+ searchableFields: ["name"],
1047
+ cardProps: { title: "Monitors", description: "All monitors" },
1048
+ documentationLink: new Route("/docs/monitor"),
1049
+ videoLink: URL.fromString("https://www.youtube.com/watch?v=demo"),
1050
+ isCreateable: false,
1051
+ isEditable: false,
1052
+ isDeleteable: false,
1053
+ isViewable: false,
1054
+ callbacks: callbacks,
1055
+ } as unknown as BaseModelTableProps<Monitor>;
1056
+ }
1057
+
1058
+ function moreOptionsButton(): HTMLElement {
1059
+ return screen.getByRole("button", { name: "More options" });
1060
+ }
1061
+
1062
+ // The "/" keycaps: one on the collapsed search pill, one on the open bar.
1063
+ function searchKeycaps(): Array<HTMLElement> {
1064
+ const onPill: HTMLElement | null = screen
1065
+ .getByRole("button", { name: "Open search" })
1066
+ .querySelector("kbd");
1067
+ const onBar: HTMLElement | null = document.querySelector(
1068
+ 'kbd[title="Press / to focus search"]',
1069
+ );
1070
+
1071
+ expect(onPill).not.toBeNull();
1072
+ expect(onBar).not.toBeNull();
1073
+
1074
+ return [onPill!, onBar!];
1075
+ }
1076
+
1077
+ async function renderTable(): Promise<void> {
1078
+ render(<BaseModelTable<Monitor> {...makeProps()} />);
1079
+
1080
+ await waitFor(() => {
1081
+ expect(moreOptionsButton()).toBeInTheDocument();
1082
+ });
1083
+ }
1084
+
1085
+ beforeEach(() => {
1086
+ PermissionGate.clearPermissionPropsCache();
1087
+ window.history.replaceState(
1088
+ window.history.state,
1089
+ "",
1090
+ "/dashboard/monitors",
1091
+ );
1092
+ TableFilterUrlState.resetClaimedKeys();
1093
+ });
1094
+
1095
+ afterEach(() => {
1096
+ jest.restoreAllMocks();
1097
+ });
1098
+
1099
+ test("the search keycaps are on screen from 640px up with the rule, and still off below", async () => {
1100
+ await renderTable();
1101
+
1102
+ for (const keycap of searchKeycaps()) {
1103
+ expectOnScreenAt(keycap, WIDTHS_FROM_SM);
1104
+ expectOffScreenAt(keycap, WIDTHS_BELOW_SM);
1105
+ }
1106
+
1107
+ expect(elementsLostToForeignRule(document.body)).toEqual([]);
1108
+ });
1109
+
1110
+ /*
1111
+ * The table also marks its View Documentation and Watch Demo schemas
1112
+ * `max-md:hidden md:flex` (formerly `hidden md:flex`), but neither is ever
1113
+ * the header's main button, so both are rendered as entries of the ⋯ menu
1114
+ * — and a menu entry does not take the schema's className. What reaches
1115
+ * the screen is therefore the menu entry, and that is what is checked.
1116
+ */
1117
+ test("the documentation and demo entries in the ⋯ menu are on screen from 768px up with the rule", async () => {
1118
+ await renderTable();
1119
+
1120
+ fireEvent.click(moreOptionsButton());
1121
+
1122
+ for (const label of ["View Documentation", "Watch Demo"]) {
1123
+ const entry: HTMLElement | null = screen
1124
+ .getByText(label)
1125
+ .closest('[role="menuitem"]');
1126
+
1127
+ expect(entry).not.toBeNull();
1128
+ expect(entry!.getAttribute("class")).not.toContain("md:flex");
1129
+ expectOnScreenAt(entry, WIDTHS_FROM_MD);
1130
+ }
1131
+
1132
+ expect(elementsLostToForeignRule(document.body)).toEqual([]);
1133
+ });
1134
+
1135
+ test("control: the pre-fix search keycap class is gone under the rule", async () => {
1136
+ await renderTable();
1137
+
1138
+ for (const keycap of searchKeycaps()) {
1139
+ expectPreFixMarkupLostToForeignRule(
1140
+ keycap,
1141
+ SEARCH_KEYCAP_CHANGE,
1142
+ WIDTHS_FROM_SM,
1143
+ );
1144
+ }
1145
+ });
1146
+ });
1147
+ });