diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_system_actions_item.test.tsx b/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_system_actions_item.test.tsx index a64dcca57387f..c94062e320a8d 100644 --- a/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_system_actions_item.test.tsx +++ b/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_system_actions_item.test.tsx @@ -21,6 +21,7 @@ import { import { ActionTypeModel } from '../../common'; import { RuleActionsMessageProps } from './rule_actions_message'; import { RuleActionsSystemActionsItem } from './rule_actions_system_actions_item'; +import { I18nProvider } from '@kbn/i18n-react'; jest.mock('../hooks', () => ({ useRuleFormState: jest.fn(), @@ -81,7 +82,7 @@ const { validateParamsForWarnings } = jest.requireMock( '../validation/validate_params_for_warnings' ); -const mockConnectors = [getConnector('1', { id: 'action-1' })]; +const mockConnectors = [getConnector('1', { id: 'action-1', isSystemAction: true })]; const mockActionTypes = [getActionType('1')]; @@ -260,4 +261,59 @@ describe('ruleActionsSystemActionsItem', () => { expect(screen.getByText('warning message!')).toBeInTheDocument(); }); + + describe('licensing', () => { + it('should render the licensing message if the user does not have the sufficient license', async () => { + const mockConnectorsWithLicensing = [ + getConnector('1', { id: 'action-1', isSystemAction: true }), + ]; + const mockActionTypesWithLicensing = [ + getActionType('1', { + enabledInLicense: false, + minimumLicenseRequired: 'platinum' as const, + }), + ]; + + const actionTypeRegistry = new TypeRegistry(); + actionTypeRegistry.register( + getActionTypeModel('1', { + id: 'actionType-1', + validateParams: mockValidate, + }) + ); + useRuleFormState.mockReturnValue({ + plugins: { + actionTypeRegistry, + http: { + basePath: { + publicBaseUrl: 'publicUrl', + }, + }, + }, + actionsParamsErrors: {}, + selectedRuleType: { + ...ruleType, + enabledInLicense: false, + minimumLicenseRequired: 'platinum' as const, + }, + aadTemplateFields: [], + connectors: mockConnectorsWithLicensing, + connectorTypes: mockActionTypesWithLicensing, + }); + + render( + + + + ); + + expect( + await screen.findByText('This feature requires a Platinum license.') + ).toBeInTheDocument(); + }); + }); }); diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_system_actions_item.tsx b/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_system_actions_item.tsx index 4598d42d91aac..7432aa4c4343d 100644 --- a/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_system_actions_item.tsx +++ b/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_system_actions_item.tsx @@ -28,7 +28,7 @@ import { RuleActionParam, RuleSystemAction } from '@kbn/alerting-types'; import { SavedObjectAttribute } from '@kbn/core/types'; import { css } from '@emotion/react'; import { useRuleFormDispatch, useRuleFormState } from '../hooks'; -import { RuleFormParamsErrors } from '../../common'; +import { ActionConnector, RuleFormParamsErrors } from '../../common'; import { ACTION_ERROR_TOOLTIP, ACTION_WARNING_TITLE, @@ -38,6 +38,11 @@ import { import { RuleActionsMessage } from './rule_actions_message'; import { validateParamsForWarnings } from '../validation'; import { getAvailableActionVariables } from '../../action_variables'; +import { + IsDisabledResult, + IsEnabledResult, + checkActionFormActionTypeEnabled, +} from '../utils/check_action_type_enabled'; interface RuleActionsSystemActionsItemProps { action: RuleSystemAction; @@ -45,6 +50,64 @@ interface RuleActionsSystemActionsItemProps { producerId: string; } +interface SystemActionAccordionContentProps extends RuleActionsSystemActionsItemProps { + connector: ActionConnector; + checkEnabledResult?: IsEnabledResult | IsDisabledResult | null; + warning?: string | null; + onParamsChange: (key: string, value: RuleActionParam) => void; +} + +const SystemActionAccordionContent: React.FC = React.memo( + ({ connector, checkEnabledResult, action, index, producerId, warning, onParamsChange }) => { + const { aadTemplateFields } = useRuleFormState(); + const { euiTheme } = useEuiTheme(); + const plain = useEuiBackgroundColor('plain'); + + if (!connector || !checkEnabledResult) { + return null; + } + + if (!checkEnabledResult.isEnabled) { + return ( + + {checkEnabledResult.messageCard} + + ); + } + + return ( + + + + + + ); + } +); + export const RuleActionsSystemActionsItem = (props: RuleActionsSystemActionsItemProps) => { const { action, index, producerId } = props; @@ -54,7 +117,6 @@ export const RuleActionsSystemActionsItem = (props: RuleActionsSystemActionsItem selectedRuleType, connectorTypes, connectors, - aadTemplateFields, } = useRuleFormState(); const [isOpen, setIsOpen] = useState(true); @@ -64,7 +126,6 @@ export const RuleActionsSystemActionsItem = (props: RuleActionsSystemActionsItem const [warning, setWarning] = useState(null); const subdued = useEuiBackgroundColor('subdued'); - const plain = useEuiBackgroundColor('plain'); const { euiTheme } = useEuiTheme(); const dispatch = useRuleFormDispatch(); @@ -156,6 +217,13 @@ export const RuleActionsSystemActionsItem = (props: RuleActionsSystemActionsItem ] ); + const checkEnabledResult = useMemo(() => { + if (!actionType) { + return null; + } + return checkActionFormActionTypeEnabled(actionType, []); + }, [actionType]); + return ( } > - - - - - + ); }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/system_action_type_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/system_action_type_form.test.tsx index 3fb8207e45ef3..440e24017fab6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/system_action_type_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/system_action_type_form.test.tsx @@ -209,4 +209,64 @@ describe('action_type_form', () => { expect(setActionParamsProperty).toHaveBeenCalledWith('my-key', 'my-value', 1); }); + + describe('licensing', () => { + const actionTypeIndexDefaultWithLicensing = { + ...actionTypeIndexDefault, + '.test-system-action': { + ...actionTypeIndexDefault['.test-system-action'], + enabledInLicense: false, + minimumLicenseRequired: 'platinum' as const, + }, + }; + + beforeEach(() => { + const actionType = actionTypeRegistryMock.createMockActionTypeModel({ + id: '.test-system-action-with-license', + iconClass: 'test', + selectMessage: 'test', + validateParams: (): Promise> => { + const validationResult = { errors: {} }; + return Promise.resolve(validationResult); + }, + actionConnectorFields: null, + actionParamsFields: mockedActionParamsFields, + defaultActionParams: { + dedupKey: 'test', + eventAction: 'resolve', + }, + isSystemActionType: true, + }); + + actionTypeRegistry.get.mockReturnValue(actionType); + + jest.clearAllMocks(); + }); + + it('should render the licensing message if the user does not have the sufficient license', async () => { + render( + + + + ); + + expect( + await screen.findByText('This feature requires a Platinum license.') + ).toBeInTheDocument(); + }); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/system_action_type_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/system_action_type_form.tsx index d869449bcd929..36da1b594433d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/system_action_type_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/system_action_type_form.tsx @@ -28,6 +28,7 @@ import { isEmpty, partition, some } from 'lodash'; import { ActionVariable, RuleActionParam } from '@kbn/alerting-plugin/common'; import { ActionGroupWithMessageVariables } from '@kbn/triggers-actions-ui-types'; import { transformActionVariables } from '@kbn/alerts-ui-shared/src/action_variables/transforms'; +import { checkActionFormActionTypeEnabled } from '@kbn/alerts-ui-shared/src/rule_form/utils/check_action_type_enabled'; import { TECH_PREVIEW_DESCRIPTION, TECH_PREVIEW_LABEL } from '../translations'; import { IErrorObject, @@ -167,8 +168,12 @@ export const SystemActionTypeForm = ({ }; const ParamsFieldsComponent = actionTypeRegistered.actionParamsFields; + const checkEnabledResult = checkActionFormActionTypeEnabled( + actionTypesIndex[actionConnector.actionTypeId], + [] + ); - const accordionContent = ( + const accordionContent = checkEnabledResult.isEnabled ? ( <> {ParamsFieldsComponent ? ( @@ -212,6 +217,8 @@ export const SystemActionTypeForm = ({ ) : null} + ) : ( + checkEnabledResult.messageCard ); return (