@oneuptime/common 12.0.23 → 12.0.25
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/Span.ts +101 -0
- package/Models/DatabaseModels/DetectionRule.ts +55 -0
- package/Models/DatabaseModels/NetworkDeviceAutoImportRule.ts +27 -7
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +67 -0
- package/Models/DatabaseModels/Project.ts +68 -0
- package/Models/DatabaseModels/User.ts +68 -0
- package/Server/API/BaseAPI.ts +0 -24
- package/Server/API/SlackAPI.ts +0 -2
- package/Server/API/TelemetryAPI.ts +29 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1789400000000-AddNameToNetworkDeviceDiscoveryScan.ts +28 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1789500000000-AddCampaignUtmFields.ts +49 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1789512000000-AddDetectionRuleDistinctCountColumns.ts +33 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Middleware/GzipRequestBody.ts +311 -0
- package/Server/Middleware/MultipartFormData.ts +87 -3
- package/Server/Middleware/SlackAuthorization.ts +96 -18
- package/Server/Services/DetectionRuleService.ts +73 -6
- package/Server/Services/Index.ts +205 -0
- package/Server/Services/NetworkDeviceDiscoveryScanService.ts +59 -0
- package/Server/Services/NetworkDeviceService.ts +148 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +65 -0
- package/Server/Services/OnCallDutyPolicyFeedService.ts +1 -1
- package/Server/Services/ProjectService.ts +29 -19
- package/Server/Services/SecurityEventService.ts +90 -13
- package/Server/Services/StatusPageResourceService.ts +223 -0
- package/Server/Services/TelemetryAttributeService.ts +17 -0
- package/Server/Services/UserService.ts +4 -6
- package/Server/Types/Markdown.ts +161 -67
- package/Server/Utils/AI/Toolbox/OnCallTools.ts +12 -4
- package/Server/Utils/AnalyticsDatabase/Statement.ts +13 -1
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +297 -6
- package/Server/Utils/Attribution.ts +4 -0
- package/Server/Utils/Marketing/MarketingEventUtil.ts +45 -7
- package/Server/Utils/SecurityEvent/DetectionRuleEvaluator.ts +55 -3
- package/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.ts +21 -0
- package/Server/Utils/StartServer.ts +12 -32
- package/Server/Utils/Telemetry/LlmCostBudgetEvaluator.ts +101 -4
- package/Server/Utils/Telemetry/LlmMetricSpend.ts +181 -0
- package/Server/Utils/Telemetry/LlmSpan.ts +46 -0
- package/Server/Utils/Workspace/Slack/Actions/Auth.ts +0 -12
- package/Server/Views/Partials/AnalyticsConsent.ejs +159 -102
- package/Server/Views/Partials/Head.ejs +2 -1
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +776 -38
- package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +359 -0
- package/Tests/App/Dashboard/CorrelateGraph.test.tsx +865 -0
- package/Tests/App/Dashboard/CorrelationGraph.test.ts +346 -0
- package/Tests/App/Dashboard/CriteriaFilterConditionDropdown.test.tsx +256 -0
- package/Tests/App/Dashboard/CriteriaFilterDefaults.test.ts +738 -0
- package/Tests/App/Dashboard/CriteriaFilterMonitorTypeChange.test.ts +1122 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +283 -0
- package/Tests/App/Dashboard/ExternalStatusPageCriteriaFilter.test.ts +407 -0
- package/Tests/App/Dashboard/LlmCallsTableIdentity.test.tsx +322 -0
- package/Tests/App/Dashboard/LlmOverview.test.tsx +335 -0
- package/Tests/App/Dashboard/LlmSpanDisplay.test.ts +391 -0
- package/Tests/App/Dashboard/LlmUsageBreakdown.test.tsx +1007 -0
- package/Tests/App/Dashboard/MetricSeriesInvestigateMenu.test.tsx +5 -14
- package/Tests/App/Dashboard/MonitorCriteriaActionToggles.test.tsx +426 -0
- package/Tests/App/Dashboard/MonitorStepsCriteriaAlignmentWiring.test.tsx +352 -0
- package/Tests/App/Dashboard/OnCallLayerCardOverrides.test.tsx +278 -0
- package/Tests/App/Dashboard/OnCallLayerShiftPreviewOverrides.test.ts +237 -0
- package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +2 -2
- package/Tests/App/Dashboard/OnCallSchedulePreviewOverrides.test.tsx +460 -0
- package/Tests/App/Dashboard/SecurityEventAttributeUtil.test.ts +171 -0
- package/Tests/App/Dashboard/SecurityEventCorrelation.test.ts +857 -0
- package/Tests/App/Dashboard/SecurityEventDetailObservables.test.tsx +194 -0
- package/Tests/App/Dashboard/SecurityEventsDetectionRulesPage.test.tsx +124 -0
- package/Tests/App/Dashboard/SecurityEventsMonitorStepForm.test.tsx +79 -19
- package/Tests/App/Dashboard/SecurityEventsTableColumns.test.tsx +382 -0
- package/Tests/App/StatusPage/BulkAddStatusPageMonitors.test.ts +216 -0
- package/Tests/App/StatusPage/BulkAddStatusPageMonitorsModal.test.tsx +590 -11
- package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +757 -0
- package/Tests/Models/DiscoveryScanNameColumn.test.ts +293 -0
- package/Tests/Server/API/BaseAPI.test.ts +41 -0
- package/Tests/Server/API/BaseAPIUpdatePayloadValidation.test.ts +9 -16
- package/Tests/Server/API/SecurityEventAttributesAPI.test.ts +564 -0
- package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +120 -4
- package/Tests/Server/Middleware/GzipRequestBody.test.ts +725 -0
- package/Tests/Server/Middleware/MultipartFormData.test.ts +298 -0
- package/Tests/Server/Middleware/SlackAuthorization.test.ts +262 -5
- package/Tests/Server/Services/AddDetectionRuleDistinctCountColumnsMigration.test.ts +311 -0
- package/Tests/Server/Services/DetectionRuleService.test.ts +134 -2
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +7 -1
- package/Tests/Server/Services/FeedRetentionConsistency.test.ts +131 -0
- package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +194 -0
- package/Tests/Server/Services/NetworkDeviceMonitorStatusStamp.test.ts +800 -0
- package/Tests/Server/Services/OnCallScheduleAttachRosterRefresh.test.ts +244 -0
- package/Tests/Server/Services/SecurityEventService.test.ts +376 -0
- package/Tests/Server/Services/StatusPageResourceDuplicates.test.ts +703 -0
- package/Tests/Server/Services/TelemetryAttributeServiceSecurityEvent.test.ts +256 -0
- package/Tests/Server/Types/Workflow/Components/ComponentRegistryParity.test.ts +417 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGeneratorWhereOperators.test.ts +677 -0
- package/Tests/Server/Utils/Marketing/MarketingEventUtil.test.ts +43 -0
- package/Tests/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.test.ts +15 -11
- package/Tests/Server/Utils/SecurityEvent/DetectionRuleEvaluator.test.ts +369 -8
- package/Tests/Server/Utils/SecurityEvent/SigmaClickhouseCompiler.test.ts +35 -0
- package/Tests/Server/Utils/Telemetry/LlmCostBudgetEvaluator.test.ts +387 -4
- package/Tests/Server/Utils/Telemetry/LlmMetricSpend.test.ts +386 -0
- package/Tests/Server/Utils/Telemetry/LlmSpan.test.ts +804 -0
- package/Tests/Server/Views/AnalyticsConsentPartial.test.ts +48 -5
- package/Tests/Types/Code/YamlSyntax.test.ts +396 -0
- package/Tests/Types/Monitor/MetricAndProfileDefaultCriteria.test.ts +957 -0
- package/Tests/Types/Monitor/MonitorCriteriaActionValidation.test.ts +598 -0
- package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +49 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +6 -6
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +4 -4
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +4 -3
- package/Tests/Types/Telemetry/LlmMetricConventions.test.ts +584 -0
- package/Tests/UI/Components/AiInvestigationSettingsCard.test.tsx +0 -12
- package/Tests/UI/Components/CardModelDetailEdit.test.tsx +1 -17
- package/Tests/UI/Components/CodeEditor.test.tsx +474 -10
- package/Tests/UI/Components/Detail/YamlField.test.tsx +105 -0
- package/Tests/UI/Components/EntityDropdownLabelsBulkAdd.test.tsx +319 -0
- package/Tests/UI/Components/Forms/FormFieldYaml.test.tsx +231 -0
- package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +1 -0
- package/Tests/UI/Components/Forms/ValidationYAML.test.ts +234 -0
- package/Tests/UI/Components/ModelTable/AttributeColumns.test.tsx +573 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableAttributeColumns.test.tsx +824 -0
- package/Tests/UI/Components/ModelTable/ColumnCustomizationModalAddableColumns.test.tsx +707 -0
- package/Tests/UI/Components/SideOver.test.tsx +1 -1
- package/Tests/UI/Components/StatusPage/ResourceGridSelection.test.tsx +294 -0
- package/Tests/UI/Components/StatusPage/ResourceListSelection.test.tsx +436 -0
- package/Tests/UI/Components/TableBulkCsvExport.test.tsx +6 -2
- package/Tests/UI/Components/Toggle.test.tsx +25 -0
- package/Tests/UI/Components/YamlEditor.test.tsx +847 -0
- package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +252 -0
- package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +221 -0
- package/Tests/Utils/NetworkDiscovery/ScanNameUtil.test.ts +312 -0
- package/Tests/Utils/StatusPage/ResourceExplorer.test.ts +468 -0
- package/Tests/Utils/Telemetry/LlmMetricQuery.test.ts +770 -0
- package/Types/Code/YamlSyntax.ts +396 -0
- package/Types/Exception/ExceptionCode.ts +1 -0
- package/Types/Exception/PayloadTooLargeException.ts +8 -0
- package/Types/Marketing/Attribution.ts +10 -0
- package/Types/Marketing/MarketingEvent.ts +4 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +116 -56
- package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +2 -1
- package/Types/SecurityEvent/DetectionFindingConstants.ts +11 -0
- package/Types/Telemetry/LlmConventions.ts +255 -0
- package/Types/Telemetry/LlmMetricConventions.ts +329 -0
- package/UI/Components/AutocompleteTextInput/AutocompleteTextInput.tsx +3 -0
- package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +10 -1
- package/UI/Components/CodeEditor/CodeEditor.tsx +241 -79
- package/UI/Components/CodeEditor/YamlEditor.tsx +369 -0
- package/UI/Components/Detail/Detail.tsx +10 -0
- package/UI/Components/EntityDropdown/EntityDropdown.tsx +33 -0
- package/UI/Components/Forms/Fields/FormField.tsx +31 -0
- package/UI/Components/Forms/Types/Field.ts +8 -0
- package/UI/Components/Forms/Types/FormFieldSchemaType.ts +1 -0
- package/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.ts +2 -0
- package/UI/Components/Forms/Validation.ts +46 -0
- package/UI/Components/Input/Input.tsx +3 -0
- package/UI/Components/ModelTable/AttributeColumns.tsx +321 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +263 -14
- package/UI/Components/ModelTable/Column.ts +8 -0
- package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +310 -0
- package/UI/Components/ModelTable/ColumnPreference.ts +13 -1
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesModal.tsx +2 -2
- package/UI/Components/SideOver/SideOver.tsx +5 -5
- package/UI/Components/StatusPage/ResourceGrid.tsx +82 -2
- package/UI/Components/StatusPage/ResourceList.tsx +197 -38
- package/UI/Components/Toggle/Toggle.tsx +9 -1
- package/UI/Components/Types/FieldType.ts +1 -0
- package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +73 -1
- package/Utils/NetworkDiscovery/ScanNameUtil.ts +181 -0
- package/Utils/StatusPage/ResourceExplorer.ts +258 -0
- package/Utils/Telemetry/LlmMetricQuery.ts +287 -0
- package/build/dist/Models/AnalyticsModels/Span.js +89 -0
- package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DetectionRule.js +57 -0
- package/build/dist/Models/DatabaseModels/DetectionRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js +27 -7
- package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +69 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +76 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/User.js +76 -0
- package/build/dist/Models/DatabaseModels/User.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +3 -19
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/SlackAPI.js +0 -2
- package/build/dist/Server/API/SlackAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +17 -0
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789400000000-AddNameToNetworkDeviceDiscoveryScan.js +21 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789400000000-AddNameToNetworkDeviceDiscoveryScan.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789500000000-AddCampaignUtmFields.js +42 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789500000000-AddCampaignUtmFields.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789512000000-AddDetectionRuleDistinctCountColumns.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789512000000-AddDetectionRuleDistinctCountColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/GzipRequestBody.js +224 -0
- package/build/dist/Server/Middleware/GzipRequestBody.js.map +1 -0
- package/build/dist/Server/Middleware/MultipartFormData.js +71 -2
- package/build/dist/Server/Middleware/MultipartFormData.js.map +1 -1
- package/build/dist/Server/Middleware/SlackAuthorization.js +58 -7
- package/build/dist/Server/Middleware/SlackAuthorization.js.map +1 -1
- package/build/dist/Server/Services/DetectionRuleService.js +49 -4
- package/build/dist/Server/Services/DetectionRuleService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +204 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +50 -0
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +124 -0
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +68 -13
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyFeedService.js +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyFeedService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +25 -45
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/SecurityEventService.js +57 -5
- package/build/dist/Server/Services/SecurityEventService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageResourceService.js +140 -0
- package/build/dist/Server/Services/StatusPageResourceService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryAttributeService.js +17 -0
- package/build/dist/Server/Services/TelemetryAttributeService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +2 -12
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +147 -61
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js +12 -4
- package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +12 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +246 -9
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/Attribution.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/MarketingEventUtil.js +27 -7
- package/build/dist/Server/Utils/Marketing/MarketingEventUtil.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js +42 -7
- package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js +18 -0
- package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +12 -21
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/LlmCostBudgetEvaluator.js +76 -5
- package/build/dist/Server/Utils/Telemetry/LlmCostBudgetEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/LlmMetricSpend.js +151 -0
- package/build/dist/Server/Utils/Telemetry/LlmMetricSpend.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/LlmSpan.js +24 -1
- package/build/dist/Server/Utils/Telemetry/LlmSpan.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js +0 -10
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js.map +1 -1
- package/build/dist/Types/Code/YamlSyntax.js +212 -0
- package/build/dist/Types/Code/YamlSyntax.js.map +1 -0
- package/build/dist/Types/Exception/ExceptionCode.js +1 -0
- package/build/dist/Types/Exception/ExceptionCode.js.map +1 -1
- package/build/dist/Types/Exception/PayloadTooLargeException.js +8 -0
- package/build/dist/Types/Exception/PayloadTooLargeException.js.map +1 -0
- package/build/dist/Types/Marketing/Attribution.js +10 -0
- package/build/dist/Types/Marketing/Attribution.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +112 -51
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +2 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
- package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js +9 -0
- package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js.map +1 -1
- package/build/dist/Types/Telemetry/LlmConventions.js +236 -0
- package/build/dist/Types/Telemetry/LlmConventions.js.map +1 -1
- package/build/dist/Types/Telemetry/LlmMetricConventions.js +290 -0
- package/build/dist/Types/Telemetry/LlmMetricConventions.js.map +1 -0
- package/build/dist/UI/Components/AutocompleteTextInput/AutocompleteTextInput.js +1 -1
- package/build/dist/UI/Components/AutocompleteTextInput/AutocompleteTextInput.js.map +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +5 -2
- package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js +206 -76
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/YamlEditor.js +201 -0
- package/build/dist/UI/Components/CodeEditor/YamlEditor.js.map +1 -0
- package/build/dist/UI/Components/Detail/Detail.js +9 -0
- package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +16 -1
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +14 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Forms/Types/Field.js.map +1 -1
- package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js +1 -0
- package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js.map +1 -1
- package/build/dist/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.js +2 -0
- package/build/dist/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.js.map +1 -1
- package/build/dist/UI/Components/Forms/Validation.js +27 -0
- package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +1 -1
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/AttributeColumns.js +159 -0
- package/build/dist/UI/Components/ModelTable/AttributeColumns.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +179 -17
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +133 -2
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ColumnPreference.js +7 -1
- package/build/dist/UI/Components/ModelTable/ColumnPreference.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesModal.js +2 -2
- package/build/dist/UI/Components/SideOver/SideOver.js +5 -5
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js +28 -2
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceList.js +87 -20
- package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -1
- package/build/dist/UI/Components/Toggle/Toggle.js +9 -1
- package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
- package/build/dist/UI/Components/Types/FieldType.js +1 -0
- package/build/dist/UI/Components/Types/FieldType.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +37 -1
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/ScanNameUtil.js +120 -0
- package/build/dist/Utils/NetworkDiscovery/ScanNameUtil.js.map +1 -0
- package/build/dist/Utils/StatusPage/ResourceExplorer.js +171 -0
- package/build/dist/Utils/StatusPage/ResourceExplorer.js.map +1 -1
- package/build/dist/Utils/Telemetry/LlmMetricQuery.js +175 -0
- package/build/dist/Utils/Telemetry/LlmMetricQuery.js.map +1 -0
- package/jest.config.json +2 -0
- package/package.json +1 -1
- package/tsconfig.json +2 -1
- package/Tests/UI/Components/Toast.test.tsx +0 -197
- package/Tests/UI/Components/ToastStacking.test.tsx +0 -198
- package/UI/Components/Toast/Toast.tsx +0 -189
- package/UI/Components/Toast/ToastInit.tsx +0 -110
- package/build/dist/UI/Components/Toast/Toast.js +0 -123
- package/build/dist/UI/Components/Toast/Toast.js.map +0 -1
- package/build/dist/UI/Components/Toast/ToastInit.js +0 -53
- package/build/dist/UI/Components/Toast/ToastInit.js.map +0 -1
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { withResourcePrefixedKeys } from "./LlmConventions";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Single source of truth for the OpenTelemetry GenAI **metric** names and
|
|
5
|
+
* attribute keys OneUptime recognizes — the metric-side sibling of
|
|
6
|
+
* Common/Types/Telemetry/LlmConventions.ts, which does the same job for span
|
|
7
|
+
* attributes.
|
|
8
|
+
*
|
|
9
|
+
* Why this exists: the LLM feature was originally span-only. A span carries
|
|
10
|
+
* model, tokens and cost together, so one row answers every question. But a
|
|
11
|
+
* large class of emitters never produce GenAI spans at all:
|
|
12
|
+
*
|
|
13
|
+
* - Native OpenTelemetry GenAI metrics (gen_ai.client.token.usage) emitted
|
|
14
|
+
* by an SDK configured for metrics without tracing.
|
|
15
|
+
* - AI gateways and vendor exporters that publish spend/usage counters only.
|
|
16
|
+
*
|
|
17
|
+
* For those, token and cost totals have to come off the metric stream instead.
|
|
18
|
+
* Both the budget evaluator (Common/Server/Utils/Telemetry/LlmMetricSpend.ts)
|
|
19
|
+
* and anything else that needs metric-sourced LLM figures import these lists,
|
|
20
|
+
* so a newly recognized metric name is added HERE, once.
|
|
21
|
+
*
|
|
22
|
+
* Order matters: within each list the preferred convention comes first.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/*
|
|
26
|
+
* Metric names carrying token counts. `gen_ai.client.token.usage` is the OTel
|
|
27
|
+
* semantic convention (a histogram whose `sum` is the token total); the rest
|
|
28
|
+
* are the spellings the dominant instrumentations shipped before/alongside it.
|
|
29
|
+
*/
|
|
30
|
+
export const LlmTokenUsageMetricNames: Array<string> = [
|
|
31
|
+
"gen_ai.client.token.usage",
|
|
32
|
+
"gen_ai.client.token.count",
|
|
33
|
+
"llm.token.usage",
|
|
34
|
+
"llm.usage.tokens",
|
|
35
|
+
/*
|
|
36
|
+
* Coding-agent CLIs. Every one of these ships OpenTelemetry natively and
|
|
37
|
+
* every one namespaces its metrics under its own vendor prefix rather than
|
|
38
|
+
* gen_ai.*, so before this list knew their names an entire fleet of agents
|
|
39
|
+
* could be exporting straight into OneUptime and still report zero tokens
|
|
40
|
+
* and zero spend. That is the failure mode these three entries fix.
|
|
41
|
+
*/
|
|
42
|
+
// Anthropic Claude Code CLI.
|
|
43
|
+
"claude_code.token.usage",
|
|
44
|
+
// Cursor Enterprise OTel export.
|
|
45
|
+
"cursor.token.usage",
|
|
46
|
+
// OpenAI Codex CLI.
|
|
47
|
+
"codex.turn.token_usage",
|
|
48
|
+
/*
|
|
49
|
+
* DELIBERATELY ABSENT: "gemini_cli.token.usage".
|
|
50
|
+
*
|
|
51
|
+
* Gemini CLI emits BOTH its vendor metric and the semantic-convention
|
|
52
|
+
* `gen_ai.client.token.usage` for the SAME tokens (see the metric table in
|
|
53
|
+
* Docs/Content/en/telemetry/gemini-cli-and-copilot.md, which lists the two
|
|
54
|
+
* side by side). LlmMetricQuery.buildTokenQuery issues ONE query with
|
|
55
|
+
* `name: new Includes(LlmTokenUsageMetricNames)` and groups only by the
|
|
56
|
+
* token-TYPE attribute keys — never by metric name — so both emissions come
|
|
57
|
+
* back as separate rows and reduceTokenRows adds them together. Listing
|
|
58
|
+
* both names would make a Gemini-CLI-only project report exactly 2x its
|
|
59
|
+
* real token count on the AI / LLM Usage view, with no error and no gap in
|
|
60
|
+
* the chart to give it away.
|
|
61
|
+
*
|
|
62
|
+
* Nothing is lost by the omission: the semconv name that stays in this list
|
|
63
|
+
* is emitted by Gemini CLI itself, so its tokens are still counted — once.
|
|
64
|
+
*
|
|
65
|
+
* AUDIT of the three names above, against the vendor docs in
|
|
66
|
+
* Docs/Content/en/telemetry/, because this hazard applies to any emitter
|
|
67
|
+
* that publishes two token metrics:
|
|
68
|
+
* - claude_code.token.usage Claude Code's metric table is entirely
|
|
69
|
+
* claude_code.* — no gen_ai.* metric. Its gen_ai.* keys are on SPANS,
|
|
70
|
+
* which are a different stream and are summed separately.
|
|
71
|
+
* - cursor.token.usage Cursor publishes exactly three metrics, all
|
|
72
|
+
* cursor.*, and emits no gen_ai.* telemetry at all.
|
|
73
|
+
* - codex.turn.token_usage Codex's metrics are codex.*; its gen_ai.*
|
|
74
|
+
* usage attributes are on SPANS, not metrics.
|
|
75
|
+
* None of the three overlaps a semconv metric, so all three stay.
|
|
76
|
+
*
|
|
77
|
+
* Before re-adding ANY vendor token metric, check whether the same process
|
|
78
|
+
* also emits gen_ai.client.token.usage. If it does, leave it out.
|
|
79
|
+
*/
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
/*
|
|
83
|
+
* Metric names carrying spend in USD.
|
|
84
|
+
*
|
|
85
|
+
* There is no OTel semantic convention for LLM cost — every entry below is a
|
|
86
|
+
* vendor spelling. That is precisely why metric-sourced cost is worth
|
|
87
|
+
* supporting: the emitters that publish a cost metric are generally the ones
|
|
88
|
+
* that publish no spans, so this list is the only way their spend is visible.
|
|
89
|
+
*/
|
|
90
|
+
export const LlmCostMetricNames: Array<string> = [
|
|
91
|
+
"gen_ai.client.cost",
|
|
92
|
+
"gen_ai.client.cost.usd",
|
|
93
|
+
"gen_ai.usage.cost",
|
|
94
|
+
// LiteLLM proxy.
|
|
95
|
+
"litellm_spend_metric",
|
|
96
|
+
"litellm.cost.total",
|
|
97
|
+
// Anthropic Claude Code CLI — unit USD.
|
|
98
|
+
"claude_code.cost.usage",
|
|
99
|
+
/*
|
|
100
|
+
* Cursor Enterprise OTel export — unit USD, and documented as a
|
|
101
|
+
* best-effort estimate rather than a billed figure. It is still worth
|
|
102
|
+
* summing: an estimate that is visible beats a true cost nobody can see.
|
|
103
|
+
*/
|
|
104
|
+
"cursor.cost.usage",
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* The multiplier that turns a micro-USD figure into USD. Exported so the
|
|
109
|
+
* scale lives in exactly one place that a test can pin, rather than as a
|
|
110
|
+
* literal 0.000001 sprinkled through the query layer where a typo'd zero
|
|
111
|
+
* would be invisible in review and off by a factor of ten in production.
|
|
112
|
+
*/
|
|
113
|
+
export const MICRO_USD_TO_USD: number = 0.000001;
|
|
114
|
+
|
|
115
|
+
/*
|
|
116
|
+
* Cost metric names denominated in MILLIONTHS of a USD.
|
|
117
|
+
*
|
|
118
|
+
* This list exists separately from LlmCostMetricNames for one reason, and it
|
|
119
|
+
* is worth being blunt about it: the OpenAI Codex CLI reports spend in
|
|
120
|
+
* micro-USD. If "codex.turn.cost_microusd" were appended to the USD list, the
|
|
121
|
+
* shared Sum aggregate would add its raw values to genuinely-USD values and a
|
|
122
|
+
* $3 Codex turn would land in a cost budget as $3,000,000 — instantly
|
|
123
|
+
* breaching every threshold a customer has configured. There is no way to
|
|
124
|
+
* recover the unit after the sum, so the two units must never share a query.
|
|
125
|
+
*
|
|
126
|
+
* Callers query this separately and combine via
|
|
127
|
+
* LlmMetricQuery.combineCostTotals, which applies MICRO_USD_TO_USD in the one
|
|
128
|
+
* tested place.
|
|
129
|
+
*/
|
|
130
|
+
export const LlmMicroUsdCostMetricNames: Array<string> = [
|
|
131
|
+
// OpenAI Codex CLI — unit is millionths of a USD, NOT dollars.
|
|
132
|
+
"codex.turn.cost_microusd",
|
|
133
|
+
];
|
|
134
|
+
|
|
135
|
+
/*
|
|
136
|
+
* Attribute keys naming which side of the exchange a token datapoint counts.
|
|
137
|
+
* The OTel convention is `gen_ai.token.type`; the others are pre-convention
|
|
138
|
+
* spellings still in the wild.
|
|
139
|
+
*/
|
|
140
|
+
export const LlmTokenTypeAttributeKeys: Array<string> = [
|
|
141
|
+
"gen_ai.token.type",
|
|
142
|
+
"llm.token.type",
|
|
143
|
+
/*
|
|
144
|
+
* Claude Code spells it bare: `type`.
|
|
145
|
+
*
|
|
146
|
+
* A one-word key like this looks alarmingly generic, and the risk is worth
|
|
147
|
+
* spelling out because it is bounded rather than absent: these keys are
|
|
148
|
+
* consulted ONLY for rows that already matched one of the LLM metric NAMES
|
|
149
|
+
* above. A `type` attribute on some unrelated business metric is never
|
|
150
|
+
* reached by this code path, because that metric's name never enters the
|
|
151
|
+
* query. The key is also last-but-two in preference order, so any emitter
|
|
152
|
+
* carrying a namespaced spelling as well wins over it.
|
|
153
|
+
*/
|
|
154
|
+
"type",
|
|
155
|
+
// Cursor Enterprise OTel export.
|
|
156
|
+
"cursor.token.type",
|
|
157
|
+
// OpenAI Codex CLI.
|
|
158
|
+
"token_type",
|
|
159
|
+
];
|
|
160
|
+
|
|
161
|
+
/*
|
|
162
|
+
* Attribute values that mean "tokens sent to the model". `prompt` is the
|
|
163
|
+
* pre-1.27 semconv spelling that several instrumentations still emit.
|
|
164
|
+
*/
|
|
165
|
+
export const LlmInputTokenTypeValues: Array<string> = ["input", "prompt"];
|
|
166
|
+
|
|
167
|
+
/*
|
|
168
|
+
* Attribute values that mean "tokens produced by the model".
|
|
169
|
+
*
|
|
170
|
+
* Note what is deliberately absent, and why each exclusion is its own
|
|
171
|
+
* decision rather than an oversight. The coding-agent CLIs emit a richer
|
|
172
|
+
* token vocabulary than the semconv does:
|
|
173
|
+
*
|
|
174
|
+
* Claude Code input | output | cacheRead | cacheCreation (camelCase!)
|
|
175
|
+
* Cursor input | output | cache_read | cache_creation
|
|
176
|
+
* Codex total | input | cached_input | cache_write_input |
|
|
177
|
+
* output | reasoning_output
|
|
178
|
+
*
|
|
179
|
+
* The plain input/output values are covered by the two lists here and need
|
|
180
|
+
* nothing added. The rest are excluded on purpose:
|
|
181
|
+
*
|
|
182
|
+
* - cache_read / cacheRead / cached_input, and
|
|
183
|
+
* cache_creation / cacheCreation / cache_write_input
|
|
184
|
+
* Real token counts, but neither input nor output in the sense the span
|
|
185
|
+
* columns (llmInputTokens / llmOutputTokens) use. Folding them in would
|
|
186
|
+
* silently inflate the metric-sourced totals against the span-sourced
|
|
187
|
+
* ones they stand in for. Cache-aware accounting deserves its own
|
|
188
|
+
* columns; until it has them, these are dropped rather than guessed at.
|
|
189
|
+
* - total
|
|
190
|
+
* A SUPERSET of its siblings. Codex emits it ALONGSIDE the per-kind
|
|
191
|
+
* datapoints, so counting it would add every token a second time.
|
|
192
|
+
* - reasoning_output
|
|
193
|
+
* A SUBSET of `output` — the reasoning share of the same tokens, which
|
|
194
|
+
* Codex also reports under `output`. Counting it would double-count the
|
|
195
|
+
* reasoning portion of every turn.
|
|
196
|
+
*
|
|
197
|
+
* Both classes are pinned by explicit getLlmTokenDirection tests, so a future
|
|
198
|
+
* "why is this not handled?" reads as a decision, not a gap.
|
|
199
|
+
*/
|
|
200
|
+
export const LlmOutputTokenTypeValues: Array<string> = ["output", "completion"];
|
|
201
|
+
|
|
202
|
+
/*
|
|
203
|
+
* Attribute keys naming WHO the metric datapoint belongs to, for grouping
|
|
204
|
+
* metric-sourced spend by employee — the metric-side counterpart of
|
|
205
|
+
* LlmUserIdAttributeKeys in Common/Types/Telemetry/LlmConventions.ts.
|
|
206
|
+
*
|
|
207
|
+
* Email leads here rather than id (the span list is the other way round)
|
|
208
|
+
* because the coding-agent CLIs that dominate the metric-only population emit
|
|
209
|
+
* user.email natively, and it is the one value a manager reads without a
|
|
210
|
+
* lookup table. cursor.user.id sorts last for the same reason it does on the
|
|
211
|
+
* span side: it is an opaque team-scoped integer.
|
|
212
|
+
*
|
|
213
|
+
* Both lists below are resource-widened for the same reason the span lists
|
|
214
|
+
* are: OtelMetricsIngestService flattens resource attributes with the
|
|
215
|
+
* "resource" prefix exactly as the traces service does, so a fleet that
|
|
216
|
+
* stamps identity once on the resource — which is the normal thing to do, and
|
|
217
|
+
* the only thing OTEL_RESOURCE_ATTRIBUTES can do — arrives here as
|
|
218
|
+
* `resource.user.email` / `resource.team.id`. The bare tier still leads, so
|
|
219
|
+
* METRIC_USER_ATTRIBUTE_KEY / METRIC_TEAM_ATTRIBUTE_KEY (element zero, used
|
|
220
|
+
* for scoped filtering in LlmMetricQuery) are unchanged.
|
|
221
|
+
*/
|
|
222
|
+
export const LlmMetricUserBaseAttributeKeys: Array<string> = [
|
|
223
|
+
"user.email",
|
|
224
|
+
"user.id",
|
|
225
|
+
"user.account_uuid",
|
|
226
|
+
"user.account_id",
|
|
227
|
+
"cursor.user.id",
|
|
228
|
+
];
|
|
229
|
+
|
|
230
|
+
export const LlmMetricUserAttributeKeys: Array<string> =
|
|
231
|
+
withResourcePrefixedKeys(LlmMetricUserBaseAttributeKeys);
|
|
232
|
+
|
|
233
|
+
/*
|
|
234
|
+
* Attribute keys naming the team / cost centre a metric datapoint charges to.
|
|
235
|
+
* The first four are conventionally set by the operator via
|
|
236
|
+
* OTEL_RESOURCE_ATTRIBUTES rather than emitted by any instrumentation — which
|
|
237
|
+
* is precisely why the resource tier has to be here too; see above.
|
|
238
|
+
*/
|
|
239
|
+
export const LlmMetricTeamBaseAttributeKeys: Array<string> = [
|
|
240
|
+
"team.id",
|
|
241
|
+
"team",
|
|
242
|
+
"cost_center",
|
|
243
|
+
"department",
|
|
244
|
+
"cursor.team.id",
|
|
245
|
+
];
|
|
246
|
+
|
|
247
|
+
export const LlmMetricTeamAttributeKeys: Array<string> =
|
|
248
|
+
withResourcePrefixedKeys(LlmMetricTeamBaseAttributeKeys);
|
|
249
|
+
|
|
250
|
+
/*
|
|
251
|
+
* Attribute keys naming WHICH MODEL a metric datapoint was produced by.
|
|
252
|
+
*
|
|
253
|
+
* This exists because the vendor cost/token counters DO carry the model on
|
|
254
|
+
* the datapoint even though they carry no provider and no service id:
|
|
255
|
+
* claude_code.cost.usage and claude_code.token.usage stamp a bare `model`,
|
|
256
|
+
* and cursor.cost.usage stamps `cursor.model.name`. Without this list the
|
|
257
|
+
* Model breakdown is empty for an entire fleet of coding agents whose spend
|
|
258
|
+
* is perfectly well attributed to a model — the same failure the user list
|
|
259
|
+
* above fixes for people.
|
|
260
|
+
*
|
|
261
|
+
* `model` is bare and looks alarmingly generic, and the bound is the same one
|
|
262
|
+
* that makes the bare `type` token key safe: these keys are only ever read
|
|
263
|
+
* off rows that already matched one of the LLM metric NAMES above, so a
|
|
264
|
+
* `model` attribute on some unrelated business metric is never reached. It
|
|
265
|
+
* also sorts after the semantic-convention spelling, so an emitter carrying
|
|
266
|
+
* both wins with the namespaced one.
|
|
267
|
+
*
|
|
268
|
+
* Resource-widened for the same reason the identity lists are: a fleet that
|
|
269
|
+
* pins one model per deployment sets it once via OTEL_RESOURCE_ATTRIBUTES,
|
|
270
|
+
* and OtelMetricsIngestService flattens that to `resource.model`.
|
|
271
|
+
*/
|
|
272
|
+
export const LlmMetricModelBaseAttributeKeys: Array<string> = [
|
|
273
|
+
"gen_ai.request.model",
|
|
274
|
+
// Anthropic Claude Code CLI — bare, on both its cost and token counters.
|
|
275
|
+
"model",
|
|
276
|
+
// Cursor Enterprise OTel export.
|
|
277
|
+
"cursor.model.name",
|
|
278
|
+
];
|
|
279
|
+
|
|
280
|
+
export const LlmMetricModelAttributeKeys: Array<string> =
|
|
281
|
+
withResourcePrefixedKeys(LlmMetricModelBaseAttributeKeys);
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Which side of the exchange a `gen_ai.token.type` value denotes, or null
|
|
285
|
+
* when the value is one we deliberately do not count (the cache kinds,
|
|
286
|
+
* `total`, `reasoning_output` — see LlmOutputTokenTypeValues for why each is
|
|
287
|
+
* excluded) or do not recognize at all.
|
|
288
|
+
*
|
|
289
|
+
* Comparison is case-insensitive and whitespace-trimmed: the value reaches us
|
|
290
|
+
* as a free-form OTLP string attribute, and emitters are inconsistent about
|
|
291
|
+
* casing.
|
|
292
|
+
*/
|
|
293
|
+
export type LlmTokenDirection = "input" | "output";
|
|
294
|
+
|
|
295
|
+
export function getLlmTokenDirection(
|
|
296
|
+
attributeValue: string | undefined | null,
|
|
297
|
+
): LlmTokenDirection | null {
|
|
298
|
+
if (typeof attributeValue !== "string") {
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const normalized: string = attributeValue.trim().toLowerCase();
|
|
303
|
+
|
|
304
|
+
if (!normalized) {
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (LlmInputTokenTypeValues.includes(normalized)) {
|
|
309
|
+
return "input";
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (LlmOutputTokenTypeValues.includes(normalized)) {
|
|
313
|
+
return "output";
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* The attribute values to match for a direction. Exposed so query builders
|
|
321
|
+
* and tests share one definition of "what counts as input".
|
|
322
|
+
*/
|
|
323
|
+
export function getLlmTokenTypeValues(
|
|
324
|
+
direction: LlmTokenDirection,
|
|
325
|
+
): Array<string> {
|
|
326
|
+
return direction === "input"
|
|
327
|
+
? LlmInputTokenTypeValues
|
|
328
|
+
: LlmOutputTokenTypeValues;
|
|
329
|
+
}
|
|
@@ -27,6 +27,8 @@ export interface ComponentProps {
|
|
|
27
27
|
isLoadingSuggestions?: boolean | undefined;
|
|
28
28
|
loadingMessage?: string | undefined;
|
|
29
29
|
noSuggestionsMessage?: string | undefined;
|
|
30
|
+
// For inputs with no visible label element to point ariaLabelledby at.
|
|
31
|
+
ariaLabel?: string | undefined;
|
|
30
32
|
/*
|
|
31
33
|
* The id of the element that names this input. Without it a picker that draws
|
|
32
34
|
* its own label - the workflow record editor, where the field's name sits in
|
|
@@ -464,6 +466,7 @@ const AutocompleteTextInput: FunctionComponent<ComponentProps> = (
|
|
|
464
466
|
className={getInputClassName()}
|
|
465
467
|
data-testid={props.dataTestId}
|
|
466
468
|
disabled={props.disabled}
|
|
469
|
+
aria-label={props.ariaLabel}
|
|
467
470
|
aria-labelledby={props.ariaLabelledby}
|
|
468
471
|
aria-autocomplete="list"
|
|
469
472
|
aria-controls={listboxIdRef.current}
|
|
@@ -358,7 +358,16 @@ const BulkUpdateForm: <T extends GenericObject>(
|
|
|
358
358
|
className="h-4 w-4 text-indigo-600"
|
|
359
359
|
/>
|
|
360
360
|
<span>
|
|
361
|
-
{props.selectedItems.length}
|
|
361
|
+
{props.selectedItems.length}{" "}
|
|
362
|
+
{/*
|
|
363
|
+
* The singular when there is one of them. The badge is the
|
|
364
|
+
* one sentence in this bar that is always on screen, and
|
|
365
|
+
* "1 resources Selected" reads as a bug in the count.
|
|
366
|
+
*/}
|
|
367
|
+
{props.selectedItems.length === 1
|
|
368
|
+
? props.singularLabel
|
|
369
|
+
: props.pluralLabel}{" "}
|
|
370
|
+
Selected
|
|
362
371
|
</span>
|
|
363
372
|
</div>
|
|
364
373
|
|