diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx index 01e63f2c6081..311166f09e46 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx @@ -69,6 +69,7 @@ const alertTypeFromApi = { defaultActionGroupId: 'default', producer: ALERTS_FEATURE_ID, minimumLicenseRequired: 'basic', + enabledInLicense: true, authorizedConsumers: { [ALERTS_FEATURE_ID]: { read: true, all: true }, }, @@ -520,3 +521,122 @@ describe('alerts_list with show only capability', () => { // TODO: check delete button }); }); + +describe('alerts_list with disabled itmes', () => { + let wrapper: ReactWrapper; + + async function setup() { + loadAlerts.mockResolvedValue({ + page: 1, + perPage: 10000, + total: 2, + data: [ + { + id: '1', + name: 'test alert', + tags: ['tag1'], + enabled: true, + alertTypeId: 'test_alert_type', + schedule: { interval: '5d' }, + actions: [], + params: { name: 'test alert type name' }, + scheduledTaskId: null, + createdBy: null, + updatedBy: null, + apiKeyOwner: null, + throttle: '1m', + muteAll: false, + mutedInstanceIds: [], + executionStatus: { + status: 'active', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + error: null, + }, + }, + { + id: '2', + name: 'test alert 2', + tags: ['tag1'], + enabled: true, + alertTypeId: 'test_alert_type_disabled_by_license', + schedule: { interval: '5d' }, + actions: [{ id: 'test', group: 'alert', params: { message: 'test' } }], + params: { name: 'test alert type name' }, + scheduledTaskId: null, + createdBy: null, + updatedBy: null, + apiKeyOwner: null, + throttle: '1m', + muteAll: false, + mutedInstanceIds: [], + executionStatus: { + status: 'active', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + error: null, + }, + }, + ], + }); + loadActionTypes.mockResolvedValue([ + { + id: 'test', + name: 'Test', + }, + { + id: 'test2', + name: 'Test2', + }, + ]); + + loadAlertTypes.mockResolvedValue([ + alertTypeFromApi, + { + id: 'test_alert_type_disabled_by_license', + name: 'some alert type that is not allowed', + actionGroups: [{ id: 'default', name: 'Default' }], + recoveryActionGroup: { id: 'recovered', name: 'Recovered' }, + actionVariables: { context: [], state: [] }, + defaultActionGroupId: 'default', + producer: ALERTS_FEATURE_ID, + minimumLicenseRequired: 'platinum', + enabledInLicense: false, + authorizedConsumers: { + [ALERTS_FEATURE_ID]: { read: true, all: true }, + }, + }, + ]); + loadAllActions.mockResolvedValue([]); + + alertTypeRegistry.has.mockReturnValue(false); + // eslint-disable-next-line react-hooks/rules-of-hooks + useKibanaMock().services.alertTypeRegistry = alertTypeRegistry; + + // eslint-disable-next-line react-hooks/rules-of-hooks + useKibanaMock().services.actionTypeRegistry = actionTypeRegistry; + wrapper = mountWithIntl(); + + await act(async () => { + await nextTick(); + wrapper.update(); + }); + } + + it('renders rules list with disabled indicator if disabled due to license', async () => { + await setup(); + expect(wrapper.find('EuiBasicTable')).toHaveLength(1); + expect(wrapper.find('EuiTableRow')).toHaveLength(2); + expect(wrapper.find('EuiTableRow').at(0).prop('className')).toEqual(''); + expect(wrapper.find('EuiTableRow').at(1).prop('className')).toEqual( + 'actAlertsList__tableRowDisabled' + ); + expect(wrapper.find('EuiIconTip[data-test-subj="ruleDisabledByLicenseTooltip"]').length).toBe( + 1 + ); + expect( + wrapper.find('EuiIconTip[data-test-subj="ruleDisabledByLicenseTooltip"]').props().type + ).toEqual('questionInCircle'); + expect( + wrapper.find('EuiIconTip[data-test-subj="ruleDisabledByLicenseTooltip"]').props().content + ).toEqual('This rule type requires a Platinum license.'); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx index 1fb688c4dd6b..1c1633ff4a72 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx @@ -18,6 +18,7 @@ import { EuiFieldSearch, EuiFlexGroup, EuiFlexItem, + EuiIconTip, EuiSpacer, EuiLink, EuiEmptyPrompt, @@ -63,6 +64,7 @@ import { DEFAULT_HIDDEN_ACTION_TYPES } from '../../../../common/constants'; import './alerts_list.scss'; import { CenterJustifiedSpinner } from '../../../components/center_justified_spinner'; import { ManageLicenseModal } from './manage_license_modal'; +import { checkAlertTypeEnabled } from '../../../lib/check_alert_type_enabled'; const ENTER_KEY = 13; @@ -318,15 +320,32 @@ export const AlertsList: React.FunctionComponent = () => { width: '35%', 'data-test-subj': 'alertsTableCell-name', render: (name: string, alert: AlertTableItem) => { - return ( - { - history.push(routeToRuleDetails.replace(`:ruleId`, alert.id)); - }} - > - {name} - + const ruleType = alertTypesState.data.get(alert.alertTypeId); + const checkEnabledResult = checkAlertTypeEnabled(ruleType); + const link = ( + <> + { + history.push(routeToRuleDetails.replace(`:ruleId`, alert.id)); + }} + > + {name} + + + ); + return checkEnabledResult.isEnabled ? ( + link + ) : ( + <> + {link} + + ); }, },