@oneuptime/common 11.7.2 → 11.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/AnalyticsModels/KubernetesCostAllocation.ts +103 -0
- package/Models/DatabaseModels/AlertEpisodeStateTimeline.ts +1 -0
- package/Models/DatabaseModels/AlertStateTimeline.ts +1 -0
- package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
- package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
- package/Models/DatabaseModels/Index.ts +5 -0
- package/Models/DatabaseModels/LogDropFilter.ts +89 -0
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +13 -3
- package/Models/DatabaseModels/RecommendationDismissal.ts +463 -0
- package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
- package/Models/DatabaseModels/StatusPageGroup.ts +95 -0
- package/Models/DatabaseModels/TableView.ts +40 -0
- package/Models/DatabaseModels/TraceDropFilter.ts +89 -0
- package/Models/DatabaseModels/WorkflowVariable.ts +5 -1
- package/Server/API/AlertAPI.ts +32 -17
- package/Server/API/BaseAPI.ts +31 -2
- package/Server/API/BaseAnalyticsAPI.ts +36 -2
- package/Server/API/CommonAPI.ts +57 -0
- package/Server/API/IncidentAPI.ts +60 -33
- package/Server/API/IncidentEpisodeAPI.ts +31 -16
- package/Server/API/MonitorAPI.ts +30 -0
- package/Server/API/MonitorTemplateAPI.ts +8 -0
- package/Server/API/ProbeAPI.ts +196 -15
- package/Server/API/ProjectAPI.ts +79 -1
- package/Server/API/ScheduledMaintenanceAPI.ts +33 -18
- package/Server/API/StatusPageAPI.ts +74 -37
- package/Server/API/WorkspaceNotificationRuleAPI.ts +34 -4
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.ts +13 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.ts +527 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.ts +55 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.ts +53 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Services/AlertEpisodeService.ts +47 -0
- package/Server/Services/AlertService.ts +125 -0
- package/Server/Services/BillingService.ts +98 -0
- package/Server/Services/DatabaseService.ts +184 -20
- package/Server/Services/IncidentEpisodeService.ts +47 -0
- package/Server/Services/IncidentService.ts +123 -0
- package/Server/Services/IncidentTemplateService.ts +123 -1
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/LogDropFilterService.ts +133 -0
- package/Server/Services/MonitorProbeService.ts +94 -4
- package/Server/Services/MonitorService.ts +48 -43
- package/Server/Services/NetworkDeviceDiscoveryScanService.ts +70 -0
- package/Server/Services/ProbeService.ts +66 -0
- package/Server/Services/ProjectService.ts +131 -7
- package/Server/Services/RecommendationDismissalService.ts +52 -0
- package/Server/Services/RunbookAgentJobService.ts +68 -7
- package/Server/Services/ScheduledMaintenanceService.ts +103 -0
- package/Server/Services/ScheduledMaintenanceTemplateService.ts +90 -0
- package/Server/Services/StatusPageGroupService.ts +186 -0
- package/Server/Services/TraceDropFilterService.ts +133 -0
- package/Server/Types/Workflow/Components/API/Delete.ts +12 -0
- package/Server/Types/Workflow/Components/API/Get.ts +12 -0
- package/Server/Types/Workflow/Components/API/Patch.ts +12 -0
- package/Server/Types/Workflow/Components/API/Post.ts +12 -0
- package/Server/Types/Workflow/Components/API/Put.ts +13 -0
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +212 -0
- package/Server/Utils/DropFilterValidation.ts +127 -0
- package/Server/Utils/Errors.ts +5 -0
- package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
- package/Server/Utils/Monitor/MonitorIncident.ts +31 -2
- package/Server/Utils/Telemetry/AppMetrics.ts +31 -0
- package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +16 -0
- package/Tests/Models/DatabaseModels/MonitorProbeColumnAccessControl.test.ts +196 -0
- package/Tests/Models/RecommendationDismissalModel.test.ts +269 -0
- package/Tests/Server/API/BaseAPIUpdatePayloadValidation.test.ts +320 -0
- package/Tests/Server/API/BaseAnalyticsAPIUpdatePayloadValidation.test.ts +293 -0
- package/Tests/Server/API/CommonAPIAuthGuard.test.ts +164 -0
- package/Tests/Server/API/ProbeAPI.test.ts +422 -53
- package/Tests/Server/API/ProjectAPI.test.ts +180 -0
- package/Tests/Server/API/ProjectAPIExtendTrialBillingDisabled.test.ts +138 -0
- package/Tests/Server/API/ProjectScopedCustomRouteAuth.test.ts +458 -0
- package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +359 -0
- package/Tests/Server/Infrastructure/ProcessSignalDelivery.test.ts +427 -0
- package/Tests/Server/Services/BillingServiceExtendTrial.test.ts +439 -0
- package/Tests/Server/Services/CrossProjectReferenceWriteGuard.test.ts +810 -0
- package/Tests/Server/Services/DatabaseServiceAtomicAddToColumns.test.ts +269 -0
- package/Tests/Server/Services/DatabaseServiceEmptyUpdate.test.ts +277 -0
- package/Tests/Server/Services/DatabaseServiceSortColumnSelect.test.ts +201 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +81 -23
- package/Tests/Server/Services/DropFilterSaveValidation.test.ts +398 -0
- package/Tests/Server/Services/MonitorProbeDeleteHooks.test.ts +280 -0
- package/Tests/Server/Services/MonitorProbeServiceProbeTenancy.test.ts +304 -0
- package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +262 -0
- package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +614 -0
- package/Tests/Server/Services/RecommendationDismissalService.test.ts +306 -0
- package/Tests/Server/Services/RepairCrossProjectIncidentReferencesMigration.test.ts +528 -0
- package/Tests/Server/Services/StatusPageGroupNesting.test.ts +395 -0
- package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +26 -21
- package/Tests/Server/Types/Database/Permissions/WorkflowVariableColumnPermission.test.ts +227 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +285 -0
- package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +463 -0
- package/Tests/Server/Utils/DropFilterValidation.test.ts +269 -0
- package/Tests/Server/Utils/Telemetry/SpanUtil.test.ts +94 -0
- package/Tests/Types/DateUserTimezone.test.ts +52 -0
- package/Tests/Types/JSONFunctions.test.ts +103 -1
- package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +177 -9
- package/Tests/Types/Monitor/MonitorStepDnsMonitor.test.ts +105 -0
- package/Tests/Types/Monitor/MonitorStepDnssecMonitor.test.ts +131 -0
- package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +60 -0
- package/Tests/Types/Monitor/MonitorStepExternalStatusPageMonitor.test.ts +82 -0
- package/Tests/Types/Monitor/MonitorStepInfrastructureMonitors.test.ts +268 -0
- package/Tests/Types/Monitor/MonitorStepMetricMonitor.test.ts +386 -0
- package/Tests/Types/Monitor/MonitorStepProfileMonitor.test.ts +185 -0
- package/Tests/Types/Monitor/MonitorStepSnmpMonitor.test.ts +156 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +371 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +901 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +607 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +754 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +960 -0
- package/Tests/Types/RollingTime/RollingTimeUtil.test.ts +186 -0
- package/Tests/Types/Runbook/RunbookStepTimeout.test.ts +410 -0
- package/Tests/Types/Telemetry/DropFilterSampling.test.ts +241 -0
- package/Tests/Types/Workspace/NotificationRuleConditionUtil.test.ts +353 -0
- package/Tests/Types/Workspace/NotificationRuleUtil.test.ts +566 -0
- package/Tests/UI/Components/CodeEditor.test.tsx +174 -0
- package/Tests/UI/Components/ErrorBoundary.test.tsx +555 -24
- package/Tests/UI/Components/InfoCard.test.tsx +358 -0
- package/Tests/UI/Components/LogTimeRangePicker.test.tsx +138 -0
- package/Tests/UI/Components/Modal.test.tsx +43 -5
- package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +679 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +397 -0
- package/Tests/UI/Components/ModelTable/ColumnCustomizationModal.test.tsx +999 -0
- package/Tests/UI/Components/ModelTable/ColumnPreference.test.ts +1678 -0
- package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1094 -0
- package/Tests/UI/Components/Runbook/StepTimeoutInput.test.tsx +386 -0
- package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +671 -0
- package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +404 -0
- package/Tests/UI/Utils/DropdownAlignment.test.ts +306 -0
- package/Tests/UI/Utils/TableFilterUrlState.test.ts +292 -0
- package/Tests/Utils/Monitor/MonitorSummaryProbeUtil.test.ts +263 -0
- package/Tests/Utils/NetworkDiscovery/ScanTargetUtil.test.ts +583 -0
- package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +1072 -0
- package/Tests/Utils/StatusPage/GroupTree.test.ts +583 -0
- package/Tests/Utils/StatusPage/ResourceUptime.test.ts +411 -0
- package/Tests/Utils/UserPreferences.test.ts +563 -0
- package/Types/Date.ts +15 -6
- package/Types/JSONFunctions.ts +7 -2
- package/Types/Kubernetes/KubernetesCostIngest.ts +37 -1
- package/Types/Monitor/KubernetesAlertTemplates.ts +205 -0
- package/Types/Monitor/MonitorStep.ts +10 -1
- package/Types/Monitor/MonitorStepMetricMonitor.ts +46 -1
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +413 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +168 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +175 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +743 -0
- package/Types/Permission.ts +45 -0
- package/Types/Recommendation/RecommendationType.ts +20 -0
- package/Types/Runbook/RunbookExecutionDeadline.ts +129 -0
- package/Types/Runbook/RunbookStepTimeout.ts +202 -0
- package/Types/Telemetry/DropFilterSampling.ts +92 -0
- package/UI/Components/AI/GenerateFromAIModal.tsx +0 -2
- package/UI/Components/Accordion/Accordion.tsx +10 -2
- package/UI/Components/BulkUpdate/BulkLabelActions.tsx +0 -1
- package/UI/Components/CodeEditor/CodeEditor.tsx +34 -20
- package/UI/Components/Date/RangeStartAndEndDateView.tsx +0 -1
- package/UI/Components/EditionLabel/EditionLabel.tsx +1 -27
- package/UI/Components/Error/PageError.tsx +0 -4
- package/UI/Components/ErrorBoundary.tsx +252 -15
- package/UI/Components/InfoCard/InfoCard.tsx +58 -1
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +34 -1
- package/UI/Components/MasterPage/MasterPage.tsx +65 -0
- package/UI/Components/Modal/Modal.tsx +16 -60
- package/UI/Components/ModelFormModal/ModelFormModal.tsx +0 -8
- package/UI/Components/ModelTable/BaseModelTable.tsx +503 -71
- package/UI/Components/ModelTable/Column.ts +17 -0
- package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +523 -0
- package/UI/Components/ModelTable/ColumnPreference.ts +482 -0
- package/UI/Components/ModelTable/CustomFieldColumns.tsx +326 -0
- package/UI/Components/ModelTable/TableView.tsx +24 -2
- package/UI/Components/ModelTable/useCustomFieldColumns.ts +150 -0
- package/UI/Components/Runbook/StepTimeoutInput.tsx +173 -0
- package/UI/Components/SideMenu/SideMenu.tsx +24 -4
- package/UI/Components/StatusPage/ResourceGroupSection.tsx +231 -0
- package/UI/Components/Table/Table.tsx +14 -1
- package/UI/Components/Table/TableRow.tsx +180 -175
- package/UI/Components/Table/Types/Column.ts +2 -0
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +34 -1
- package/UI/Utils/DropdownAlignment.ts +162 -0
- package/UI/Utils/TableFilterUrlState.ts +59 -20
- package/Utils/API.ts +106 -2
- package/Utils/Monitor/MonitorSummaryProbeUtil.ts +130 -0
- package/Utils/NetworkDiscovery/ScanTargetUtil.ts +434 -0
- package/Utils/StatusPage/GroupNestingLayout.ts +343 -0
- package/Utils/StatusPage/GroupTree.ts +307 -0
- package/Utils/StatusPage/ResourceUptime.ts +90 -17
- package/Utils/UserPreferences.ts +53 -0
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +86 -0
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogDropFilter.js +91 -0
- package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +14 -4
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RecommendationDismissal.js +484 -0
- package/build/dist/Models/DatabaseModels/RecommendationDismissal.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageGroup.js +94 -0
- package/build/dist/Models/DatabaseModels/StatusPageGroup.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TableView.js +40 -0
- package/build/dist/Models/DatabaseModels/TableView.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js +91 -0
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js +5 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
- package/build/dist/Server/API/AlertAPI.js +22 -13
- package/build/dist/Server/API/AlertAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +22 -1
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAnalyticsAPI.js +24 -1
- package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +42 -0
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentAPI.js +43 -26
- package/build/dist/Server/API/IncidentAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentEpisodeAPI.js +21 -12
- package/build/dist/Server/API/IncidentEpisodeAPI.js.map +1 -1
- package/build/dist/Server/API/MonitorAPI.js +23 -0
- package/build/dist/Server/API/MonitorAPI.js.map +1 -1
- package/build/dist/Server/API/MonitorTemplateAPI.js +4 -0
- package/build/dist/Server/API/MonitorTemplateAPI.js.map +1 -1
- package/build/dist/Server/API/ProbeAPI.js +131 -15
- package/build/dist/Server/API/ProbeAPI.js.map +1 -1
- package/build/dist/Server/API/ProjectAPI.js +62 -3
- package/build/dist/Server/API/ProjectAPI.js.map +1 -1
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js +23 -14
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +61 -33
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js +26 -2
- package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js +397 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeService.js +39 -0
- package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +95 -0
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +71 -0
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +140 -17
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js +39 -0
- package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +100 -0
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentTemplateService.js +97 -0
- package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/LogDropFilterService.js +93 -0
- package/build/dist/Server/Services/LogDropFilterService.js.map +1 -1
- package/build/dist/Server/Services/MonitorProbeService.js +73 -5
- package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +34 -39
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +71 -0
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
- package/build/dist/Server/Services/ProbeService.js +64 -0
- package/build/dist/Server/Services/ProbeService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +103 -7
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RecommendationDismissalService.js +50 -0
- package/build/dist/Server/Services/RecommendationDismissalService.js.map +1 -0
- package/build/dist/Server/Services/RunbookAgentJobService.js +63 -5
- package/build/dist/Server/Services/RunbookAgentJobService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +83 -0
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js +65 -0
- package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageGroupService.js +136 -0
- package/build/dist/Server/Services/StatusPageGroupService.js.map +1 -1
- package/build/dist/Server/Services/TraceDropFilterService.js +93 -0
- package/build/dist/Server/Services/TraceDropFilterService.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js +12 -0
- package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +132 -0
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -0
- package/build/dist/Server/Utils/DropFilterValidation.js +80 -0
- package/build/dist/Server/Utils/DropFilterValidation.js.map +1 -0
- package/build/dist/Server/Utils/Errors.js +3 -0
- package/build/dist/Server/Utils/Errors.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +30 -12
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +38 -18
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/AppMetrics.js +26 -0
- package/build/dist/Server/Utils/Telemetry/AppMetrics.js.map +1 -1
- package/build/dist/Types/Date.js +14 -4
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +8 -3
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +192 -0
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +6 -1
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js +32 -1
- package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +294 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +110 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +58 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +451 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -0
- package/build/dist/Types/Permission.js +40 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Recommendation/RecommendationType.js +21 -0
- package/build/dist/Types/Recommendation/RecommendationType.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookExecutionDeadline.js +93 -0
- package/build/dist/Types/Runbook/RunbookExecutionDeadline.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookStepTimeout.js +142 -0
- package/build/dist/Types/Runbook/RunbookStepTimeout.js.map +1 -0
- package/build/dist/Types/Telemetry/DropFilterSampling.js +75 -0
- package/build/dist/Types/Telemetry/DropFilterSampling.js.map +1 -0
- package/build/dist/UI/Components/AI/GenerateFromAIModal.js +1 -2
- package/build/dist/UI/Components/AI/GenerateFromAIModal.js.map +1 -1
- package/build/dist/UI/Components/Accordion/Accordion.js +9 -2
- package/build/dist/UI/Components/Accordion/Accordion.js.map +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js +27 -14
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
- package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js +1 -1
- package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +2 -20
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/Error/PageError.js +1 -3
- package/build/dist/UI/Components/Error/PageError.js.map +1 -1
- package/build/dist/UI/Components/ErrorBoundary.js +145 -11
- package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js +28 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +13 -2
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.js +50 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +4 -32
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +308 -40
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +230 -0
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/ColumnPreference.js +258 -0
- package/build/dist/UI/Components/ModelTable/ColumnPreference.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +168 -0
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/TableView.js +13 -2
- package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +84 -0
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -0
- package/build/dist/UI/Components/Runbook/StepTimeoutInput.js +101 -0
- package/build/dist/UI/Components/Runbook/StepTimeoutInput.js.map +1 -0
- package/build/dist/UI/Components/SideMenu/SideMenu.js +15 -5
- package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +73 -0
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +15 -2
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +11 -6
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +13 -2
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Utils/DropdownAlignment.js +98 -0
- package/build/dist/UI/Utils/DropdownAlignment.js.map +1 -0
- package/build/dist/UI/Utils/TableFilterUrlState.js +48 -15
- package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
- package/build/dist/Utils/API.js +39 -2
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js +97 -0
- package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +330 -0
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -0
- package/build/dist/Utils/StatusPage/GroupNestingLayout.js +280 -0
- package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -0
- package/build/dist/Utils/StatusPage/GroupTree.js +214 -0
- package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -0
- package/build/dist/Utils/StatusPage/ResourceUptime.js +60 -16
- package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
- package/build/dist/Utils/UserPreferences.js +33 -0
- package/build/dist/Utils/UserPreferences.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import InfoCard from "../../../UI/Components/InfoCard/InfoCard";
|
|
2
|
+
/*
|
|
3
|
+
* The package entry, not the `/extend-expect` subpath the older tests use:
|
|
4
|
+
* the matchers are already registered by Tests/jest.setup.ts, and only this
|
|
5
|
+
* specifier resolves to the type augmentation that makes them visible to
|
|
6
|
+
* TypeScript.
|
|
7
|
+
*/
|
|
8
|
+
import "@testing-library/jest-dom";
|
|
9
|
+
import { fireEvent, render, screen } from "@testing-library/react";
|
|
10
|
+
import React from "react";
|
|
11
|
+
import { describe, expect, jest, test } from "@jest/globals";
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
* InfoCard is the stat card used across the product. Most of them are inert
|
|
15
|
+
* containers, a handful navigate somewhere when clicked, and the network
|
|
16
|
+
* summary strips use them as toggles that filter the table below.
|
|
17
|
+
*
|
|
18
|
+
* The three have to stay distinguishable to a screen reader and to the
|
|
19
|
+
* keyboard, and the distinctions are all driven off which props were passed —
|
|
20
|
+
* so that is what these cover, end to end through a real render.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* The card's own root element. Taken off the render container rather than
|
|
25
|
+
* walked up from the title, because a card with no click handler has no role
|
|
26
|
+
* to query it by — which is exactly what several of these assert.
|
|
27
|
+
*/
|
|
28
|
+
function getCard(): HTMLElement {
|
|
29
|
+
return document.body.firstElementChild!.firstElementChild as HTMLElement;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
describe("InfoCard", () => {
|
|
33
|
+
describe("a card with no click handler", () => {
|
|
34
|
+
test("renders its title and value", () => {
|
|
35
|
+
render(<InfoCard title="Devices Up" value="12" />);
|
|
36
|
+
|
|
37
|
+
expect(screen.getByText("Devices Up")).toBeInTheDocument();
|
|
38
|
+
expect(screen.getByText("12")).toBeInTheDocument();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
/*
|
|
42
|
+
* The majority of InfoCards in the product are read-only. Announcing one
|
|
43
|
+
* as a button would put a tab stop on every tile of every dashboard.
|
|
44
|
+
*/
|
|
45
|
+
test("is not a button, and is not focusable", () => {
|
|
46
|
+
render(<InfoCard title="Devices Up" value="12" />);
|
|
47
|
+
|
|
48
|
+
expect(screen.queryByRole("button")).not.toBeInTheDocument();
|
|
49
|
+
expect(getCard()).not.toHaveAttribute("tabindex");
|
|
50
|
+
expect(getCard()).not.toHaveAttribute("aria-pressed");
|
|
51
|
+
expect(getCard()).not.toHaveAttribute("aria-label");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("does not look clickable", () => {
|
|
55
|
+
render(<InfoCard title="Devices Up" value="12" />);
|
|
56
|
+
|
|
57
|
+
expect(getCard()).not.toHaveClass("cursor-pointer");
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe("a card that navigates when clicked", () => {
|
|
62
|
+
/*
|
|
63
|
+
* The pre-existing clickable cards — the Home overview stats, the
|
|
64
|
+
* Kubernetes and Proxmox summaries — all navigate. They pass onClick and
|
|
65
|
+
* no isSelected.
|
|
66
|
+
*/
|
|
67
|
+
test("is a real button, reachable by keyboard", () => {
|
|
68
|
+
render(
|
|
69
|
+
<InfoCard
|
|
70
|
+
title="Devices Up"
|
|
71
|
+
value="12"
|
|
72
|
+
onClick={() => {
|
|
73
|
+
// no-op
|
|
74
|
+
}}
|
|
75
|
+
/>,
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const card: HTMLElement = screen.getByRole("button");
|
|
79
|
+
expect(card).toBeInTheDocument();
|
|
80
|
+
expect(card).toHaveAttribute("tabindex", "0");
|
|
81
|
+
expect(card).toHaveClass("cursor-pointer");
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
/*
|
|
85
|
+
* The regression this guards: `aria-pressed="false"` asserts the control
|
|
86
|
+
* is a toggle that is currently off. On a card that navigates away, that
|
|
87
|
+
* is a state activating it can never reach — the user is told to expect
|
|
88
|
+
* something the product never does.
|
|
89
|
+
*/
|
|
90
|
+
test("is not announced as an unpressed toggle", () => {
|
|
91
|
+
render(
|
|
92
|
+
<InfoCard
|
|
93
|
+
title="Devices Up"
|
|
94
|
+
value="12"
|
|
95
|
+
onClick={() => {
|
|
96
|
+
// no-op
|
|
97
|
+
}}
|
|
98
|
+
/>,
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
expect(screen.getByRole("button")).not.toHaveAttribute("aria-pressed");
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test("keeps the plain border", () => {
|
|
105
|
+
render(
|
|
106
|
+
<InfoCard
|
|
107
|
+
title="Devices Up"
|
|
108
|
+
value="12"
|
|
109
|
+
onClick={() => {
|
|
110
|
+
// no-op
|
|
111
|
+
}}
|
|
112
|
+
/>,
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
expect(screen.getByRole("button")).toHaveClass("border-gray-200");
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe("a card used as a toggle", () => {
|
|
120
|
+
test("announces itself as pressed when selected", () => {
|
|
121
|
+
render(
|
|
122
|
+
<InfoCard
|
|
123
|
+
title="Devices Up"
|
|
124
|
+
value="12"
|
|
125
|
+
isSelected={true}
|
|
126
|
+
onClick={() => {
|
|
127
|
+
// no-op
|
|
128
|
+
}}
|
|
129
|
+
/>,
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
expect(screen.getByRole("button")).toHaveAttribute(
|
|
133
|
+
"aria-pressed",
|
|
134
|
+
"true",
|
|
135
|
+
);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
/*
|
|
139
|
+
* Explicit `false` is a real state here — the tile exists, it is simply
|
|
140
|
+
* not the one the table is filtered by — so it must still announce as a
|
|
141
|
+
* toggle, unlike the navigation card above.
|
|
142
|
+
*/
|
|
143
|
+
test("announces itself as unpressed when explicitly not selected", () => {
|
|
144
|
+
render(
|
|
145
|
+
<InfoCard
|
|
146
|
+
title="Devices Up"
|
|
147
|
+
value="12"
|
|
148
|
+
isSelected={false}
|
|
149
|
+
onClick={() => {
|
|
150
|
+
// no-op
|
|
151
|
+
}}
|
|
152
|
+
/>,
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
expect(screen.getByRole("button")).toHaveAttribute(
|
|
156
|
+
"aria-pressed",
|
|
157
|
+
"false",
|
|
158
|
+
);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
/*
|
|
162
|
+
* Tailwind emits both border-colour utilities at the same specificity, so
|
|
163
|
+
* a selected card that merely *added* a border colour would leave the
|
|
164
|
+
* winner up to stylesheet order. The class is swapped.
|
|
165
|
+
*/
|
|
166
|
+
test("swaps its border rather than stacking a second one", () => {
|
|
167
|
+
render(
|
|
168
|
+
<InfoCard
|
|
169
|
+
title="Devices Up"
|
|
170
|
+
value="12"
|
|
171
|
+
isSelected={true}
|
|
172
|
+
onClick={() => {
|
|
173
|
+
// no-op
|
|
174
|
+
}}
|
|
175
|
+
/>,
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
const card: HTMLElement = screen.getByRole("button");
|
|
179
|
+
expect(card).toHaveClass("border-indigo-500");
|
|
180
|
+
expect(card).not.toHaveClass("border-gray-200");
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test("carries the caller's label for screen readers", () => {
|
|
184
|
+
render(
|
|
185
|
+
<InfoCard
|
|
186
|
+
title="Devices Up"
|
|
187
|
+
value="12"
|
|
188
|
+
isSelected={true}
|
|
189
|
+
ariaLabel="Devices Up: 12. Showing these in the list below."
|
|
190
|
+
onClick={() => {
|
|
191
|
+
// no-op
|
|
192
|
+
}}
|
|
193
|
+
/>,
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
expect(
|
|
197
|
+
screen.getByRole("button", {
|
|
198
|
+
name: "Devices Up: 12. Showing these in the list below.",
|
|
199
|
+
}),
|
|
200
|
+
).toBeInTheDocument();
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// A label on an inert card would announce a control that is not there.
|
|
204
|
+
test("ignores the label when there is nothing to activate", () => {
|
|
205
|
+
render(
|
|
206
|
+
<InfoCard title="Devices Up" value="12" ariaLabel="Should not apply" />,
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
expect(getCard()).not.toHaveAttribute("aria-label");
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// Selection styling is meaningless without a handler to toggle it.
|
|
213
|
+
test("a non-clickable card ignores isSelected", () => {
|
|
214
|
+
render(<InfoCard title="Devices Up" value="12" isSelected={true} />);
|
|
215
|
+
|
|
216
|
+
expect(getCard()).toHaveClass("border-gray-200");
|
|
217
|
+
expect(getCard()).not.toHaveAttribute("aria-pressed");
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
describe("activation", () => {
|
|
222
|
+
test("a click fires the handler", () => {
|
|
223
|
+
const onClick: () => void = jest.fn();
|
|
224
|
+
render(<InfoCard title="Devices Up" value="12" onClick={onClick} />);
|
|
225
|
+
|
|
226
|
+
fireEvent.click(screen.getByRole("button"));
|
|
227
|
+
|
|
228
|
+
expect(onClick).toHaveBeenCalledTimes(1);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
/*
|
|
232
|
+
* A div with an onClick is invisible to the keyboard. Enter and Space are
|
|
233
|
+
* what a real button responds to, and both have to work here or the tiles
|
|
234
|
+
* are mouse-only.
|
|
235
|
+
*/
|
|
236
|
+
test("Enter fires the handler", () => {
|
|
237
|
+
const onClick: () => void = jest.fn();
|
|
238
|
+
render(<InfoCard title="Devices Up" value="12" onClick={onClick} />);
|
|
239
|
+
|
|
240
|
+
fireEvent.keyDown(screen.getByRole("button"), { key: "Enter" });
|
|
241
|
+
|
|
242
|
+
expect(onClick).toHaveBeenCalledTimes(1);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
test("Space fires the handler", () => {
|
|
246
|
+
const onClick: () => void = jest.fn();
|
|
247
|
+
render(<InfoCard title="Devices Up" value="12" onClick={onClick} />);
|
|
248
|
+
|
|
249
|
+
fireEvent.keyDown(screen.getByRole("button"), { key: " " });
|
|
250
|
+
|
|
251
|
+
expect(onClick).toHaveBeenCalledTimes(1);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
/*
|
|
255
|
+
* Space scrolls the page by default. Without preventDefault, activating a
|
|
256
|
+
* tile from the keyboard would also jump the view down a screen.
|
|
257
|
+
*/
|
|
258
|
+
test("Space does not also scroll the page", () => {
|
|
259
|
+
render(
|
|
260
|
+
<InfoCard
|
|
261
|
+
title="Devices Up"
|
|
262
|
+
value="12"
|
|
263
|
+
onClick={() => {
|
|
264
|
+
// no-op
|
|
265
|
+
}}
|
|
266
|
+
/>,
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
// fireEvent returns false when the handler called preventDefault.
|
|
270
|
+
const notCancelled: boolean = fireEvent.keyDown(
|
|
271
|
+
screen.getByRole("button"),
|
|
272
|
+
{ key: " ", cancelable: true },
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
expect(notCancelled).toBe(false);
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
test("Enter does not swallow the default either way it is used", () => {
|
|
279
|
+
render(
|
|
280
|
+
<InfoCard
|
|
281
|
+
title="Devices Up"
|
|
282
|
+
value="12"
|
|
283
|
+
onClick={() => {
|
|
284
|
+
// no-op
|
|
285
|
+
}}
|
|
286
|
+
/>,
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
expect(
|
|
290
|
+
fireEvent.keyDown(screen.getByRole("button"), {
|
|
291
|
+
key: "Enter",
|
|
292
|
+
cancelable: true,
|
|
293
|
+
}),
|
|
294
|
+
).toBe(false);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
test.each([["Tab"], ["Escape"], ["a"], ["ArrowDown"], ["Shift"]])(
|
|
298
|
+
"%s does not activate it",
|
|
299
|
+
(key: string) => {
|
|
300
|
+
const onClick: () => void = jest.fn();
|
|
301
|
+
render(<InfoCard title="Devices Up" value="12" onClick={onClick} />);
|
|
302
|
+
|
|
303
|
+
const notCancelled: boolean = fireEvent.keyDown(
|
|
304
|
+
screen.getByRole("button"),
|
|
305
|
+
{ key: key, cancelable: true },
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
expect(onClick).not.toHaveBeenCalled();
|
|
309
|
+
// And the key still does whatever it normally does.
|
|
310
|
+
expect(notCancelled).toBe(true);
|
|
311
|
+
},
|
|
312
|
+
);
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
describe("styling passthrough", () => {
|
|
316
|
+
test("the caller's className still lands on the card", () => {
|
|
317
|
+
render(<InfoCard title="Devices Up" value="12" className="col-span-2" />);
|
|
318
|
+
|
|
319
|
+
expect(getCard()).toHaveClass("col-span-2");
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
test("the caller's text class still wraps the value", () => {
|
|
323
|
+
render(
|
|
324
|
+
<InfoCard
|
|
325
|
+
title="Devices Up"
|
|
326
|
+
value="12"
|
|
327
|
+
textClassName="text-emerald-600"
|
|
328
|
+
/>,
|
|
329
|
+
);
|
|
330
|
+
|
|
331
|
+
expect(screen.getByText("12")).toHaveClass("text-emerald-600");
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
/*
|
|
335
|
+
* A keyboard user has to be able to see which card they are on — the
|
|
336
|
+
* focus ring is the only cue, since the card has no other focus styling.
|
|
337
|
+
*/
|
|
338
|
+
test("a clickable card shows a focus ring", () => {
|
|
339
|
+
render(
|
|
340
|
+
<InfoCard
|
|
341
|
+
title="Devices Up"
|
|
342
|
+
value="12"
|
|
343
|
+
onClick={() => {
|
|
344
|
+
// no-op
|
|
345
|
+
}}
|
|
346
|
+
/>,
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
expect(screen.getByRole("button")).toHaveClass("focus-visible:ring-2");
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
test("an inert card does not", () => {
|
|
353
|
+
render(<InfoCard title="Devices Up" value="12" />);
|
|
354
|
+
|
|
355
|
+
expect(getCard()).not.toHaveClass("focus-visible:ring-2");
|
|
356
|
+
});
|
|
357
|
+
});
|
|
358
|
+
});
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import LogTimeRangePicker, {
|
|
2
|
+
LOG_TIME_RANGE_DROPDOWN_WIDTH_IN_PX,
|
|
3
|
+
} from "../../../UI/Components/LogsViewer/components/LogTimeRangePicker";
|
|
4
|
+
import RangeStartAndEndDateTime from "../../../Types/Time/RangeStartAndEndDateTime";
|
|
5
|
+
import TimeRange from "../../../Types/Time/TimeRange";
|
|
6
|
+
import "@testing-library/jest-dom/extend-expect";
|
|
7
|
+
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
|
|
8
|
+
import React from "react";
|
|
9
|
+
import {
|
|
10
|
+
afterEach,
|
|
11
|
+
beforeEach,
|
|
12
|
+
describe,
|
|
13
|
+
expect,
|
|
14
|
+
jest,
|
|
15
|
+
test,
|
|
16
|
+
} from "@jest/globals";
|
|
17
|
+
|
|
18
|
+
const BUTTON_TEST_ID: string = "log-time-range-picker-button";
|
|
19
|
+
const DROPDOWN_TEST_ID: string = "log-time-range-picker-dropdown";
|
|
20
|
+
|
|
21
|
+
const ORIGINAL_INNER_WIDTH: number = window.innerWidth;
|
|
22
|
+
const originalGetBoundingClientRect: () => DOMRect =
|
|
23
|
+
Element.prototype.getBoundingClientRect;
|
|
24
|
+
|
|
25
|
+
function setViewportWidth(width: number): void {
|
|
26
|
+
Object.defineProperty(window, "innerWidth", {
|
|
27
|
+
configurable: true,
|
|
28
|
+
writable: true,
|
|
29
|
+
value: width,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function stubTriggerRect(left: number, right: number): void {
|
|
34
|
+
Element.prototype.getBoundingClientRect = function (this: Element): DOMRect {
|
|
35
|
+
if (
|
|
36
|
+
this instanceof HTMLElement &&
|
|
37
|
+
this.getAttribute("data-testid") === BUTTON_TEST_ID
|
|
38
|
+
) {
|
|
39
|
+
return {
|
|
40
|
+
left: left,
|
|
41
|
+
right: right,
|
|
42
|
+
top: 40,
|
|
43
|
+
bottom: 68,
|
|
44
|
+
width: right - left,
|
|
45
|
+
height: 28,
|
|
46
|
+
x: left,
|
|
47
|
+
y: 40,
|
|
48
|
+
toJSON: (): Record<string, unknown> => {
|
|
49
|
+
return {};
|
|
50
|
+
},
|
|
51
|
+
} as DOMRect;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return originalGetBoundingClientRect.call(this);
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function openDropdown(value: RangeStartAndEndDateTime): HTMLElement {
|
|
59
|
+
render(<LogTimeRangePicker value={value} onChange={jest.fn()} />);
|
|
60
|
+
fireEvent.click(screen.getByTestId(BUTTON_TEST_ID));
|
|
61
|
+
return screen.getByTestId(DROPDOWN_TEST_ID);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function hasClass(element: HTMLElement, className: string): boolean {
|
|
65
|
+
return element.classList.contains(className);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
describe("LogTimeRangePicker", () => {
|
|
69
|
+
beforeEach(() => {
|
|
70
|
+
setViewportWidth(1440);
|
|
71
|
+
stubTriggerRect(64, 180);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
afterEach(() => {
|
|
75
|
+
cleanup();
|
|
76
|
+
Element.prototype.getBoundingClientRect = originalGetBoundingClientRect;
|
|
77
|
+
setViewportWidth(ORIGINAL_INNER_WIDTH);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("opens rightwards when the trigger sits at the left of the toolbar", () => {
|
|
81
|
+
const dropdown: HTMLElement = openDropdown({
|
|
82
|
+
range: TimeRange.PAST_ONE_HOUR,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
expect(hasClass(dropdown, "left-0")).toBe(true);
|
|
86
|
+
expect(hasClass(dropdown, "right-0")).toBe(false);
|
|
87
|
+
expect(dropdown.getAttribute("data-align")).toBe("left");
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("flips to right alignment when the trigger is near the right edge", () => {
|
|
91
|
+
stubTriggerRect(1310, 1430);
|
|
92
|
+
|
|
93
|
+
const dropdown: HTMLElement = openDropdown({
|
|
94
|
+
range: TimeRange.PAST_ONE_HOUR,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
expect(hasClass(dropdown, "right-0")).toBe(true);
|
|
98
|
+
expect(hasClass(dropdown, "left-0")).toBe(false);
|
|
99
|
+
expect(dropdown.getAttribute("data-align")).toBe("right");
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test("stays left aligned on a narrow mobile viewport", () => {
|
|
103
|
+
setViewportWidth(375);
|
|
104
|
+
stubTriggerRect(12, 128);
|
|
105
|
+
|
|
106
|
+
expect(
|
|
107
|
+
hasClass(openDropdown({ range: TimeRange.PAST_ONE_HOUR }), "left-0"),
|
|
108
|
+
).toBe(true);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test("caps the panel width so it cannot exceed the viewport", () => {
|
|
112
|
+
expect(
|
|
113
|
+
hasClass(
|
|
114
|
+
openDropdown({ range: TimeRange.PAST_ONE_HOUR }),
|
|
115
|
+
"max-w-[calc(100vw-1rem)]",
|
|
116
|
+
),
|
|
117
|
+
).toBe(true);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test("exports a width constant that matches the rendered w-72 panel", () => {
|
|
121
|
+
expect(LOG_TIME_RANGE_DROPDOWN_WIDTH_IN_PX).toBe(288);
|
|
122
|
+
expect(
|
|
123
|
+
hasClass(openDropdown({ range: TimeRange.PAST_ONE_HOUR }), "w-72"),
|
|
124
|
+
).toBe(true);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test("keeps the panel anchored below the trigger", () => {
|
|
128
|
+
const dropdown: HTMLElement = openDropdown({
|
|
129
|
+
range: TimeRange.PAST_ONE_HOUR,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
expect(hasClass(dropdown, "absolute")).toBe(true);
|
|
133
|
+
expect(hasClass(dropdown, "top-full")).toBe(true);
|
|
134
|
+
expect(
|
|
135
|
+
dropdown.parentElement?.classList.contains("relative") ?? false,
|
|
136
|
+
).toBe(true);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
@@ -2,9 +2,13 @@ import { ButtonStyleType } from "../../../UI/Components/Button/Button";
|
|
|
2
2
|
import ButtonType from "../../../UI/Components/Button/ButtonTypes";
|
|
3
3
|
import Modal, { ModalWidth } from "../../../UI/Components/Modal/Modal";
|
|
4
4
|
import { describe, expect, it, test } from "@jest/globals";
|
|
5
|
-
|
|
5
|
+
/*
|
|
6
|
+
* The main entry, not "/extend-expect": the latter no longer ships type
|
|
7
|
+
* declarations, so every jest-dom matcher in this file fails to typecheck and
|
|
8
|
+
* the whole suite is skipped before a single assertion runs.
|
|
9
|
+
*/
|
|
10
|
+
import "@testing-library/jest-dom";
|
|
6
11
|
import { fireEvent, render } from "@testing-library/react";
|
|
7
|
-
import IconProp from "../../../Types/Icon/IconProp";
|
|
8
12
|
import React from "react";
|
|
9
13
|
import getJestMockFunction, { MockFunction } from "../../../Tests/MockType";
|
|
10
14
|
|
|
@@ -338,16 +342,50 @@ describe("Modal", () => {
|
|
|
338
342
|
expect(submitButton).toBeDisabled();
|
|
339
343
|
});
|
|
340
344
|
|
|
341
|
-
|
|
345
|
+
/*
|
|
346
|
+
* The header carries the title, the description and the close button, and
|
|
347
|
+
* nothing else. A decorative icon beside the title said nothing the title did
|
|
348
|
+
* not already say, so there is no longer anywhere for one to be rendered.
|
|
349
|
+
*/
|
|
350
|
+
it("renders no decorative icon in the header", () => {
|
|
342
351
|
const onSubmitMock: MockFunction = getJestMockFunction();
|
|
343
352
|
|
|
353
|
+
const { queryByTestId, getByTestId } = render(
|
|
354
|
+
<Modal
|
|
355
|
+
title="Test Modal"
|
|
356
|
+
description="Test modal description"
|
|
357
|
+
onSubmit={onSubmitMock}
|
|
358
|
+
onClose={getJestMockFunction()}
|
|
359
|
+
>
|
|
360
|
+
<div>Modal content</div>
|
|
361
|
+
</Modal>,
|
|
362
|
+
);
|
|
363
|
+
|
|
364
|
+
expect(queryByTestId("icon")).not.toBeInTheDocument();
|
|
365
|
+
|
|
366
|
+
// The rest of the header is untouched.
|
|
367
|
+
expect(getByTestId("modal-title")).toHaveTextContent("Test Modal");
|
|
368
|
+
expect(getByTestId("modal-description")).toHaveTextContent(
|
|
369
|
+
"Test modal description",
|
|
370
|
+
);
|
|
371
|
+
expect(getByTestId("close-button")).toBeInTheDocument();
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
it("keeps the title as the first thing inside the header", () => {
|
|
344
375
|
const { getByTestId } = render(
|
|
345
|
-
<Modal title="Test Modal" onSubmit={
|
|
376
|
+
<Modal title="Test Modal" onSubmit={getJestMockFunction()}>
|
|
346
377
|
<div>Modal content</div>
|
|
347
378
|
</Modal>,
|
|
348
379
|
);
|
|
349
380
|
|
|
350
|
-
|
|
381
|
+
const title: HTMLElement = getByTestId("modal-title");
|
|
382
|
+
const header: HTMLElement = title.parentElement!.parentElement!;
|
|
383
|
+
|
|
384
|
+
/*
|
|
385
|
+
* With the icon gone the title block is the header's first child. Anything
|
|
386
|
+
* else in that slot would push the title out of line with the body.
|
|
387
|
+
*/
|
|
388
|
+
expect(header.firstElementChild).toContainElement(title);
|
|
351
389
|
});
|
|
352
390
|
|
|
353
391
|
it("displays the submit button with the default style when submitButtonStyleType is not set", () => {
|