@oneuptime/common 14.0.10 → 14.0.11
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.
- package/Models/DatabaseModels/AIConversation.ts +127 -1
- package/Models/DatabaseModels/CephCluster.ts +12 -0
- package/Models/DatabaseModels/CloudResource.ts +12 -0
- package/Models/DatabaseModels/DatabaseServer.ts +12 -0
- package/Models/DatabaseModels/DockerHost.ts +12 -0
- package/Models/DatabaseModels/DockerSwarmCluster.ts +12 -0
- package/Models/DatabaseModels/GlobalOidc.ts +0 -4
- package/Models/DatabaseModels/GlobalOidcProject.ts +0 -4
- package/Models/DatabaseModels/GlobalSso.ts +0 -4
- package/Models/DatabaseModels/GlobalSsoProject.ts +0 -4
- package/Models/DatabaseModels/Host.ts +12 -0
- package/Models/DatabaseModels/IncidentForm.ts +594 -0
- package/Models/DatabaseModels/IncidentFormSubmission.ts +283 -0
- package/Models/DatabaseModels/IncidentTemplate.ts +59 -0
- package/Models/DatabaseModels/Index.ts +14 -0
- package/Models/DatabaseModels/IoTFleet.ts +12 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +12 -0
- package/Models/DatabaseModels/MessageQueue.ts +1102 -0
- package/Models/DatabaseModels/MessageQueueLabelRule.ts +553 -0
- package/Models/DatabaseModels/MessageQueueOwnerRule.ts +633 -0
- package/Models/DatabaseModels/MessageQueueOwnerTeam.ts +491 -0
- package/Models/DatabaseModels/MessageQueueOwnerUser.ts +490 -0
- package/Models/DatabaseModels/PodmanHost.ts +12 -0
- package/Models/DatabaseModels/Project.ts +59 -0
- package/Models/DatabaseModels/ProjectOidc.ts +0 -4
- package/Models/DatabaseModels/ProjectSso.ts +0 -4
- package/Models/DatabaseModels/ProxmoxCluster.ts +12 -0
- package/Models/DatabaseModels/RumApplication.ts +12 -0
- package/Models/DatabaseModels/ServerlessFunction.ts +12 -0
- package/Models/DatabaseModels/Service.ts +12 -0
- package/Models/DatabaseModels/StatusPageOidc.ts +0 -4
- package/Models/DatabaseModels/StatusPageSso.ts +0 -4
- package/Models/DatabaseModels/TeamComplianceSetting.ts +47 -2
- package/Models/DatabaseModels/VMwareVCenter.ts +12 -0
- package/Server/API/AIChatAPI.ts +13 -114
- package/Server/API/AIInvestigationAPI.ts +3 -3
- package/Server/API/AIInvestigationConversationAPI.ts +266 -0
- package/Server/API/IncidentFormAPI.ts +376 -0
- package/Server/API/ProjectOIDC.ts +16 -25
- package/Server/API/ProjectSSO.ts +16 -24
- package/Server/API/StatusPageAPI.ts +42 -77
- package/Server/Enterprise/EnterpriseEdition.ts +93 -28
- package/Server/Enterprise/EnterpriseFeature.ts +25 -3
- package/Server/Enterprise/EnterpriseLicenseSnapshot.ts +1 -1
- package/Server/Enterprise/EnterpriseServerModule.ts +4 -1
- package/Server/EnvironmentConfig.ts +1 -1
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.ts +129 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.ts +52 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.ts +75 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.ts +477 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
- package/Server/Middleware/IncidentFormRateLimit.ts +847 -0
- package/Server/Middleware/UserAuthorization.ts +16 -38
- package/Server/Services/AIService.ts +10 -13
- package/Server/Services/IncidentCustomFieldService.ts +112 -2
- package/Server/Services/IncidentEpisodeMemberService.ts +24 -4
- package/Server/Services/IncidentEpisodeService.ts +10 -1
- package/Server/Services/IncidentFormService.ts +1566 -0
- package/Server/Services/IncidentFormSubmissionService.ts +97 -0
- package/Server/Services/IncidentGroupingEngineService.ts +45 -8
- package/Server/Services/IncidentService.ts +123 -5
- package/Server/Services/IncidentTemplateService.ts +22 -0
- package/Server/Services/Index.ts +14 -0
- package/Server/Services/MessageQueueLabelRuleEngineService.ts +321 -0
- package/Server/Services/MessageQueueLabelRuleService.ts +14 -0
- package/Server/Services/MessageQueueOwnerRuleEngineService.ts +412 -0
- package/Server/Services/MessageQueueOwnerRuleService.ts +14 -0
- package/Server/Services/MessageQueueOwnerTeamService.ts +62 -0
- package/Server/Services/MessageQueueOwnerUserService.ts +62 -0
- package/Server/Services/MessageQueueService.ts +1463 -0
- package/Server/Services/OpenTelemetryIngestService.ts +37 -4
- package/Server/Services/ProjectService.ts +0 -59
- package/Server/Services/StatusPagePrivateUserService.ts +1 -4
- package/Server/Services/StatusPageService.ts +1 -51
- package/Server/Services/TeamComplianceSettingService.ts +163 -42
- package/Server/Services/UserNotificationRuleService.ts +8 -1
- package/Server/Services/WorkspaceNotificationSummaryService.ts +12 -3
- package/Server/Types/Database/Permissions/CreatePermission.ts +17 -3
- package/Server/Types/Database/Permissions/EditionPermission.ts +140 -38
- package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +16 -0
- package/Server/Types/Database/Permissions/TablePermission.ts +3 -3
- package/Server/Types/Database/Permissions/UpdatePermission.ts +20 -6
- package/Server/Utils/AI/Chat/AgentContextCompactor.ts +200 -0
- package/Server/Utils/AI/Chat/ChatAgentRunner.ts +307 -48
- package/Server/Utils/AI/Chat/ChatRunCancellation.ts +156 -0
- package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +78 -18
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
- package/Server/Utils/AI/Chat/ToolOutputPager.ts +322 -0
- package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +88 -30
- package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +13 -1
- package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +0 -32
- package/Server/Utils/AI/CodeFix/FixRunBudget.ts +27 -25
- package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +7 -1
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +34 -14
- package/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.ts +69 -24
- package/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.ts +9 -0
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +53 -10
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +27 -10
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +27 -10
- package/Server/Utils/AI/SRE/InvestigationQueue.ts +16 -19
- package/Server/Utils/AI/SRE/InvestigationThread.ts +646 -0
- package/Server/Utils/AI/SRE/InvestigationThreadService.ts +715 -0
- package/Server/Utils/AI/Toolbox/Serializer.ts +10 -3
- package/Server/Utils/EditionEnforcement.ts +19 -202
- package/Server/Utils/LLM/LLMService.ts +259 -63
- package/Server/Utils/RelaxedScimTeamLocksReport.ts +245 -0
- package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +25 -0
- package/Server/Utils/SameOriginRequest.ts +203 -0
- package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +2 -0
- package/Server/Utils/Telemetry/EntityRegistry.ts +4 -1
- package/Server/Utils/Telemetry/MessageQueueDiscovery.ts +1402 -0
- package/Server/Utils/Telemetry/ResourceEntityFilter.ts +4 -1
- package/Server/Utils/VendorAssets.ts +3 -3
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +3 -1
- package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +3 -1
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +10 -1
- package/Tests/App/Accounts/IncidentFormPage.test.tsx +2036 -0
- package/Tests/App/Accounts/IncidentFormServerMessages.test.ts +119 -0
- package/Tests/App/Accounts/IncidentFormUtils.test.ts +1157 -0
- package/Tests/App/Accounts/LoginPasskey.test.tsx +6 -4
- package/Tests/App/Accounts/LoginSso.test.tsx +724 -0
- package/Tests/App/AdminDashboard/AdminAuthenticationRequireSso.test.tsx +338 -0
- package/Tests/App/AdminDashboard/AdminAuthenticationSsoCardLocales.test.tsx +331 -0
- package/Tests/App/AdminDashboard/AdminEnterprisePluginPage.test.tsx +47 -33
- package/Tests/App/AdminDashboard/GlobalSsoOidcPages.test.tsx +1021 -0
- package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +876 -78
- package/Tests/App/Dashboard/AffectedResourcesSlo.test.tsx +20 -3
- package/Tests/App/Dashboard/CephProxmoxVMwareDocumentationCards.test.tsx +359 -0
- package/Tests/App/Dashboard/CephSetupGuide.test.ts +961 -0
- package/Tests/App/Dashboard/CloudDocumentationCard.test.tsx +381 -95
- package/Tests/App/Dashboard/CloudSetupGuide.test.ts +1463 -0
- package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +174 -12
- package/Tests/App/Dashboard/ContainerSetupGuideCards.test.tsx +345 -0
- package/Tests/App/Dashboard/CoreListEmptyStates.test.tsx +501 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +0 -1
- package/Tests/App/Dashboard/DatabaseDocumentationCard.test.tsx +400 -0
- package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +5 -0
- package/Tests/App/Dashboard/DatabaseSetupGuide.test.ts +1869 -0
- package/Tests/App/Dashboard/DatabaseTelemetryScope.test.ts +44 -0
- package/Tests/App/Dashboard/DatabaseTelemetryTabs.test.tsx +50 -9
- package/Tests/App/Dashboard/DockerSetupGuide.test.ts +899 -0
- package/Tests/App/Dashboard/DockerSwarmSetupGuide.test.ts +964 -0
- package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +141 -7
- package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +52 -39
- package/Tests/App/Dashboard/EventOverviewPages.test.tsx +7 -1
- package/Tests/App/Dashboard/GettingStartedTaskRoutes.test.tsx +331 -0
- package/Tests/App/Dashboard/HomeOverviewStatsFirstRun.test.tsx +925 -0
- package/Tests/App/Dashboard/HostDocumentationCard.test.tsx +225 -0
- package/Tests/App/Dashboard/HostSetupGuide.test.ts +1183 -0
- package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +69 -45
- package/Tests/App/Dashboard/IncidentCreateTemplateCustomFieldSettings.test.tsx +745 -0
- package/Tests/App/Dashboard/IncidentCreateTemplateOwners.test.tsx +414 -0
- package/Tests/App/Dashboard/IncidentCustomFieldCreateSettingsForm.test.ts +1042 -0
- package/Tests/App/Dashboard/IncidentCustomFieldSettingsCard.test.tsx +1816 -0
- package/Tests/App/Dashboard/IncidentFormPlan.test.ts +89 -0
- package/Tests/App/Dashboard/IncidentFormShareLinkCard.test.tsx +846 -0
- package/Tests/App/Dashboard/IncidentFormsPages.test.tsx +1324 -0
- package/Tests/App/Dashboard/IncidentTemplateCustomFieldSettings.test.tsx +630 -0
- package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +13 -0
- package/Tests/App/Dashboard/IncomingEmailMonitorLinkVerifyHint.test.tsx +104 -0
- package/Tests/App/Dashboard/InvestigationConversation.test.tsx +1107 -0
- package/Tests/App/Dashboard/InvestigationConversationData.test.ts +546 -0
- package/Tests/App/Dashboard/InvestigationEvidenceList.test.tsx +170 -5
- package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +207 -2
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +729 -34
- package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +9 -21
- package/Tests/App/Dashboard/InvestigationReportView.test.tsx +274 -37
- package/Tests/App/Dashboard/InvestigationStatusBadge.test.tsx +130 -0
- package/Tests/App/Dashboard/IoTDocumentationCard.test.tsx +218 -0
- package/Tests/App/Dashboard/IoTSetupGuide.test.ts +1124 -0
- package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +20 -6
- package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +107 -83
- package/Tests/App/Dashboard/KubernetesSetupGuide.test.ts +787 -0
- package/Tests/App/Dashboard/MessageQueueBreadcrumbs.test.tsx +228 -0
- package/Tests/App/Dashboard/MessageQueueBrokerHealth.test.tsx +1538 -0
- package/Tests/App/Dashboard/MessageQueueBrokerHealthMetricChart.test.tsx +969 -0
- package/Tests/App/Dashboard/MessageQueueBrokerHealthReads.test.ts +889 -0
- package/Tests/App/Dashboard/MessageQueueBrokerMetricsReach.test.ts +236 -0
- package/Tests/App/Dashboard/MessageQueueDocumentationCard.test.tsx +479 -0
- package/Tests/App/Dashboard/MessageQueueListPages.test.tsx +1232 -0
- package/Tests/App/Dashboard/MessageQueueMetricDescriptions.test.ts +244 -0
- package/Tests/App/Dashboard/MessageQueueMonitorLink.test.ts +952 -0
- package/Tests/App/Dashboard/MessageQueueMonitorLinkMonitorCreate.test.tsx +859 -0
- package/Tests/App/Dashboard/MessageQueueOverview.test.tsx +1773 -0
- package/Tests/App/Dashboard/MessageQueueOverviewPresentation.test.ts +196 -0
- package/Tests/App/Dashboard/MessageQueuePresentation.test.ts +799 -0
- package/Tests/App/Dashboard/MessageQueueProducersConsumers.test.tsx +680 -0
- package/Tests/App/Dashboard/MessageQueueRoutes.test.tsx +383 -0
- package/Tests/App/Dashboard/MessageQueueRulePages.test.tsx +278 -0
- package/Tests/App/Dashboard/MessageQueueSetupGuide.test.ts +2778 -0
- package/Tests/App/Dashboard/MessageQueueSideMenus.test.tsx +273 -0
- package/Tests/App/Dashboard/MessageQueueSpanPopulations.test.ts +930 -0
- package/Tests/App/Dashboard/MessageQueueSpanStore.ts +351 -0
- package/Tests/App/Dashboard/MessageQueueTelemetryScope.test.ts +375 -0
- package/Tests/App/Dashboard/MessageQueueTelemetryScopeTabs.test.tsx +668 -0
- package/Tests/App/Dashboard/MessageQueueViewPages.test.tsx +685 -0
- package/Tests/App/Dashboard/MonitorAndHomeNotOperationalMenus.test.tsx +342 -0
- package/Tests/App/Dashboard/MonitorCreateFirstRunDefaults.test.tsx +623 -0
- package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +442 -0
- package/Tests/App/Dashboard/MonitorLogsPageViewSummary.test.tsx +814 -0
- package/Tests/App/Dashboard/MonitorSetupCardBodies.test.tsx +246 -0
- package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +8 -0
- package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +27 -12
- package/Tests/App/Dashboard/PlanGatedPage.test.tsx +292 -0
- package/Tests/App/Dashboard/PodmanSetupGuide.test.ts +948 -0
- package/Tests/App/Dashboard/ProductOrientation.test.tsx +5 -4
- package/Tests/App/Dashboard/ProductSettingsSectionCollapsed.test.tsx +266 -0
- package/Tests/App/Dashboard/ProxmoxSetupGuide.test.ts +1318 -0
- package/Tests/App/Dashboard/ResourceAiAgentAttentionServerParity.test.ts +555 -0
- package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +298 -9
- package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +453 -0
- package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +16 -0
- package/Tests/App/Dashboard/ResourceConnectionGuideCard.test.tsx +444 -0
- package/Tests/App/Dashboard/ResourceConnectionGuideOverviewsInfra.test.tsx +798 -0
- package/Tests/App/Dashboard/ResourceConnectionGuideOverviewsPlatforms.test.tsx +717 -0
- package/Tests/App/Dashboard/ResourceConnectionGuides.test.ts +981 -0
- package/Tests/App/Dashboard/ResourceConnectionState.test.ts +132 -0
- package/Tests/App/Dashboard/RumDocumentationCard.test.tsx +293 -0
- package/Tests/App/Dashboard/RumSessionReplayRetentionSettings.test.tsx +467 -0
- package/Tests/App/Dashboard/RumSetupGuide.test.ts +758 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +25 -0
- package/Tests/App/Dashboard/ServerlessDocumentationCard.test.tsx +254 -0
- package/Tests/App/Dashboard/ServerlessSetupGuide.test.ts +1074 -0
- package/Tests/App/Dashboard/SetupGuide.test.ts +246 -0
- package/Tests/App/Dashboard/SetupGuideCard.test.tsx +756 -0
- package/Tests/App/Dashboard/SloListSideMenu.test.tsx +120 -0
- package/Tests/App/Dashboard/SsoPages.test.tsx +833 -0
- package/Tests/App/Dashboard/TelemetryDocumentation.test.tsx +253 -0
- package/Tests/App/Dashboard/TelemetryRetentionShells.test.tsx +730 -0
- package/Tests/App/Dashboard/VMwareSetupGuide.test.ts +1033 -0
- package/Tests/App/StatusPage/StatusPageSsoEmptyState.test.tsx +87 -7
- package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +28 -9
- package/Tests/Models/DatabaseModels/IncidentFormModel.test.ts +1250 -0
- package/Tests/Models/DatabaseModels/MessageQueueModels.test.ts +1983 -0
- package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
- package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +190 -14
- package/Tests/Models/IncidentTemplateCustomFieldSettingsColumn.test.ts +291 -0
- package/Tests/Server/API/AIInvestigationConversationAPI.test.ts +412 -0
- package/Tests/Server/API/GlobalConfigLicense.test.ts +38 -9
- package/Tests/Server/API/IncidentFormAPI.test.ts +942 -0
- package/Tests/Server/API/IncidentFormPublicRoutes.test.ts +1653 -0
- package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -1
- package/Tests/Server/API/{SsoProviderListingsEdition.test.ts → SsoProviderListings.test.ts} +164 -110
- package/Tests/Server/Enterprise/EnterpriseEdition.test.ts +76 -54
- package/Tests/Server/Enterprise/EnterpriseFeatureActive.test.ts +125 -42
- package/Tests/Server/Enterprise/EnterpriseLicenseSnapshot.test.ts +36 -10
- package/Tests/Server/Enterprise/EnterpriseModelFeatureMap.test.ts +51 -9
- package/Tests/Server/Enterprise/FakeEnterpriseModule.ts +13 -8
- package/Tests/Server/Enterprise/SsoInCommunityEdition.test.ts +540 -0
- package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
- package/Tests/Server/Infrastructure/Postgres/AddIncidentFormsMigration.test.ts +438 -0
- package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleNotificationChannelsMigration.test.ts +255 -0
- package/Tests/Server/Infrastructure/Postgres/MessageQueueTablesMigration.test.ts +637 -0
- package/Tests/Server/Middleware/IncidentFormRateLimit.test.ts +1630 -0
- package/Tests/Server/Middleware/UserAuthorization.test.ts +16 -17
- package/Tests/Server/Middleware/UserAuthorizationSsoEnforcement.test.ts +544 -0
- package/Tests/Server/Services/AIServiceDailyBudget.test.ts +37 -8
- package/Tests/Server/Services/IncidentCreatedFeedTitle.test.ts +212 -0
- package/Tests/Server/Services/IncidentCustomFieldDeleteFormQuestions.test.ts +297 -0
- package/Tests/Server/Services/IncidentFormOwnersCreatedNotification.test.ts +497 -0
- package/Tests/Server/Services/IncidentFormPostgres.test.ts +958 -0
- package/Tests/Server/Services/IncidentFormPublicForm.test.ts +1260 -0
- package/Tests/Server/Services/IncidentFormPublicSubmission.test.ts +2520 -0
- package/Tests/Server/Services/IncidentFormRegistration.test.ts +159 -0
- package/Tests/Server/Services/IncidentFormService.test.ts +663 -0
- package/Tests/Server/Services/IncidentFormSubmissionService.test.ts +430 -0
- package/Tests/Server/Services/IncidentFormSubmissionTemplateBranch.test.ts +473 -0
- package/Tests/Server/Services/IncidentGroupingTemplateSubstitution.test.ts +81 -0
- package/Tests/Server/Services/IncidentTemplateCustomFieldSettings.test.ts +262 -0
- package/Tests/Server/Services/IncidentTemplateOwnersOnDeclare.test.ts +566 -0
- package/Tests/Server/Services/IncidentTitleMarkdownSinks.test.ts +640 -0
- package/Tests/Server/Services/LlmLogServiceTokenAggregateParams.test.ts +3 -3
- package/Tests/Server/Services/MessageQueueOwnerServices.test.ts +440 -0
- package/Tests/Server/Services/MessageQueueRegistries.test.ts +577 -0
- package/Tests/Server/Services/MessageQueueRuleEngines.test.ts +900 -0
- package/Tests/Server/Services/MessageQueueService.test.ts +2210 -0
- package/Tests/Server/Services/MessageQueueSqlPostgres.test.ts +1271 -0
- package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +28 -1
- package/Tests/Server/Services/OpenTelemetryRetentionOverrideEdition.test.ts +474 -0
- package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +21 -0
- package/Tests/Server/Services/OwnerRowUniqueness.test.ts +3 -0
- package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +0 -1
- package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupBRun.test.ts +56 -6
- package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +30 -1
- package/Tests/Server/Services/SsoRequirementReads.test.ts +454 -0
- package/Tests/Server/Services/SsoRequirementWrites.test.ts +529 -0
- package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +3 -3
- package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +107 -89
- package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +1068 -176
- package/Tests/Server/Services/TeamComplianceSettingService.test.ts +1962 -200
- package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +654 -297
- package/Tests/Server/Types/Database/Permissions/RetentionOverrideColumns.test.ts +784 -0
- package/Tests/Server/Types/Database/Permissions/SsoScalePlanGate.test.ts +418 -0
- package/Tests/Server/Utils/AI/AIAlertGating.test.ts +0 -1
- package/Tests/Server/Utils/AI/AIInvestigationEngineRunLimits.test.ts +136 -0
- package/Tests/Server/Utils/AI/AIInvestigationQueue.test.ts +15 -14
- package/Tests/Server/Utils/AI/AgentContextCompactor.test.ts +351 -0
- package/Tests/Server/Utils/AI/ChatAgentRunnerSharedThread.test.ts +842 -0
- package/Tests/Server/Utils/AI/ChatRunCancellation.test.ts +195 -0
- package/Tests/Server/Utils/AI/CodeFixReadiness.test.ts +10 -57
- package/Tests/Server/Utils/AI/FixRunBudget.test.ts +20 -24
- package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +7 -30
- package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +225 -29
- package/Tests/Server/Utils/AI/InvestigationInfrastructureAccessWiring.test.ts +266 -25
- package/Tests/Server/Utils/AI/InvestigationThread.test.ts +580 -0
- package/Tests/Server/Utils/AI/InvestigationThreadService.test.ts +801 -0
- package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +525 -43
- package/Tests/Server/Utils/AI/KubectlJobRunner.test.ts +4 -2
- package/Tests/Server/Utils/AI/LLMServiceUnreachableProvider.test.ts +435 -0
- package/Tests/Server/Utils/AI/ObservabilityAssistantLimits.test.ts +462 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +14 -25
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +2 -0
- package/Tests/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.test.ts +297 -15
- package/Tests/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.test.ts +10 -6
- package/Tests/Server/Utils/AI/ToolOutputPager.test.ts +382 -0
- package/Tests/Server/Utils/AI/ToolResultSerializer.test.ts +23 -4
- package/Tests/Server/Utils/AI/Toolbox/LogTools.test.ts +25 -6
- package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +14 -3
- package/Tests/Server/Utils/EditionEnforcement.test.ts +107 -147
- package/Tests/Server/Utils/{CommunityEditionSsoReport.test.ts → RelaxedScimTeamLocksReport.test.ts} +212 -208
- package/Tests/Server/Utils/SameOriginRequest.test.ts +372 -0
- package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +20 -0
- package/Tests/Server/Utils/Telemetry/MessageQueueDiscovery.test.ts +2590 -0
- package/Tests/Server/Utils/Telemetry/MessageQueueSpanQueryTwin.ts +246 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +23 -0
- package/Tests/Types/AI/AIAgentRunLimits.test.ts +255 -0
- package/Tests/Types/Code/JsonSyntax.test.ts +1300 -0
- package/Tests/Types/CustomField/CustomFieldCreateSettings.test.ts +1113 -0
- package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +91 -0
- package/Tests/Types/CustomField/CustomFieldValueValidator.test.ts +30 -0
- package/Tests/Types/Incident/IncidentFormIpAllowlist.test.ts +227 -0
- package/Tests/Types/Incident/IncidentFormPublic.test.ts +1916 -0
- package/Tests/Types/MessageQueue/MessageQueueEntityKey.test.ts +916 -0
- package/Tests/Types/MessageQueue/MessageQueueIdentity.test.ts +567 -0
- package/Tests/Types/MessageQueue/MessageQueueManualIdentity.test.ts +686 -0
- package/Tests/Types/MessageQueue/MessageQueueMetricCatalog.test.ts +1726 -0
- package/Tests/Types/MessageQueue/MessageQueueMetricResolution.test.ts +1758 -0
- package/Tests/Types/MessageQueue/MessagingInstrumentationFixtures.test.ts +4686 -0
- package/Tests/Types/MessageQueue/MessagingSystem.test.ts +840 -0
- package/Tests/Types/MessageQueue/MessagingTelemetryFixtures.ts +3287 -0
- package/Tests/Types/MessageQueue/MessagingTelemetryResolver.test.ts +2966 -0
- package/Tests/Types/Monitor/MessageQueueAlertTemplates.test.ts +5401 -0
- package/Tests/Types/Monitor/MetricEngineFold.ts +154 -0
- package/Tests/Types/ResourceAiAgent/ResourceAiAccess.test.ts +5 -3
- package/Tests/Types/Team/ComplianceRule.test.ts +588 -37
- package/Tests/Types/Team/TeamComplianceStatus.test.ts +64 -11
- package/Tests/Types/XML.test.ts +51 -0
- package/Tests/UI/Components/CodeEditor/CodeEditor.test.tsx +2362 -0
- package/Tests/UI/Components/CodeEditor/CodeEditorCommands.test.ts +810 -0
- package/Tests/UI/Components/CodeEditor/CodeEditorHighlight.test.ts +338 -0
- package/Tests/UI/Components/CodeEditor/CodeEditorLanguages.test.ts +222 -0
- package/Tests/UI/Components/CodeEditor/CodeEditorStyles.test.ts +807 -0
- package/Tests/UI/Components/CodeEditor/NoMonaco.test.ts +245 -0
- package/Tests/UI/Components/CodeEditor/YamlEditor.test.tsx +729 -0
- package/Tests/UI/Components/CopyTextButton.test.tsx +76 -0
- package/Tests/UI/Components/EditionLabelLapseCopy.ts +51 -14
- package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +131 -23
- package/Tests/UI/Components/ErrorMessageAction.test.tsx +142 -0
- package/Tests/UI/Components/FacetSidebarInScope.test.tsx +459 -0
- package/Tests/UI/Components/FacetValuesInScope.test.ts +270 -0
- package/Tests/UI/Components/Forms/FormFieldCodeEditors.test.tsx +294 -0
- package/Tests/UI/Components/Forms/FormFieldMarkdown.test.tsx +126 -0
- package/Tests/UI/Components/Forms/FormFieldYaml.test.tsx +22 -75
- package/Tests/UI/Components/Forms/ModelFormOnBeforeCreateMiscData.test.tsx +254 -0
- package/Tests/UI/Components/Icon.test.tsx +32 -0
- package/Tests/UI/Components/Input.test.tsx +31 -0
- package/Tests/UI/Components/LockedFilterChipScope.test.tsx +501 -0
- package/Tests/UI/Components/MarkdownConverters.test.ts +253 -1
- package/Tests/UI/Components/MarkdownEditor.test.tsx +2785 -2
- package/Tests/UI/Components/MarkdownEditorHistory.test.ts +243 -0
- package/Tests/UI/Components/MarkdownListEditing.test.ts +1118 -0
- package/Tests/UI/Components/MarkdownPaste.test.ts +1180 -0
- package/Tests/UI/Components/MarkdownViewerCopy.test.tsx +466 -0
- package/Tests/UI/Components/MarkdownVisualEditing.test.ts +1089 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableEmptyStateAction.test.tsx +623 -0
- package/Tests/UI/Components/ResetObjectID.test.tsx +282 -0
- package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
- package/Tests/UI/Components/Table/EmptyTableMessage.test.ts +439 -0
- package/Tests/UI/Components/Table/TableEmptyState.test.tsx +352 -0
- package/Tests/UI/Components/TableRowMobileTitles.test.tsx +78 -0
- package/Tests/UI/Components/TextArea.test.tsx +19 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditor.render.test.tsx +12 -29
- package/Tests/UI/Components/fixtures/MarkdownPasteFixtures.ts +460 -0
- package/Tests/UI/EsbuildConfig.test.ts +115 -39
- package/Tests/UI/EsbuildEnterpriseAlias.test.ts +4 -4
- package/Tests/UI/Monitor/MonitorLogSummaryRender.test.tsx +377 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +81 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +17 -0
- package/Tests/Utils/LabelRuleImportExport.test.ts +5 -0
- package/Tests/Utils/Markdown/DashboardMarkdownRenderer.ts +81 -0
- package/Tests/Utils/Markdown/UntrustedMarkdown.test.ts +1339 -0
- package/Tests/Utils/Monitor/MonitorLogSummaryUtil.test.ts +862 -0
- package/Types/AI/AIAgentRunLimits.ts +146 -0
- package/Types/Code/CodeType.ts +2 -0
- package/Types/Code/JsonSyntax.ts +923 -0
- package/Types/CustomField/CustomFieldCreateSettings.ts +549 -0
- package/Types/CustomField/CustomFieldMappingCatalog.ts +77 -0
- package/Types/CustomField/CustomFieldValueValidator.ts +10 -7
- package/Types/EnterpriseLicense/EnterpriseLicensePeriods.ts +1 -1
- package/Types/Icon/IconProp.ts +2 -0
- package/Types/Incident/IncidentFormIpAllowlist.ts +206 -0
- package/Types/Incident/IncidentFormPublic.ts +1145 -0
- package/Types/Kubernetes/KubernetesClusterAiAccess.ts +10 -3
- package/Types/MessageQueue/MessageQueueIdentity.ts +256 -0
- package/Types/MessageQueue/MessageQueueManualIdentity.ts +325 -0
- package/Types/MessageQueue/MessageQueueMetricCatalog.ts +1357 -0
- package/Types/MessageQueue/MessagingSystem.ts +518 -0
- package/Types/MessageQueue/MessagingTelemetryResolver.ts +2311 -0
- package/Types/Monitor/MessageQueueAlertTemplates.ts +2128 -0
- package/Types/Permission.ts +310 -0
- package/Types/ResourceAiAgent/ResourceAiAccess.ts +10 -4
- package/Types/Rules/RuleCriteriaFieldRegistry.ts +12 -0
- package/Types/Rules/RuleRun.ts +4 -0
- package/Types/Team/ComplianceNotificationChannel.ts +4 -3
- package/Types/Team/ComplianceRule.ts +71 -18
- package/Types/Team/ComplianceRuleType.ts +2 -2
- package/Types/Team/TeamComplianceStatus.ts +6 -2
- package/Types/Telemetry/EntityType.ts +16 -0
- package/Types/Telemetry/LockedFilterDetail.ts +22 -0
- package/Types/XML.ts +26 -0
- package/UI/Components/CodeEditor/CodeEditor.css +379 -0
- package/UI/Components/CodeEditor/CodeEditor.tsx +1128 -294
- package/UI/Components/CodeEditor/CodeEditorCommands.ts +774 -0
- package/UI/Components/CodeEditor/CodeEditorHighlight.ts +106 -0
- package/UI/Components/CodeEditor/CodeEditorLanguages.ts +164 -0
- package/UI/Components/CodeEditor/YamlEditor.tsx +28 -326
- package/UI/Components/CopyTextButton/CopyTextButton.tsx +5 -1
- package/UI/Components/CustomFields/CustomFieldModelFormFields.tsx +6 -25
- package/UI/Components/EditionLabel/EditionLabel.tsx +14 -13
- package/UI/Components/ErrorMessage/ErrorMessage.tsx +11 -1
- package/UI/Components/Forms/Fields/FormField.tsx +8 -0
- package/UI/Components/Forms/Types/Field.ts +8 -0
- package/UI/Components/Icon/Icon.tsx +18 -0
- package/UI/Components/Input/Input.tsx +11 -4
- package/UI/Components/LogsViewer/LogsViewer.tsx +4 -0
- package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +21 -3
- package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
- package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +877 -79
- package/UI/Components/Markdown.tsx/MarkdownEditorHistory.ts +284 -0
- package/UI/Components/Markdown.tsx/MarkdownListEditing.ts +1362 -0
- package/UI/Components/Markdown.tsx/MarkdownPaste.ts +1326 -0
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +106 -10
- package/UI/Components/Markdown.tsx/MarkdownVisualEditing.ts +1032 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +85 -7
- package/UI/Components/ResetObjectID/ResetObjectID.tsx +35 -9
- package/UI/Components/Table/EmptyTableMessage.ts +81 -0
- package/UI/Components/Table/Table.tsx +50 -21
- package/UI/Components/Table/TableRow.tsx +9 -1
- package/UI/Components/TelemetryViewer/FacetVisibility.ts +97 -2
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +13 -0
- package/UI/Components/TelemetryViewer/components/LockedFilterChip.tsx +214 -7
- package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +21 -3
- package/UI/Components/TextArea/TextArea.tsx +9 -2
- package/UI/Components/Workflow/ModelFieldPicker.tsx +10 -12
- package/UI/Styles/Theme.css +8 -0
- package/UI/esbuild-config.js +2 -32
- package/Utils/LabelRuleImportExport.ts +2 -0
- package/Utils/Markdown/UntrustedMarkdown.ts +1513 -0
- package/Utils/Monitor/IncomingEmailMonitorRequestUtil.ts +41 -0
- package/Utils/Monitor/MonitorLogSummaryUtil.ts +212 -0
- package/Utils/Telemetry/EntityKey.ts +48 -0
- package/build/dist/Models/DatabaseModels/AIConversation.js +125 -1
- package/build/dist/Models/DatabaseModels/AIConversation.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CephCluster.js +12 -0
- package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CloudResource.js +12 -0
- package/build/dist/Models/DatabaseModels/CloudResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseServer.js +12 -0
- package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerHost.js +12 -0
- package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js +12 -0
- package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalOidc.js +0 -4
- package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +0 -4
- package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSso.js +0 -4
- package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +0 -4
- package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Host.js +12 -0
- package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentForm.js +605 -0
- package/build/dist/Models/DatabaseModels/IncidentForm.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncidentFormSubmission.js +299 -0
- package/build/dist/Models/DatabaseModels/IncidentFormSubmission.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js +60 -0
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +14 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IoTFleet.js +12 -0
- package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +12 -0
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MessageQueue.js +1106 -0
- package/build/dist/Models/DatabaseModels/MessageQueue.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MessageQueueLabelRule.js +562 -0
- package/build/dist/Models/DatabaseModels/MessageQueueLabelRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerRule.js +643 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerTeam.js +506 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerTeam.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerUser.js +505 -0
- package/build/dist/Models/DatabaseModels/MessageQueueOwnerUser.js.map +1 -0
- package/build/dist/Models/DatabaseModels/PodmanHost.js +12 -0
- package/build/dist/Models/DatabaseModels/PodmanHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +61 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectOidc.js +0 -4
- package/build/dist/Models/DatabaseModels/ProjectOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectSso.js +0 -4
- package/build/dist/Models/DatabaseModels/ProjectSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +12 -0
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js +12 -0
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServerlessFunction.js +12 -0
- package/build/dist/Models/DatabaseModels/ServerlessFunction.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Service.js +12 -0
- package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js +0 -4
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageSso.js +0 -4
- package/build/dist/Models/DatabaseModels/StatusPageSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +49 -3
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
- package/build/dist/Models/DatabaseModels/VMwareVCenter.js +12 -0
- package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +9 -103
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +3 -3
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationConversationAPI.js +162 -0
- package/build/dist/Server/API/AIInvestigationConversationAPI.js.map +1 -0
- package/build/dist/Server/API/IncidentFormAPI.js +245 -0
- package/build/dist/Server/API/IncidentFormAPI.js.map +1 -0
- package/build/dist/Server/API/ProjectOIDC.js +16 -24
- package/build/dist/Server/API/ProjectOIDC.js.map +1 -1
- package/build/dist/Server/API/ProjectSSO.js +16 -24
- package/build/dist/Server/API/ProjectSSO.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +42 -75
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseEdition.js +79 -25
- package/build/dist/Server/Enterprise/EnterpriseEdition.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseFeature.js +24 -3
- package/build/dist/Server/Enterprise/EnterpriseFeature.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js +1 -1
- package/build/dist/Server/Enterprise/EnterpriseServerModule.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.js +63 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.js +41 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.js +183 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/IncidentFormRateLimit.js +559 -0
- package/build/dist/Server/Middleware/IncidentFormRateLimit.js.map +1 -0
- package/build/dist/Server/Middleware/UserAuthorization.js +11 -30
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +10 -13
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/IncidentCustomFieldService.js +83 -0
- package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js +8 -4
- package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js +10 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/IncidentFormService.js +1202 -0
- package/build/dist/Server/Services/IncidentFormService.js.map +1 -0
- package/build/dist/Server/Services/IncidentFormSubmissionService.js +91 -0
- package/build/dist/Server/Services/IncidentFormSubmissionService.js.map +1 -0
- package/build/dist/Server/Services/IncidentGroupingEngineService.js +20 -8
- package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +106 -4
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentTemplateService.js +18 -0
- package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +14 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MessageQueueLabelRuleEngineService.js +262 -0
- package/build/dist/Server/Services/MessageQueueLabelRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueLabelRuleService.js +13 -0
- package/build/dist/Server/Services/MessageQueueLabelRuleService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueOwnerRuleEngineService.js +334 -0
- package/build/dist/Server/Services/MessageQueueOwnerRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueOwnerRuleService.js +13 -0
- package/build/dist/Server/Services/MessageQueueOwnerRuleService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueOwnerTeamService.js +62 -0
- package/build/dist/Server/Services/MessageQueueOwnerTeamService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueOwnerUserService.js +62 -0
- package/build/dist/Server/Services/MessageQueueOwnerUserService.js.map +1 -0
- package/build/dist/Server/Services/MessageQueueService.js +1140 -0
- package/build/dist/Server/Services/MessageQueueService.js.map +1 -0
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +25 -4
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +0 -54
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +1 -4
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +0 -46
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TeamComplianceSettingService.js +120 -31
- package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +8 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js +12 -3
- package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +6 -3
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js +109 -37
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +16 -0
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TablePermission.js +3 -3
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js +9 -6
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/AgentContextCompactor.js +128 -0
- package/build/dist/Server/Utils/AI/Chat/AgentContextCompactor.js.map +1 -0
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +192 -50
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ChatRunCancellation.js +133 -0
- package/build/dist/Server/Utils/AI/Chat/ChatRunCancellation.js.map +1 -0
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +53 -13
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
- package/build/dist/Server/Utils/AI/Chat/ToolOutputPager.js +206 -0
- package/build/dist/Server/Utils/AI/Chat/ToolOutputPager.js.map +1 -0
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +53 -26
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +4 -2
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +1 -29
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +24 -24
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +7 -2
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +29 -14
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js +38 -14
- package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js.map +1 -1
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js +2 -0
- package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +40 -10
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +19 -7
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +19 -7
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +15 -18
- package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationThread.js +412 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationThread.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationThreadService.js +495 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationThreadService.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/Serializer.js +10 -3
- package/build/dist/Server/Utils/AI/Toolbox/Serializer.js.map +1 -1
- package/build/dist/Server/Utils/EditionEnforcement.js +20 -158
- package/build/dist/Server/Utils/EditionEnforcement.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +193 -54
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/RelaxedScimTeamLocksReport.js +160 -0
- package/build/dist/Server/Utils/RelaxedScimTeamLocksReport.js.map +1 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +25 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
- package/build/dist/Server/Utils/SameOriginRequest.js +151 -0
- package/build/dist/Server/Utils/SameOriginRequest.js.map +1 -0
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +2 -0
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +4 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js +1015 -0
- package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +4 -1
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
- package/build/dist/Server/Utils/VendorAssets.js +3 -3
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +3 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +3 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +10 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/AI/AIAgentRunLimits.js +91 -0
- package/build/dist/Types/AI/AIAgentRunLimits.js.map +1 -0
- package/build/dist/Types/Code/CodeType.js +2 -0
- package/build/dist/Types/Code/CodeType.js.map +1 -1
- package/build/dist/Types/Code/JsonSyntax.js +604 -0
- package/build/dist/Types/Code/JsonSyntax.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldCreateSettings.js +310 -0
- package/build/dist/Types/CustomField/CustomFieldCreateSettings.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +38 -0
- package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -1
- package/build/dist/Types/CustomField/CustomFieldValueValidator.js +10 -7
- package/build/dist/Types/CustomField/CustomFieldValueValidator.js.map +1 -1
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js +1 -1
- package/build/dist/Types/Icon/IconProp.js +2 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/Incident/IncidentFormIpAllowlist.js +119 -0
- package/build/dist/Types/Incident/IncidentFormIpAllowlist.js.map +1 -0
- package/build/dist/Types/Incident/IncidentFormPublic.js +678 -0
- package/build/dist/Types/Incident/IncidentFormPublic.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +10 -3
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
- package/build/dist/Types/MessageQueue/MessageQueueIdentity.js +184 -0
- package/build/dist/Types/MessageQueue/MessageQueueIdentity.js.map +1 -0
- package/build/dist/Types/MessageQueue/MessageQueueManualIdentity.js +190 -0
- package/build/dist/Types/MessageQueue/MessageQueueManualIdentity.js.map +1 -0
- package/build/dist/Types/MessageQueue/MessageQueueMetricCatalog.js +1057 -0
- package/build/dist/Types/MessageQueue/MessageQueueMetricCatalog.js.map +1 -0
- package/build/dist/Types/MessageQueue/MessagingSystem.js +394 -0
- package/build/dist/Types/MessageQueue/MessagingSystem.js.map +1 -0
- package/build/dist/Types/MessageQueue/MessagingTelemetryResolver.js +1768 -0
- package/build/dist/Types/MessageQueue/MessagingTelemetryResolver.js.map +1 -0
- package/build/dist/Types/Monitor/MessageQueueAlertTemplates.js +1207 -0
- package/build/dist/Types/Monitor/MessageQueueAlertTemplates.js.map +1 -0
- package/build/dist/Types/Permission.js +274 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js +10 -4
- package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -1
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +12 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
- package/build/dist/Types/Rules/RuleRun.js +4 -0
- package/build/dist/Types/Rules/RuleRun.js.map +1 -1
- package/build/dist/Types/Team/ComplianceNotificationChannel.js +4 -3
- package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -1
- package/build/dist/Types/Team/ComplianceRule.js +48 -14
- package/build/dist/Types/Team/ComplianceRule.js.map +1 -1
- package/build/dist/Types/Team/ComplianceRuleType.js +2 -2
- package/build/dist/Types/Telemetry/EntityType.js +16 -0
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/XML.js +23 -0
- package/build/dist/Types/XML.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js +641 -266
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditorCommands.js +464 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorCommands.js.map +1 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorHighlight.js +69 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorHighlight.js.map +1 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorLanguages.js +108 -0
- package/build/dist/UI/Components/CodeEditor/CodeEditorLanguages.js.map +1 -0
- package/build/dist/UI/Components/CodeEditor/YamlEditor.js +14 -186
- package/build/dist/UI/Components/CodeEditor/YamlEditor.js.map +1 -1
- package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js +5 -1
- package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js +5 -14
- package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +14 -13
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js +1 -1
- package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +8 -3
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +8 -0
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +11 -3
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +2 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +14 -4
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +710 -65
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditorHistory.js +238 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditorHistory.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownListEditing.js +1028 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownListEditing.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownPaste.js +1088 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownPaste.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +70 -10
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownVisualEditing.js +887 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownVisualEditing.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +57 -6
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js +7 -5
- package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js.map +1 -1
- package/build/dist/UI/Components/Table/EmptyTableMessage.js +51 -0
- package/build/dist/UI/Components/Table/EmptyTableMessage.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +30 -11
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +9 -2
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js +63 -1
- package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +4 -2
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js +91 -10
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +14 -4
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/TextArea/TextArea.js +9 -3
- package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ModelFieldPicker.js +1 -2
- package/build/dist/UI/Components/Workflow/ModelFieldPicker.js.map +1 -1
- package/build/dist/Utils/LabelRuleImportExport.js +2 -0
- package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
- package/build/dist/Utils/Markdown/UntrustedMarkdown.js +988 -0
- package/build/dist/Utils/Markdown/UntrustedMarkdown.js.map +1 -0
- package/build/dist/Utils/Monitor/IncomingEmailMonitorRequestUtil.js +34 -0
- package/build/dist/Utils/Monitor/IncomingEmailMonitorRequestUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorLogSummaryUtil.js +148 -0
- package/build/dist/Utils/Monitor/MonitorLogSummaryUtil.js.map +1 -0
- package/build/dist/Utils/Telemetry/EntityKey.js +36 -0
- package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
- package/package.json +1 -3
- package/Server/Utils/CommunityEditionSsoReport.ts +0 -361
- package/Tests/App/Accounts/LoginSsoEdition.test.tsx +0 -616
- package/Tests/App/AdminDashboard/AdminAuthenticationSsoEdition.test.tsx +0 -217
- package/Tests/App/AdminDashboard/GlobalSSOEnterpriseShells.test.tsx +0 -271
- package/Tests/App/Dashboard/CloudDocumentationMarkdown.test.ts +0 -215
- package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +0 -784
- package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +0 -518
- package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +0 -419
- package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +0 -769
- package/Tests/UI/Components/CodeEditor.test.tsx +0 -638
- package/Tests/UI/Components/MonacoLoader.test.ts +0 -67
- package/Tests/UI/Components/MonacoRuntime.test.ts +0 -121
- package/Tests/UI/Components/Telemetry/TelemetryRetentionConfigForm.test.tsx +0 -329
- package/Tests/UI/Components/YamlEditor.test.tsx +0 -847
- package/UI/Components/CodeEditor/MonacoLoader.ts +0 -36
- package/UI/Components/Telemetry/TelemetryRetentionConfigForm.tsx +0 -319
- package/UI/Components/Telemetry/TelemetryRetentionConfigSummary.tsx +0 -223
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js +0 -223
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js.map +0 -1
- package/build/dist/UI/Components/CodeEditor/MonacoLoader.js +0 -34
- package/build/dist/UI/Components/CodeEditor/MonacoLoader.js.map +0 -1
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js +0 -171
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js.map +0 -1
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigSummary.js +0 -119
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigSummary.js.map +0 -1
|
@@ -1,14 +1,33 @@
|
|
|
1
1
|
import { afterEach, describe, expect, jest, test } from "@jest/globals";
|
|
2
2
|
import "@testing-library/jest-dom";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
cleanup,
|
|
5
|
+
fireEvent,
|
|
6
|
+
render,
|
|
7
|
+
screen,
|
|
8
|
+
within,
|
|
9
|
+
} from "@testing-library/react";
|
|
4
10
|
import React, { ReactElement, ReactNode } from "react";
|
|
5
11
|
|
|
6
12
|
/*
|
|
7
|
-
* AffectedResourcesDisplay
|
|
13
|
+
* AffectedResourcesDisplay is the body of the "Affected Resources" card on
|
|
14
|
+
* the incident, alert and scheduled maintenance overview pages (and of the
|
|
15
|
+
* templates' cards). It groups an event's resources by category.
|
|
16
|
+
*
|
|
17
|
+
* Each category used to be a card of its own - bordered, shadowed, rounded,
|
|
18
|
+
* with a coloured bar across its top - so the page's card read as a stack of
|
|
19
|
+
* cards nested inside a card. The categories are now flat sections of the one
|
|
20
|
+
* card: a small tinted icon, the label and its count, then the resources
|
|
21
|
+
* indented under the label, split by hairlines like the details card's rows.
|
|
22
|
+
*
|
|
8
23
|
* Its grid used to follow the viewport alone (two columns from md up), so on
|
|
9
|
-
* an overview page's ~300px sidebar two
|
|
10
|
-
* was clipped mid-word ("Checkout A"). Callers in a narrow column
|
|
11
|
-
* one column, and a long name ends in an ellipsis with the full name on
|
|
24
|
+
* an overview page's ~300px sidebar two categories shared the width and every
|
|
25
|
+
* name was clipped mid-word ("Checkout A"). Callers in a narrow column ask
|
|
26
|
+
* for one column, and a long name ends in an ellipsis with the full name on
|
|
27
|
+
* hover.
|
|
28
|
+
*
|
|
29
|
+
* Browser-level checks (computed styles, the stretched link, hover, focus,
|
|
30
|
+
* dark mode) live in packages/E2E/EventOverview.
|
|
12
31
|
*/
|
|
13
32
|
|
|
14
33
|
jest.mock(
|
|
@@ -32,90 +51,289 @@ jest.mock(
|
|
|
32
51
|
);
|
|
33
52
|
|
|
34
53
|
import AffectedResourcesDisplay, {
|
|
54
|
+
AFFECTED_RESOURCE_ITEM_CLASS_NAME,
|
|
35
55
|
getAffectedResourcesGridClassName,
|
|
56
|
+
getAffectedResourcesSectionClassName,
|
|
36
57
|
} from "../../../../App/FeatureSet/Dashboard/src/Components/AffectedResources/AffectedResourcesDisplay";
|
|
37
58
|
import AffectedResourcesCell from "../../../../App/FeatureSet/Dashboard/src/Components/AffectedResources/AffectedResourcesCell";
|
|
59
|
+
import CephCluster from "../../../Models/DatabaseModels/CephCluster";
|
|
60
|
+
import DatabaseServer from "../../../Models/DatabaseModels/DatabaseServer";
|
|
61
|
+
import DockerHost from "../../../Models/DatabaseModels/DockerHost";
|
|
62
|
+
import DockerSwarmCluster from "../../../Models/DatabaseModels/DockerSwarmCluster";
|
|
63
|
+
import Host from "../../../Models/DatabaseModels/Host";
|
|
64
|
+
import IoTFleet from "../../../Models/DatabaseModels/IoTFleet";
|
|
65
|
+
import KubernetesCluster from "../../../Models/DatabaseModels/KubernetesCluster";
|
|
38
66
|
import Monitor from "../../../Models/DatabaseModels/Monitor";
|
|
67
|
+
import NetworkSite from "../../../Models/DatabaseModels/NetworkSite";
|
|
68
|
+
import PodmanHost from "../../../Models/DatabaseModels/PodmanHost";
|
|
69
|
+
import ProxmoxCluster from "../../../Models/DatabaseModels/ProxmoxCluster";
|
|
39
70
|
import Service from "../../../Models/DatabaseModels/Service";
|
|
40
|
-
import
|
|
41
|
-
import
|
|
71
|
+
import ServiceLevelObjective from "../../../Models/DatabaseModels/ServiceLevelObjective";
|
|
72
|
+
import VMwareVCenter from "../../../Models/DatabaseModels/VMwareVCenter";
|
|
42
73
|
import Color from "../../../Types/Color";
|
|
43
74
|
|
|
44
75
|
const LONG_MONITOR_NAME: string =
|
|
45
76
|
"Checkout API p95 latency above two seconds in eu-west-1";
|
|
46
77
|
|
|
47
|
-
|
|
78
|
+
interface NamedModel {
|
|
79
|
+
_id?: string | undefined;
|
|
80
|
+
name?: string | undefined;
|
|
81
|
+
}
|
|
48
82
|
|
|
49
|
-
|
|
83
|
+
type NamedFunction = <T extends NamedModel>(
|
|
84
|
+
type: new () => T,
|
|
50
85
|
id: string,
|
|
51
86
|
name: string,
|
|
87
|
+
) => T;
|
|
88
|
+
|
|
89
|
+
const named: NamedFunction = <T extends NamedModel>(
|
|
90
|
+
type: new () => T,
|
|
91
|
+
id: string,
|
|
92
|
+
name: string,
|
|
93
|
+
): T => {
|
|
94
|
+
const model: T = new type();
|
|
95
|
+
model._id = id;
|
|
96
|
+
model.name = name;
|
|
97
|
+
return model;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
type IdFunction = (hex: string, n: number) => string;
|
|
101
|
+
|
|
102
|
+
// A valid UUID per model and index: "aaaaaaaa-aaaa-4aaa-8aaa-000000000001".
|
|
103
|
+
const id: IdFunction = (hex: string, n: number): string => {
|
|
104
|
+
const block: string = hex.repeat(8);
|
|
105
|
+
|
|
106
|
+
return `${block}-${hex.repeat(4)}-4${hex.repeat(3)}-8${hex.repeat(3)}-${String(n).padStart(12, "0")}`;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
type BuildMonitorFunction = (n: number, name: string) => Monitor;
|
|
110
|
+
|
|
111
|
+
const buildMonitor: BuildMonitorFunction = (
|
|
112
|
+
n: number,
|
|
113
|
+
name: string,
|
|
52
114
|
): Monitor => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
115
|
+
return named(Monitor, id("a", n), name);
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
type BuildMonitorsFunction = (count: number) => Array<Monitor>;
|
|
119
|
+
|
|
120
|
+
const buildMonitors: BuildMonitorsFunction = (
|
|
121
|
+
count: number,
|
|
122
|
+
): Array<Monitor> => {
|
|
123
|
+
return Array.from({ length: count }, (_: unknown, i: number): Monitor => {
|
|
124
|
+
return buildMonitor(i + 1, `probe-${String(i + 1).padStart(3, "0")}`);
|
|
125
|
+
});
|
|
57
126
|
};
|
|
58
127
|
|
|
59
|
-
type BuildServiceFunction = (
|
|
128
|
+
type BuildServiceFunction = (n: number, name: string) => Service;
|
|
60
129
|
|
|
61
130
|
const buildService: BuildServiceFunction = (
|
|
62
|
-
|
|
131
|
+
n: number,
|
|
63
132
|
name: string,
|
|
64
133
|
): Service => {
|
|
65
|
-
const service: Service =
|
|
66
|
-
service._id = id;
|
|
67
|
-
service.name = name;
|
|
134
|
+
const service: Service = named(Service, id("b", n), name);
|
|
68
135
|
service.serviceColor = new Color("#6366f1");
|
|
69
136
|
return service;
|
|
70
137
|
};
|
|
71
138
|
|
|
72
139
|
const MONITORS: Array<Monitor> = [
|
|
73
|
-
buildMonitor(
|
|
74
|
-
buildMonitor(
|
|
140
|
+
buildMonitor(1, LONG_MONITOR_NAME),
|
|
141
|
+
buildMonitor(2, "orders-db primary"),
|
|
75
142
|
];
|
|
76
143
|
|
|
77
|
-
const SERVICES: Array<Service> = [
|
|
78
|
-
buildService("bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbb1", "checkout-api"),
|
|
79
|
-
];
|
|
144
|
+
const SERVICES: Array<Service> = [buildService(1, "checkout-api")];
|
|
80
145
|
|
|
81
146
|
afterEach(() => {
|
|
82
147
|
cleanup();
|
|
83
148
|
});
|
|
84
149
|
|
|
150
|
+
/*
|
|
151
|
+
* Every class token on an element and its descendants: what the stylesheet
|
|
152
|
+
* can paint on this display, whatever the markup nests.
|
|
153
|
+
*/
|
|
154
|
+
function classTokensWithin(element: Element): Array<string> {
|
|
155
|
+
return [element, ...Array.from(element.querySelectorAll("*"))].flatMap(
|
|
156
|
+
(node: Element): Array<string> => {
|
|
157
|
+
return Array.from(node.classList);
|
|
158
|
+
},
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/*
|
|
163
|
+
* What made a category a card: a border (other than the grid's hairlines,
|
|
164
|
+
* which are divide-* on the grid), a shadow, a white fill of its own, card
|
|
165
|
+
* rounding, a ring, clipping, and the coloured bar across its top.
|
|
166
|
+
*/
|
|
167
|
+
const BORDER_OR_SHADOW: RegExp = /^(hover:)?(border|shadow)(-|$)/;
|
|
168
|
+
const RING: RegExp = /^ring(-|$)/;
|
|
169
|
+
const CARD_ROUNDING: RegExp = /^rounded-(lg|xl|2xl|3xl)$/;
|
|
170
|
+
|
|
171
|
+
function cardChromeIn(element: Element): Array<string> {
|
|
172
|
+
return classTokensWithin(element).filter((token: string): boolean => {
|
|
173
|
+
return (
|
|
174
|
+
BORDER_OR_SHADOW.test(token) ||
|
|
175
|
+
RING.test(token) ||
|
|
176
|
+
token === "bg-white" ||
|
|
177
|
+
token === "overflow-hidden" ||
|
|
178
|
+
CARD_ROUNDING.test(token) ||
|
|
179
|
+
token === "h-1"
|
|
180
|
+
);
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
type SectionsFunction = () => Array<HTMLElement>;
|
|
185
|
+
|
|
186
|
+
const sections: SectionsFunction = (): Array<HTMLElement> => {
|
|
187
|
+
return screen.getAllByTestId("affected-resource-category");
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
type HeadingNamesFunction = () => Array<string>;
|
|
191
|
+
|
|
192
|
+
// The category headings, as a screen reader names them: label, then count.
|
|
193
|
+
const headingNames: HeadingNamesFunction = (): Array<string> => {
|
|
194
|
+
return screen
|
|
195
|
+
.getAllByRole("heading", { level: 3 })
|
|
196
|
+
.map((heading: HTMLElement): string => {
|
|
197
|
+
return (heading.textContent || "").replace(/\s+/g, " ").trim();
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
|
|
85
201
|
describe("getAffectedResourcesGridClassName", () => {
|
|
86
|
-
test("
|
|
87
|
-
expect(getAffectedResourcesGridClassName(
|
|
88
|
-
"grid grid-cols-1
|
|
202
|
+
test("one column stacks the sections, split by hairlines", () => {
|
|
203
|
+
expect(getAffectedResourcesGridClassName(1)).toBe(
|
|
204
|
+
"grid grid-cols-1 divide-y divide-gray-100",
|
|
205
|
+
);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
test("by default the sections sit two abreast from md up, spaced instead of divided", () => {
|
|
209
|
+
const className: string = getAffectedResourcesGridClassName(undefined);
|
|
210
|
+
|
|
211
|
+
expect(className).toBe(
|
|
212
|
+
"grid grid-cols-1 divide-y divide-gray-100 md:grid-cols-2 md:gap-x-10 md:gap-y-6 md:divide-y-0",
|
|
213
|
+
);
|
|
214
|
+
// Phones still get one divided column.
|
|
215
|
+
expect(className.split(" ")).toEqual(
|
|
216
|
+
expect.arrayContaining(["grid-cols-1", "divide-y", "divide-gray-100"]),
|
|
89
217
|
);
|
|
90
218
|
});
|
|
91
219
|
|
|
92
220
|
test("two columns is the same viewport-based grid", () => {
|
|
93
221
|
expect(getAffectedResourcesGridClassName(2)).toBe(
|
|
94
|
-
|
|
222
|
+
getAffectedResourcesGridClassName(undefined),
|
|
95
223
|
);
|
|
96
224
|
});
|
|
97
225
|
|
|
98
226
|
test("one column never splits, whatever the viewport", () => {
|
|
99
227
|
const className: string = getAffectedResourcesGridClassName(1);
|
|
100
228
|
|
|
101
|
-
expect(className).toBe("grid grid-cols-1 gap-3");
|
|
102
229
|
expect(className).not.toContain("md:grid-cols-2");
|
|
230
|
+
expect(className).not.toContain("md:divide-y-0");
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
test("no layout spaces the sections with a gap between cards", () => {
|
|
234
|
+
for (const columns of [1, 2, undefined] as const) {
|
|
235
|
+
expect(getAffectedResourcesGridClassName(columns).split(" ")).not.toEqual(
|
|
236
|
+
expect.arrayContaining(["gap-3"]),
|
|
237
|
+
);
|
|
238
|
+
}
|
|
103
239
|
});
|
|
104
240
|
});
|
|
105
241
|
|
|
106
|
-
describe("
|
|
107
|
-
test("
|
|
242
|
+
describe("getAffectedResourcesSectionClassName", () => {
|
|
243
|
+
test("in one column a section is padded between hairlines, flush at both ends", () => {
|
|
244
|
+
expect(getAffectedResourcesSectionClassName(1)).toBe(
|
|
245
|
+
"min-w-0 py-4 first:pt-0 last:pb-0",
|
|
246
|
+
);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
test("side by side the padding goes, since whitespace separates the sections", () => {
|
|
250
|
+
expect(getAffectedResourcesSectionClassName(undefined)).toBe(
|
|
251
|
+
"min-w-0 py-4 first:pt-0 last:pb-0 md:py-0",
|
|
252
|
+
);
|
|
253
|
+
expect(getAffectedResourcesSectionClassName(2)).toBe(
|
|
254
|
+
getAffectedResourcesSectionClassName(undefined),
|
|
255
|
+
);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
test("the grid and its sections agree on the layout", () => {
|
|
259
|
+
render(
|
|
260
|
+
<AffectedResourcesDisplay
|
|
261
|
+
monitors={MONITORS}
|
|
262
|
+
services={SERVICES}
|
|
263
|
+
columns={1}
|
|
264
|
+
/>,
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
for (const section of sections()) {
|
|
268
|
+
expect(section.className).toBe(getAffectedResourcesSectionClassName(1));
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
cleanup();
|
|
108
272
|
render(
|
|
109
273
|
<AffectedResourcesDisplay monitors={MONITORS} services={SERVICES} />,
|
|
110
274
|
);
|
|
111
275
|
|
|
112
|
-
const
|
|
276
|
+
for (const section of sections()) {
|
|
277
|
+
expect(section.className).toBe(
|
|
278
|
+
getAffectedResourcesSectionClassName(undefined),
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
});
|
|
113
283
|
|
|
114
|
-
|
|
115
|
-
|
|
284
|
+
describe("AffectedResourcesDisplay: sections of one card, not cards in a card", () => {
|
|
285
|
+
const EVERY_CATEGORY: Array<ReactElement> = [
|
|
286
|
+
<AffectedResourcesDisplay
|
|
287
|
+
key="sidebar"
|
|
288
|
+
monitors={buildMonitors(7)}
|
|
289
|
+
hosts={[named(Host, id("c", 1), "web-01")]}
|
|
290
|
+
services={SERVICES}
|
|
291
|
+
serviceLevelObjectives={[
|
|
292
|
+
named(ServiceLevelObjective, id("d", 1), "Checkout availability"),
|
|
293
|
+
]}
|
|
294
|
+
columns={1}
|
|
295
|
+
/>,
|
|
296
|
+
<AffectedResourcesDisplay
|
|
297
|
+
key="full-width"
|
|
298
|
+
monitors={buildMonitors(7)}
|
|
299
|
+
hosts={[named(Host, id("c", 1), "web-01")]}
|
|
300
|
+
services={SERVICES}
|
|
301
|
+
/>,
|
|
302
|
+
];
|
|
303
|
+
|
|
304
|
+
test.each([
|
|
305
|
+
["the sidebar layout", 0],
|
|
306
|
+
["the full-width layout", 1],
|
|
307
|
+
])(
|
|
308
|
+
"no category in %s carries a border, shadow, fill, card rounding or accent bar",
|
|
309
|
+
(_layout: string, index: number) => {
|
|
310
|
+
const { container } = render(EVERY_CATEGORY[index]!);
|
|
311
|
+
|
|
312
|
+
expect(sections().length).toBeGreaterThan(1);
|
|
313
|
+
expect(cardChromeIn(container)).toEqual([]);
|
|
314
|
+
},
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
test("a category is a plain section: its own classes are only layout", () => {
|
|
318
|
+
render(
|
|
319
|
+
<AffectedResourcesDisplay
|
|
320
|
+
monitors={MONITORS}
|
|
321
|
+
services={SERVICES}
|
|
322
|
+
columns={1}
|
|
323
|
+
/>,
|
|
324
|
+
);
|
|
325
|
+
|
|
326
|
+
for (const section of sections()) {
|
|
327
|
+
expect(section.className.split(" ")).toEqual([
|
|
328
|
+
"min-w-0",
|
|
329
|
+
"py-4",
|
|
330
|
+
"first:pt-0",
|
|
331
|
+
"last:pb-0",
|
|
332
|
+
]);
|
|
333
|
+
}
|
|
116
334
|
});
|
|
117
335
|
|
|
118
|
-
test("
|
|
336
|
+
test("the sections are split by the grid's hairlines, not spaced apart as tiles", () => {
|
|
119
337
|
render(
|
|
120
338
|
<AffectedResourcesDisplay
|
|
121
339
|
monitors={MONITORS}
|
|
@@ -126,21 +344,260 @@ describe("AffectedResourcesDisplay columns", () => {
|
|
|
126
344
|
|
|
127
345
|
const grid: HTMLElement = screen.getByTestId("affected-resources-grid");
|
|
128
346
|
|
|
129
|
-
expect(grid).toHaveClass("
|
|
130
|
-
expect(grid).not.toHaveClass("
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
347
|
+
expect(grid).toHaveClass("divide-y", "divide-gray-100");
|
|
348
|
+
expect(grid).not.toHaveClass("gap-3");
|
|
349
|
+
expect(Array.from(grid.children)).toEqual(sections());
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
test("expanding a category and hitting the cap adds no box either", () => {
|
|
353
|
+
const { container } = render(
|
|
354
|
+
<AffectedResourcesDisplay monitors={buildMonitors(130)} columns={1} />,
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
fireEvent.click(screen.getByRole("button", { name: "Show 96 more" }));
|
|
358
|
+
|
|
359
|
+
expect(
|
|
360
|
+
screen.getByTestId("affected-resource-truncated-note"),
|
|
361
|
+
).toBeInTheDocument();
|
|
362
|
+
expect(cardChromeIn(container)).toEqual([]);
|
|
363
|
+
// The note is tinted text, not a tinted banner.
|
|
364
|
+
expect(
|
|
365
|
+
classTokensWithin(screen.getByTestId("affected-resource-truncated-note")),
|
|
366
|
+
).not.toEqual(expect.arrayContaining(["bg-amber-50"]));
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
test("the empty state is open text inside the card, not a dashed box", () => {
|
|
370
|
+
const { container } = render(<AffectedResourcesDisplay columns={1} />);
|
|
371
|
+
|
|
372
|
+
expect(screen.getByTestId("affected-resources-empty")).toBeInTheDocument();
|
|
373
|
+
expect(cardChromeIn(container)).toEqual([]);
|
|
374
|
+
expect(classTokensWithin(container)).not.toEqual(
|
|
375
|
+
expect.arrayContaining(["border-dashed"]),
|
|
376
|
+
);
|
|
377
|
+
expect(classTokensWithin(container)).not.toEqual(
|
|
378
|
+
expect.arrayContaining(["bg-gray-50/50"]),
|
|
379
|
+
);
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
describe("AffectedResourcesDisplay: category headings", () => {
|
|
384
|
+
const ALL_CATEGORIES: ReactElement = (
|
|
385
|
+
<AffectedResourcesDisplay
|
|
386
|
+
monitors={[buildMonitor(1, "api.acme.com")]}
|
|
387
|
+
hosts={[named(Host, id("c", 1), "web-01")]}
|
|
388
|
+
kubernetesClusters={[
|
|
389
|
+
named(KubernetesCluster, id("e", 1), "prod-eks-eu-west-1"),
|
|
390
|
+
]}
|
|
391
|
+
dockerHosts={[named(DockerHost, id("f", 1), "docker-edge-01")]}
|
|
392
|
+
podmanHosts={[named(PodmanHost, id("1", 1), "podman-01")]}
|
|
393
|
+
proxmoxClusters={[named(ProxmoxCluster, id("2", 1), "pve-lab")]}
|
|
394
|
+
vmwareVCenters={[named(VMwareVCenter, id("3", 1), "vcenter-01")]}
|
|
395
|
+
cephClusters={[named(CephCluster, id("4", 1), "ceph-prod")]}
|
|
396
|
+
dockerSwarmClusters={[named(DockerSwarmCluster, id("5", 1), "swarm-1")]}
|
|
397
|
+
iotFleets={[named(IoTFleet, id("6", 1), "sensors-eu")]}
|
|
398
|
+
databaseServers={[
|
|
399
|
+
named(DatabaseServer, id("7", 1), "PostgreSQL db.prod:5432"),
|
|
400
|
+
]}
|
|
401
|
+
networkSites={[named(NetworkSite, id("9", 1), "Frankfurt DC")]}
|
|
402
|
+
services={[buildService(1, "checkout-api"), buildService(2, "payments")]}
|
|
403
|
+
serviceLevelObjectives={[
|
|
404
|
+
named(ServiceLevelObjective, id("d", 1), "Checkout availability"),
|
|
405
|
+
]}
|
|
406
|
+
columns={1}
|
|
407
|
+
/>
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
/*
|
|
411
|
+
* Label, then the icon tile's tint and the icon's colour. Each pair has a
|
|
412
|
+
* dark-mode remap in Theme.css (see AffectedResourcesDisplayDarkMode in the
|
|
413
|
+
* App tests).
|
|
414
|
+
*/
|
|
415
|
+
const CATEGORIES: Array<[string, string, string]> = [
|
|
416
|
+
["Monitors", "bg-blue-50", "text-blue-600"],
|
|
417
|
+
["Hosts", "bg-emerald-50", "text-emerald-600"],
|
|
418
|
+
["Kubernetes Clusters", "bg-indigo-50", "text-indigo-600"],
|
|
419
|
+
["Docker Hosts", "bg-sky-50", "text-sky-600"],
|
|
420
|
+
["Podman Hosts", "bg-violet-50", "text-violet-600"],
|
|
421
|
+
["Proxmox Clusters", "bg-orange-50", "text-orange-600"],
|
|
422
|
+
["vCenters", "bg-sky-50", "text-sky-600"],
|
|
423
|
+
["Ceph Clusters", "bg-rose-50", "text-rose-600"],
|
|
424
|
+
["Docker Swarm Clusters", "bg-cyan-50", "text-cyan-600"],
|
|
425
|
+
["IoT Fleets", "bg-teal-50", "text-teal-600"],
|
|
426
|
+
["Databases", "bg-purple-50", "text-purple-600"],
|
|
427
|
+
["Network Sites", "bg-indigo-50", "text-indigo-600"],
|
|
428
|
+
["Services", "bg-amber-50", "text-amber-600"],
|
|
429
|
+
["SLOs", "bg-fuchsia-50", "text-fuchsia-600"],
|
|
430
|
+
];
|
|
431
|
+
|
|
432
|
+
test("every category is a level-3 heading naming its label and count, in a fixed order", () => {
|
|
433
|
+
render(ALL_CATEGORIES);
|
|
434
|
+
|
|
435
|
+
expect(headingNames()).toEqual(
|
|
436
|
+
CATEGORIES.map(([label]: [string, string, string]): string => {
|
|
437
|
+
return label === "Services" ? `${label} 2` : `${label} 1`;
|
|
438
|
+
}),
|
|
439
|
+
);
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
test.each(CATEGORIES)(
|
|
443
|
+
"%s has its own tinted icon tile beside the label",
|
|
444
|
+
(label: string, tint: string, iconColour: string) => {
|
|
445
|
+
render(ALL_CATEGORIES);
|
|
446
|
+
|
|
447
|
+
const section: HTMLElement = sections().find(
|
|
448
|
+
(candidate: HTMLElement): boolean => {
|
|
449
|
+
return (
|
|
450
|
+
within(candidate).getByRole("heading", { level: 3 })
|
|
451
|
+
.firstElementChild?.textContent === label
|
|
452
|
+
);
|
|
453
|
+
},
|
|
454
|
+
)!;
|
|
455
|
+
const tile: HTMLElement = section.firstElementChild!
|
|
456
|
+
.firstElementChild as HTMLElement;
|
|
457
|
+
|
|
458
|
+
expect(tile).toHaveClass(
|
|
459
|
+
"flex",
|
|
460
|
+
"h-6",
|
|
461
|
+
"w-6",
|
|
462
|
+
"shrink-0",
|
|
463
|
+
"items-center",
|
|
464
|
+
"justify-center",
|
|
465
|
+
"rounded-md",
|
|
466
|
+
tint,
|
|
467
|
+
);
|
|
468
|
+
expect(tile.querySelector("svg")).toHaveClass(
|
|
469
|
+
"h-3.5",
|
|
470
|
+
"w-3.5",
|
|
471
|
+
iconColour,
|
|
472
|
+
);
|
|
473
|
+
// The tile is not part of the heading: an icon is no part of the name.
|
|
474
|
+
expect(
|
|
475
|
+
within(section).getByRole("heading", { level: 3 }),
|
|
476
|
+
).not.toContainElement(tile);
|
|
477
|
+
},
|
|
478
|
+
);
|
|
479
|
+
|
|
480
|
+
test("each list is named by its heading, so the count is read before the items", () => {
|
|
481
|
+
render(
|
|
482
|
+
<AffectedResourcesDisplay
|
|
483
|
+
monitors={buildMonitors(7)}
|
|
484
|
+
services={SERVICES}
|
|
485
|
+
columns={1}
|
|
486
|
+
/>,
|
|
487
|
+
);
|
|
488
|
+
|
|
489
|
+
const monitors: HTMLElement = screen.getByRole("list", {
|
|
490
|
+
name: "Monitors 7",
|
|
491
|
+
});
|
|
492
|
+
const services: HTMLElement = screen.getByRole("list", {
|
|
493
|
+
name: "Services 1",
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
expect(within(monitors).getAllByRole("listitem")).toHaveLength(4);
|
|
497
|
+
expect(within(services).getAllByRole("listitem")).toHaveLength(1);
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
test("the count covers every item, including those behind Show more", () => {
|
|
501
|
+
render(<AffectedResourcesDisplay monitors={buildMonitors(12)} />);
|
|
502
|
+
|
|
503
|
+
expect(
|
|
504
|
+
screen.getByTestId("affected-resource-category-count"),
|
|
505
|
+
).toHaveTextContent(/^12$/);
|
|
506
|
+
expect(screen.getAllByTestId("affected-resource-item")).toHaveLength(4);
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
test("a four-digit count is grouped the way the locale groups it", () => {
|
|
510
|
+
render(<AffectedResourcesDisplay monitors={buildMonitors(1200)} />);
|
|
511
|
+
|
|
512
|
+
expect(
|
|
513
|
+
screen.getByTestId("affected-resource-category-count"),
|
|
514
|
+
).toHaveTextContent((1200).toLocaleString());
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
test("the label can truncate but the count never shrinks, and it sits right after the label", () => {
|
|
518
|
+
render(<AffectedResourcesDisplay monitors={MONITORS} columns={1} />);
|
|
519
|
+
|
|
520
|
+
const heading: HTMLElement = screen.getByRole("heading", { level: 3 });
|
|
521
|
+
const label: HTMLElement = within(heading).getByText("Monitors");
|
|
522
|
+
const count: HTMLElement = within(heading).getByText("2");
|
|
523
|
+
|
|
524
|
+
expect(heading).toHaveClass("flex", "min-w-0", "flex-1", "items-center");
|
|
525
|
+
expect(label).toHaveClass("min-w-0", "truncate");
|
|
526
|
+
// Not pushed to the far edge: in a wide card that parted it from its label.
|
|
527
|
+
expect(label).not.toHaveClass("flex-1");
|
|
528
|
+
expect(count).toHaveClass("shrink-0", "rounded-full", "tabular-nums");
|
|
529
|
+
expect(label.nextElementSibling).toBe(count);
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
test("the resources are indented under the label, past the icon tile", () => {
|
|
533
|
+
render(<AffectedResourcesDisplay monitors={MONITORS} columns={1} />);
|
|
534
|
+
|
|
535
|
+
// The tile is h-6 w-6 and the header row has gap-2: 24px + 8px = pl-8.
|
|
536
|
+
expect(screen.getByRole("list")).toHaveClass("pl-8");
|
|
537
|
+
expect(screen.getByRole("heading", { level: 3 }).parentElement).toHaveClass(
|
|
538
|
+
"flex",
|
|
539
|
+
"items-center",
|
|
540
|
+
"gap-2",
|
|
541
|
+
);
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
test("hidden categories are left out of the headings", () => {
|
|
545
|
+
render(
|
|
546
|
+
<AffectedResourcesDisplay
|
|
547
|
+
monitors={MONITORS}
|
|
548
|
+
services={SERVICES}
|
|
549
|
+
hideMonitors={true}
|
|
550
|
+
columns={1}
|
|
551
|
+
/>,
|
|
552
|
+
);
|
|
553
|
+
|
|
554
|
+
expect(headingNames()).toEqual(["Services 1"]);
|
|
555
|
+
});
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
describe("AffectedResourcesDisplay: summary", () => {
|
|
559
|
+
test("two or more categories add up to one line above them", () => {
|
|
560
|
+
render(
|
|
561
|
+
<AffectedResourcesDisplay
|
|
562
|
+
monitors={MONITORS}
|
|
563
|
+
services={SERVICES}
|
|
564
|
+
columns={1}
|
|
565
|
+
/>,
|
|
566
|
+
);
|
|
567
|
+
|
|
568
|
+
const summary: HTMLElement = screen.getByTestId(
|
|
569
|
+
"affected-resources-summary",
|
|
570
|
+
);
|
|
571
|
+
|
|
572
|
+
expect(summary).toHaveTextContent("3 resources across 2 categories");
|
|
573
|
+
// The total is the emphasised part.
|
|
574
|
+
expect(within(summary).getByText("3 resources")).toHaveClass(
|
|
575
|
+
"font-semibold",
|
|
576
|
+
"text-gray-900",
|
|
577
|
+
);
|
|
578
|
+
expect(screen.getByText("across 2 categories")).toBe(summary);
|
|
579
|
+
expect(summary.nextElementSibling).toBe(
|
|
580
|
+
screen.getByTestId("affected-resources-grid"),
|
|
581
|
+
);
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
test("a single category counts itself in its heading, so there is no summary", () => {
|
|
585
|
+
render(<AffectedResourcesDisplay monitors={MONITORS} columns={1} />);
|
|
586
|
+
|
|
587
|
+
expect(screen.queryByTestId("affected-resources-summary")).toBeNull();
|
|
588
|
+
expect(screen.queryByText(/across/)).toBeNull();
|
|
589
|
+
expect(headingNames()).toEqual(["Monitors 2"]);
|
|
134
590
|
});
|
|
135
591
|
|
|
136
|
-
test("
|
|
592
|
+
test("the summary reads the same in either layout, with no separator to dangle", () => {
|
|
137
593
|
const { rerender } = render(
|
|
138
594
|
<AffectedResourcesDisplay monitors={MONITORS} services={SERVICES} />,
|
|
139
595
|
);
|
|
140
596
|
|
|
141
|
-
expect(screen.
|
|
142
|
-
|
|
143
|
-
|
|
597
|
+
expect(screen.getByTestId("affected-resources-summary")).toHaveTextContent(
|
|
598
|
+
"3 resources across 2 categories",
|
|
599
|
+
);
|
|
600
|
+
expect(screen.queryByText("·")).toBeNull();
|
|
144
601
|
|
|
145
602
|
rerender(
|
|
146
603
|
<AffectedResourcesDisplay
|
|
@@ -150,23 +607,42 @@ describe("AffectedResourcesDisplay columns", () => {
|
|
|
150
607
|
/>,
|
|
151
608
|
);
|
|
152
609
|
|
|
153
|
-
expect(screen.
|
|
154
|
-
|
|
155
|
-
|
|
610
|
+
expect(screen.getByTestId("affected-resources-summary")).toHaveTextContent(
|
|
611
|
+
"3 resources across 2 categories",
|
|
612
|
+
);
|
|
156
613
|
expect(screen.queryByText("·")).toBeNull();
|
|
157
614
|
});
|
|
158
615
|
|
|
159
|
-
test("
|
|
616
|
+
test("a hidden category is not added up", () => {
|
|
160
617
|
render(
|
|
161
|
-
<AffectedResourcesDisplay
|
|
618
|
+
<AffectedResourcesDisplay
|
|
619
|
+
monitors={MONITORS}
|
|
620
|
+
services={SERVICES}
|
|
621
|
+
hosts={[named(Host, id("c", 1), "web-01")]}
|
|
622
|
+
hideHosts={true}
|
|
623
|
+
/>,
|
|
162
624
|
);
|
|
163
625
|
|
|
164
|
-
expect(screen.
|
|
165
|
-
|
|
626
|
+
expect(screen.getByTestId("affected-resources-summary")).toHaveTextContent(
|
|
627
|
+
"3 resources across 2 categories",
|
|
628
|
+
);
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
test("large totals are grouped the way the locale groups them", () => {
|
|
632
|
+
render(
|
|
633
|
+
<AffectedResourcesDisplay
|
|
634
|
+
monitors={buildMonitors(1500)}
|
|
635
|
+
services={SERVICES}
|
|
636
|
+
/>,
|
|
637
|
+
);
|
|
638
|
+
|
|
639
|
+
expect(screen.getByTestId("affected-resources-summary")).toHaveTextContent(
|
|
640
|
+
`${(1501).toLocaleString()} resources across 2 categories`,
|
|
641
|
+
);
|
|
166
642
|
});
|
|
167
643
|
});
|
|
168
644
|
|
|
169
|
-
describe("AffectedResourcesDisplay
|
|
645
|
+
describe("AffectedResourcesDisplay: rows", () => {
|
|
170
646
|
test("every item carries its full name as a title", () => {
|
|
171
647
|
render(
|
|
172
648
|
<AffectedResourcesDisplay
|
|
@@ -194,7 +670,6 @@ describe("AffectedResourcesDisplay item names", () => {
|
|
|
194
670
|
|
|
195
671
|
expect(item).toHaveClass(
|
|
196
672
|
"min-w-0",
|
|
197
|
-
"flex-1",
|
|
198
673
|
"truncate",
|
|
199
674
|
"[&_span.flex]:block",
|
|
200
675
|
"[&_span.flex]:truncate",
|
|
@@ -206,10 +681,86 @@ describe("AffectedResourcesDisplay item names", () => {
|
|
|
206
681
|
|
|
207
682
|
expect(nameSpan).not.toBeNull();
|
|
208
683
|
expect(nameSpan).toHaveTextContent(LONG_MONITOR_NAME);
|
|
209
|
-
expect(link).toHaveAttribute(
|
|
210
|
-
|
|
211
|
-
|
|
684
|
+
expect(link).toHaveAttribute("href", expect.stringContaining(id("a", 1)));
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
test("the link is stretched over its whole row, so the row that highlights is the row that opens", () => {
|
|
688
|
+
render(<AffectedResourcesDisplay monitors={MONITORS} columns={1} />);
|
|
689
|
+
|
|
690
|
+
const item: HTMLElement = screen.getByTitle(LONG_MONITOR_NAME);
|
|
691
|
+
const row: HTMLElement = item.closest("li")!;
|
|
692
|
+
|
|
693
|
+
expect(item.className).toBe(AFFECTED_RESOURCE_ITEM_CLASS_NAME);
|
|
694
|
+
expect(item).toHaveClass(
|
|
695
|
+
"[&_a]:after:absolute",
|
|
696
|
+
"[&_a]:after:inset-0",
|
|
697
|
+
"[&_a]:after:rounded-md",
|
|
212
698
|
);
|
|
699
|
+
// The row is what the link's ::after fills: positioned, and hoverable.
|
|
700
|
+
expect(row).toHaveClass("relative", "rounded-md", "hover:bg-gray-50");
|
|
701
|
+
/*
|
|
702
|
+
* Nothing between the row and the link may be positioned, or the ::after
|
|
703
|
+
* would fill that element instead of the row.
|
|
704
|
+
*/
|
|
705
|
+
let node: HTMLElement | null = within(item).getByRole("link");
|
|
706
|
+
while (node && node !== row) {
|
|
707
|
+
expect(node.className.split(" ")).not.toEqual(
|
|
708
|
+
expect.arrayContaining(["relative"]),
|
|
709
|
+
);
|
|
710
|
+
node = node.parentElement;
|
|
711
|
+
}
|
|
712
|
+
// One link per row: the stretched one.
|
|
713
|
+
expect(within(row).getAllByRole("link")).toHaveLength(1);
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
test("keyboard focus draws a ring around the row, not a clipped outline round the name", () => {
|
|
717
|
+
render(<AffectedResourcesDisplay monitors={MONITORS} columns={1} />);
|
|
718
|
+
|
|
719
|
+
expect(screen.getByTitle(LONG_MONITOR_NAME)).toHaveClass(
|
|
720
|
+
"[&_a:focus-visible]:outline-none",
|
|
721
|
+
"[&_a:focus-visible]:after:ring-2",
|
|
722
|
+
"[&_a:focus-visible]:after:ring-indigo-500",
|
|
723
|
+
);
|
|
724
|
+
});
|
|
725
|
+
|
|
726
|
+
/*
|
|
727
|
+
* Tailwind v3 applies stacked variants right to left, so
|
|
728
|
+
* "[&_a]:focus-visible:x" would style an <a> inside a focused wrapper,
|
|
729
|
+
* which never happens. The focused link has to be in the arbitrary variant.
|
|
730
|
+
*/
|
|
731
|
+
test("no class stacks a pseudo-class after the descendant variant", () => {
|
|
732
|
+
for (const token of AFFECTED_RESOURCE_ITEM_CLASS_NAME.split(" ")) {
|
|
733
|
+
expect(token).not.toMatch(/^\[&_a\]:(focus|hover|active)/);
|
|
734
|
+
}
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
test("the row's hover sits flush with the dividers on the right", () => {
|
|
738
|
+
render(<AffectedResourcesDisplay monitors={MONITORS} columns={1} />);
|
|
739
|
+
|
|
740
|
+
const row: HTMLElement = screen
|
|
741
|
+
.getByTitle(LONG_MONITOR_NAME)
|
|
742
|
+
.closest("li")!;
|
|
743
|
+
|
|
744
|
+
// Pulled left by its own padding so the name lines up with the label...
|
|
745
|
+
expect(row).toHaveClass("-ml-2", "px-2");
|
|
746
|
+
// ...but not past the right edge, where the dividers and counts end.
|
|
747
|
+
expect(row).not.toHaveClass("-mx-2");
|
|
748
|
+
expect(row).not.toHaveClass("-mr-2");
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
test("the old chevron is gone: the whole row says it is a link", () => {
|
|
752
|
+
const { container } = render(
|
|
753
|
+
<AffectedResourcesDisplay monitors={MONITORS} columns={1} />,
|
|
754
|
+
);
|
|
755
|
+
|
|
756
|
+
for (const row of Array.from(container.querySelectorAll("li"))) {
|
|
757
|
+
// Only the element inside the link draws anything.
|
|
758
|
+
expect(row.children).toHaveLength(1);
|
|
759
|
+
expect(row.firstElementChild).toHaveAttribute(
|
|
760
|
+
"data-testid",
|
|
761
|
+
"affected-resource-item",
|
|
762
|
+
);
|
|
763
|
+
}
|
|
213
764
|
});
|
|
214
765
|
|
|
215
766
|
test("a service name truncates beside its colour swatch", () => {
|
|
@@ -231,41 +782,289 @@ describe("AffectedResourcesDisplay item names", () => {
|
|
|
231
782
|
);
|
|
232
783
|
});
|
|
233
784
|
|
|
234
|
-
test("
|
|
235
|
-
|
|
785
|
+
test("a resource without an id is named without a link, so there is nothing to stretch", () => {
|
|
786
|
+
const unsaved: Host = new Host();
|
|
787
|
+
unsaved.name = "Unsaved host";
|
|
788
|
+
|
|
789
|
+
render(<AffectedResourcesDisplay hosts={[unsaved]} columns={1} />);
|
|
790
|
+
|
|
791
|
+
const item: HTMLElement = screen.getByTitle("Unsaved host");
|
|
792
|
+
|
|
793
|
+
expect(within(item).queryByRole("link")).toBeNull();
|
|
794
|
+
expect(item).toHaveTextContent("Unsaved host");
|
|
795
|
+
});
|
|
796
|
+
});
|
|
797
|
+
|
|
798
|
+
describe("AffectedResourcesDisplay: Show more", () => {
|
|
799
|
+
test("four resources fit without a toggle", () => {
|
|
800
|
+
render(<AffectedResourcesDisplay monitors={buildMonitors(4)} />);
|
|
801
|
+
|
|
802
|
+
expect(screen.getAllByTestId("affected-resource-item")).toHaveLength(4);
|
|
803
|
+
expect(screen.queryByRole("button")).toBeNull();
|
|
804
|
+
});
|
|
805
|
+
|
|
806
|
+
test("a fifth resource waits behind 'Show 1 more'", () => {
|
|
807
|
+
render(<AffectedResourcesDisplay monitors={buildMonitors(5)} />);
|
|
808
|
+
|
|
809
|
+
expect(screen.getAllByTestId("affected-resource-item")).toHaveLength(4);
|
|
810
|
+
expect(
|
|
811
|
+
screen.getByRole("button", { name: "Show 1 more" }),
|
|
812
|
+
).toBeInTheDocument();
|
|
813
|
+
expect(screen.queryByText("probe-005")).toBeNull();
|
|
814
|
+
});
|
|
815
|
+
|
|
816
|
+
test("the toggle expands and collapses its list, and says so", () => {
|
|
817
|
+
render(<AffectedResourcesDisplay monitors={buildMonitors(7)} />);
|
|
818
|
+
|
|
819
|
+
const list: HTMLElement = screen.getByRole("list", { name: "Monitors 7" });
|
|
820
|
+
const toggle: HTMLElement = screen.getByRole("button", {
|
|
821
|
+
name: "Show 3 more",
|
|
822
|
+
});
|
|
823
|
+
|
|
824
|
+
expect(toggle).toHaveAttribute("type", "button");
|
|
825
|
+
expect(toggle).toHaveAttribute("aria-expanded", "false");
|
|
826
|
+
expect(toggle).toHaveAttribute("aria-controls", list.id);
|
|
827
|
+
expect(list.id).not.toBe("");
|
|
828
|
+
|
|
829
|
+
fireEvent.click(toggle);
|
|
830
|
+
|
|
831
|
+
expect(within(list).getAllByRole("listitem")).toHaveLength(7);
|
|
832
|
+
expect(screen.getByText("probe-007")).toBeInTheDocument();
|
|
833
|
+
expect(toggle).toHaveAttribute("aria-expanded", "true");
|
|
834
|
+
expect(toggle).toHaveTextContent("Show less");
|
|
835
|
+
|
|
836
|
+
fireEvent.click(screen.getByRole("button", { name: "Show less" }));
|
|
837
|
+
|
|
838
|
+
expect(within(list).getAllByRole("listitem")).toHaveLength(4);
|
|
839
|
+
expect(screen.queryByText("probe-007")).toBeNull();
|
|
840
|
+
expect(screen.getByRole("button", { name: "Show 3 more" })).toHaveAttribute(
|
|
841
|
+
"aria-expanded",
|
|
842
|
+
"false",
|
|
843
|
+
);
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
test("the toggle is a quiet inline control lined up with the names, not a footer bar", () => {
|
|
847
|
+
render(<AffectedResourcesDisplay monitors={buildMonitors(7)} />);
|
|
848
|
+
|
|
849
|
+
const toggle: HTMLElement = screen.getByRole("button", {
|
|
850
|
+
name: "Show 3 more",
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
// ml-6 plus its own px-2 puts its text on the names' pl-8 line.
|
|
854
|
+
expect(toggle).toHaveClass(
|
|
855
|
+
"ml-6",
|
|
856
|
+
"px-2",
|
|
857
|
+
"inline-flex",
|
|
858
|
+
"text-xs",
|
|
859
|
+
"text-indigo-600",
|
|
860
|
+
);
|
|
861
|
+
expect(toggle).not.toHaveClass("w-full");
|
|
862
|
+
expect(cardChromeIn(toggle)).toEqual([]);
|
|
863
|
+
});
|
|
864
|
+
|
|
865
|
+
test("each category keeps its own toggle", () => {
|
|
866
|
+
render(
|
|
867
|
+
<AffectedResourcesDisplay
|
|
868
|
+
monitors={buildMonitors(6)}
|
|
869
|
+
services={[1, 2, 3, 4, 5].map((n: number): Service => {
|
|
870
|
+
return buildService(n, `service-${n}`);
|
|
871
|
+
})}
|
|
872
|
+
/>,
|
|
873
|
+
);
|
|
874
|
+
|
|
875
|
+
fireEvent.click(screen.getByRole("button", { name: "Show 2 more" }));
|
|
876
|
+
|
|
877
|
+
expect(
|
|
878
|
+
within(screen.getByRole("list", { name: "Monitors 6" })).getAllByRole(
|
|
879
|
+
"listitem",
|
|
880
|
+
),
|
|
881
|
+
).toHaveLength(6);
|
|
882
|
+
expect(
|
|
883
|
+
within(screen.getByRole("list", { name: "Services 5" })).getAllByRole(
|
|
884
|
+
"listitem",
|
|
885
|
+
),
|
|
886
|
+
).toHaveLength(4);
|
|
887
|
+
expect(screen.getByRole("button", { name: "Show 1 more" })).toHaveAttribute(
|
|
888
|
+
"aria-expanded",
|
|
889
|
+
"false",
|
|
890
|
+
);
|
|
891
|
+
});
|
|
892
|
+
|
|
893
|
+
test("past 100 rows the rest is counted in a note instead of rendered", () => {
|
|
894
|
+
render(<AffectedResourcesDisplay monitors={buildMonitors(130)} />);
|
|
895
|
+
|
|
896
|
+
// The toggle offers only what it will render.
|
|
897
|
+
fireEvent.click(screen.getByRole("button", { name: "Show 96 more" }));
|
|
898
|
+
|
|
899
|
+
expect(screen.getAllByTestId("affected-resource-item")).toHaveLength(100);
|
|
900
|
+
expect(screen.getByText("probe-100")).toBeInTheDocument();
|
|
901
|
+
expect(screen.queryByText("probe-101")).toBeNull();
|
|
236
902
|
|
|
237
|
-
const
|
|
238
|
-
|
|
903
|
+
const note: HTMLElement = screen.getByTestId(
|
|
904
|
+
"affected-resource-truncated-note",
|
|
905
|
+
);
|
|
906
|
+
|
|
907
|
+
expect(note).toHaveTextContent(
|
|
908
|
+
"Showing the first 100 of 130. 30 more attached — edit affected resources to manage the full list.",
|
|
909
|
+
);
|
|
910
|
+
// Lined up with the names, and a div: the icon renders a <div> of its own.
|
|
911
|
+
expect(note.tagName).toBe("DIV");
|
|
912
|
+
expect(note).toHaveClass("ml-8", "text-amber-700");
|
|
913
|
+
// The count still covers every item.
|
|
914
|
+
expect(
|
|
915
|
+
screen.getByTestId("affected-resource-category-count"),
|
|
916
|
+
).toHaveTextContent(/^130$/);
|
|
917
|
+
|
|
918
|
+
fireEvent.click(screen.getByRole("button", { name: "Show less" }));
|
|
919
|
+
|
|
920
|
+
expect(screen.getAllByTestId("affected-resource-item")).toHaveLength(4);
|
|
921
|
+
expect(screen.queryByTestId("affected-resource-truncated-note")).toBeNull();
|
|
922
|
+
});
|
|
923
|
+
|
|
924
|
+
test("exactly 100 rows expand fully with no note", () => {
|
|
925
|
+
render(<AffectedResourcesDisplay monitors={buildMonitors(100)} />);
|
|
926
|
+
|
|
927
|
+
fireEvent.click(screen.getByRole("button", { name: "Show 96 more" }));
|
|
928
|
+
|
|
929
|
+
expect(screen.getAllByTestId("affected-resource-item")).toHaveLength(100);
|
|
930
|
+
expect(screen.queryByTestId("affected-resource-truncated-note")).toBeNull();
|
|
931
|
+
});
|
|
932
|
+
});
|
|
933
|
+
|
|
934
|
+
describe("AffectedResourcesDisplay: empty state", () => {
|
|
935
|
+
test("says nothing is affected and how to attach resources", () => {
|
|
936
|
+
render(<AffectedResourcesDisplay columns={1} />);
|
|
937
|
+
|
|
938
|
+
const empty: HTMLElement = screen.getByTestId("affected-resources-empty");
|
|
939
|
+
|
|
940
|
+
expect(within(empty).getByText("No resources affected.")).toHaveClass(
|
|
941
|
+
"text-sm",
|
|
942
|
+
"font-medium",
|
|
943
|
+
"text-gray-900",
|
|
944
|
+
);
|
|
945
|
+
expect(empty).toHaveTextContent(
|
|
946
|
+
"Attach monitors, hosts, clusters, or services to track which parts of your infrastructure are impacted.",
|
|
947
|
+
);
|
|
948
|
+
expect(screen.queryByTestId("affected-resources-grid")).toBeNull();
|
|
949
|
+
expect(screen.queryByTestId("affected-resources-summary")).toBeNull();
|
|
950
|
+
});
|
|
951
|
+
|
|
952
|
+
test("a caller's own message replaces the default", () => {
|
|
953
|
+
render(
|
|
954
|
+
<AffectedResourcesDisplay columns={1} emptyMessage="Nothing hit." />,
|
|
955
|
+
);
|
|
956
|
+
|
|
957
|
+
expect(screen.getByText("Nothing hit.")).toBeInTheDocument();
|
|
958
|
+
expect(screen.queryByText("No resources affected.")).toBeNull();
|
|
959
|
+
});
|
|
960
|
+
|
|
961
|
+
test("the empty state does not depend on columns", () => {
|
|
962
|
+
render(
|
|
963
|
+
<AffectedResourcesDisplay columns={1} emptyMessage="Nothing hit." />,
|
|
964
|
+
);
|
|
965
|
+
|
|
966
|
+
expect(screen.getByText("Nothing hit.")).toBeInTheDocument();
|
|
967
|
+
expect(screen.queryByTestId("affected-resources-grid")).toBeNull();
|
|
968
|
+
});
|
|
969
|
+
|
|
970
|
+
test("its icon sits in a plain tinted circle, with no ring or shadow", () => {
|
|
971
|
+
render(<AffectedResourcesDisplay columns={1} />);
|
|
972
|
+
|
|
973
|
+
const circle: HTMLElement = screen.getByTestId("affected-resources-empty")
|
|
974
|
+
.firstElementChild as HTMLElement;
|
|
975
|
+
|
|
976
|
+
expect(circle.tagName).toBe("DIV");
|
|
977
|
+
expect(circle).toHaveClass("rounded-full", "bg-gray-100");
|
|
978
|
+
expect(circle).not.toHaveClass("bg-white", "shadow-sm", "ring-1");
|
|
979
|
+
});
|
|
980
|
+
|
|
981
|
+
test("only a caller that shows SLOs promises that burn rate rules link them", () => {
|
|
982
|
+
const SLO_HINT: RegExp =
|
|
983
|
+
/SLOs are linked automatically when their burn rate rules fire\./;
|
|
984
|
+
|
|
985
|
+
// The incident and alert pages pass their SLOs, even an empty list.
|
|
986
|
+
render(<AffectedResourcesDisplay serviceLevelObjectives={[]} />);
|
|
987
|
+
expect(screen.getByText(SLO_HINT)).toBeInTheDocument();
|
|
988
|
+
cleanup();
|
|
989
|
+
|
|
990
|
+
// Scheduled maintenance and the templates never link an SLO.
|
|
991
|
+
render(<AffectedResourcesDisplay monitors={[]} services={[]} />);
|
|
992
|
+
expect(screen.queryByText(SLO_HINT)).toBeNull();
|
|
993
|
+
cleanup();
|
|
239
994
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
995
|
+
// Nor does a caller that hides them.
|
|
996
|
+
render(
|
|
997
|
+
<AffectedResourcesDisplay
|
|
998
|
+
serviceLevelObjectives={[]}
|
|
999
|
+
hideServiceLevelObjectives={true}
|
|
1000
|
+
/>,
|
|
1001
|
+
);
|
|
1002
|
+
expect(screen.queryByText(SLO_HINT)).toBeNull();
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
test("resources a caller hides do not count, so everything hidden is empty", () => {
|
|
1006
|
+
render(
|
|
1007
|
+
<AffectedResourcesDisplay
|
|
1008
|
+
monitors={MONITORS}
|
|
1009
|
+
services={SERVICES}
|
|
1010
|
+
hideMonitors={true}
|
|
1011
|
+
hideServices={true}
|
|
1012
|
+
/>,
|
|
1013
|
+
);
|
|
1014
|
+
|
|
1015
|
+
expect(screen.getByText("No resources affected.")).toBeInTheDocument();
|
|
1016
|
+
expect(screen.queryByRole("heading", { level: 3 })).toBeNull();
|
|
1017
|
+
});
|
|
1018
|
+
});
|
|
1019
|
+
|
|
1020
|
+
describe("AffectedResourcesDisplay columns", () => {
|
|
1021
|
+
test("renders today's two-column grid when columns is left out", () => {
|
|
1022
|
+
render(
|
|
1023
|
+
<AffectedResourcesDisplay monitors={MONITORS} services={SERVICES} />,
|
|
1024
|
+
);
|
|
1025
|
+
|
|
1026
|
+
const grid: HTMLElement = screen.getByTestId("affected-resources-grid");
|
|
1027
|
+
|
|
1028
|
+
expect(grid).toHaveClass("grid", "grid-cols-1", "md:grid-cols-2");
|
|
1029
|
+
expect(grid.children).toHaveLength(2);
|
|
1030
|
+
});
|
|
1031
|
+
|
|
1032
|
+
test("renders one column for a narrow sidebar", () => {
|
|
1033
|
+
render(
|
|
1034
|
+
<AffectedResourcesDisplay
|
|
1035
|
+
monitors={MONITORS}
|
|
1036
|
+
services={SERVICES}
|
|
1037
|
+
columns={1}
|
|
1038
|
+
/>,
|
|
1039
|
+
);
|
|
1040
|
+
|
|
1041
|
+
const grid: HTMLElement = screen.getByTestId("affected-resources-grid");
|
|
1042
|
+
|
|
1043
|
+
expect(grid).toHaveClass("grid", "grid-cols-1", "divide-y");
|
|
1044
|
+
expect(grid).not.toHaveClass("md:grid-cols-2");
|
|
1045
|
+
// Both categories still render, one under the other.
|
|
1046
|
+
expect(within(grid).getByText("Monitors")).toBeInTheDocument();
|
|
1047
|
+
expect(within(grid).getByText("Services")).toBeInTheDocument();
|
|
243
1048
|
});
|
|
244
1049
|
});
|
|
245
1050
|
|
|
246
1051
|
describe("AffectedResourcesDisplay databases", () => {
|
|
247
|
-
const DATABASE_ID: string = "
|
|
1052
|
+
const DATABASE_ID: string = id("d", 9);
|
|
248
1053
|
|
|
249
|
-
const buildDatabase: (
|
|
250
|
-
|
|
1054
|
+
const buildDatabase: (databaseId: string, name: string) => DatabaseServer = (
|
|
1055
|
+
databaseId: string,
|
|
251
1056
|
name: string,
|
|
252
1057
|
): DatabaseServer => {
|
|
253
|
-
|
|
254
|
-
database._id = id;
|
|
255
|
-
database.name = name;
|
|
256
|
-
return database;
|
|
1058
|
+
return named(DatabaseServer, databaseId, name);
|
|
257
1059
|
};
|
|
258
1060
|
|
|
259
|
-
test("attached databases get their own
|
|
1061
|
+
test("attached databases get their own section, counted with the rest", () => {
|
|
260
1062
|
render(
|
|
261
1063
|
<AffectedResourcesDisplay
|
|
262
1064
|
monitors={MONITORS}
|
|
263
1065
|
databaseServers={[
|
|
264
1066
|
buildDatabase(DATABASE_ID, "PostgreSQL db.prod:5432"),
|
|
265
|
-
buildDatabase(
|
|
266
|
-
"dddddddd-dddd-4ddd-8ddd-ddddddddddd2",
|
|
267
|
-
"Redis cache.prod:6379",
|
|
268
|
-
),
|
|
1067
|
+
buildDatabase(id("d", 8), "Redis cache.prod:6379"),
|
|
269
1068
|
]}
|
|
270
1069
|
/>,
|
|
271
1070
|
);
|
|
@@ -305,8 +1104,7 @@ describe("AffectedResourcesDisplay databases", () => {
|
|
|
305
1104
|
);
|
|
306
1105
|
|
|
307
1106
|
expect(screen.queryByText("Nothing hit.")).toBeNull();
|
|
308
|
-
expect(
|
|
309
|
-
expect(screen.getByText("across 1 category")).toBeInTheDocument();
|
|
1107
|
+
expect(headingNames()).toEqual(["Databases 1"]);
|
|
310
1108
|
});
|
|
311
1109
|
|
|
312
1110
|
test("the table cell lists a database beside the other resources", () => {
|
|
@@ -326,7 +1124,7 @@ describe("AffectedResourcesDisplay databases", () => {
|
|
|
326
1124
|
);
|
|
327
1125
|
});
|
|
328
1126
|
|
|
329
|
-
test("hideDatabaseServers drops the
|
|
1127
|
+
test("hideDatabaseServers drops the section", () => {
|
|
330
1128
|
render(
|
|
331
1129
|
<AffectedResourcesDisplay
|
|
332
1130
|
monitors={MONITORS}
|
|
@@ -337,6 +1135,6 @@ describe("AffectedResourcesDisplay databases", () => {
|
|
|
337
1135
|
|
|
338
1136
|
expect(screen.queryByText("Databases")).toBeNull();
|
|
339
1137
|
expect(screen.queryByText("MySQL orders:3306")).toBeNull();
|
|
340
|
-
expect(
|
|
1138
|
+
expect(headingNames()).toEqual(["Monitors 2"]);
|
|
341
1139
|
});
|
|
342
1140
|
});
|