diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx index c756c71b3bc2..62bac514beb8 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx @@ -613,6 +613,7 @@ const RuleDetailsPageComponent: React.FC = ({ enabled={isExistingRule && (rule?.enabled ?? false)} startMlJobsIfNeeded={startMlJobsIfNeeded} onChange={handleOnChangeEnabledRule} + ruleName={rule?.name} /> {i18n.ENABLE_RULE} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_columns.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_columns.tsx index 3e429d94fee2..eeaa93b4c9a3 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_columns.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_columns.tsx @@ -96,6 +96,7 @@ const useEnabledColumn = ({ hasCRUDPermissions, startMlJobs }: ColumnsProps): Ta (isMlRule(rule.type) && !hasMlPermissions) } isLoading={loadingIds.includes(rule.id)} + ruleName={rule.name} /> ), diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.test.tsx index 7174aa7832f9..8698cab56bb4 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.test.tsx @@ -74,6 +74,33 @@ describe('RuleSwitch', () => { expect(wrapper.find('[data-test-subj="ruleSwitch"]').at(0).props().checked).toBeFalsy(); }); + test('it sets the undefined aria-label for switch if ruleName not passed', () => { + const wrapper = mount(, { + wrappingComponent: TestProviders, + }); + expect( + wrapper.find('[data-test-subj="ruleSwitch"]').at(0).props()['aria-label'] + ).toBeUndefined(); + }); + + test('it sets the correct aria-label for switch if "enabled" is true', () => { + const wrapper = mount(, { + wrappingComponent: TestProviders, + }); + expect(wrapper.find('[data-test-subj="ruleSwitch"]').at(0).props()['aria-label']).toBe( + 'Switch off "test"' + ); + }); + + test('it sets the correct aria-label for switch if "enabled" is false', () => { + const wrapper = mount(, { + wrappingComponent: TestProviders, + }); + expect(wrapper.find('[data-test-subj="ruleSwitch"]').at(0).props()['aria-label']).toBe( + 'Switch on "test"' + ); + }); + test('it dispatches error toaster if "enableRules" call rejects', async () => { const mockError = new Error('uh oh'); (performBulkAction as jest.Mock).mockRejectedValue(mockError); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.tsx index 35434a711768..56f70865df68 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.tsx @@ -14,6 +14,7 @@ import { SINGLE_RULE_ACTIONS } from '../../../../common/lib/apm/user_actions'; import { useStartTransaction } from '../../../../common/lib/apm/use_start_transaction'; import { useExecuteBulkAction } from '../../../../detection_engine/rule_management/logic/bulk_actions/use_execute_bulk_action'; import { useRulesTableContextOptional } from '../../../../detection_engine/rule_management_ui/components/rules_table/rules_table/rules_table_context'; +import { ruleSwitchAriaLabel } from './translations'; const StaticSwitch = styled(EuiSwitch)` .euiSwitch__thumb, @@ -31,6 +32,7 @@ export interface RuleSwitchProps { isLoading?: boolean; startMlJobsIfNeeded?: () => Promise; onChange?: (enabled: boolean) => void; + ruleName?: string; } /** @@ -43,8 +45,10 @@ export const RuleSwitchComponent = ({ enabled, startMlJobsIfNeeded, onChange, + ruleName, }: RuleSwitchProps) => { const [myIsLoading, setMyIsLoading] = useState(false); + const ariaLabel = ruleName ? ruleSwitchAriaLabel(ruleName, enabled) : undefined; const rulesTableContext = useRulesTableContextOptional(); const { startTransaction } = useStartTransaction(); const { executeBulkAction } = useExecuteBulkAction({ suppressSuccessToast: !rulesTableContext }); @@ -93,6 +97,7 @@ export const RuleSwitchComponent = ({ disabled={isDisabled} checked={enabled} onChange={onRuleStateChange} + aria-label={ariaLabel} /> )} diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/translations.ts b/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/translations.ts new file mode 100644 index 000000000000..7e85df894b79 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/translations.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const ruleSwitchAriaLabel = (name: string, isActive: boolean) => + i18n.translate('xpack.securitySolution.ruleDetails.ruleSwitch.ariaLabel', { + values: { + name, + action: isActive + ? i18n.translate('xpack.securitySolution.ruleDetails.ruleSwitch.ariaLabel.switchOff', { + defaultMessage: 'Switch off', + }) + : i18n.translate('xpack.securitySolution.ruleDetails.ruleSwitch.ariaLabel.switchOn', { + defaultMessage: 'Switch on', + }), + }, + defaultMessage: '{action} "{name}"', + });