From a8b2810629e0b4650af886e9e8c6ccaa746e456a Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 31 Aug 2020 13:55:16 -0700 Subject: [PATCH] Added validation to display an error when creating index action in alert with invalid document. (#75929) --- .../es_index/es_index.test.tsx | 20 ++++++++++++++++--- .../es_index/es_index.tsx | 19 ++++++++++++++++-- .../es_index/es_index_params.tsx | 18 ++++++++++++++--- .../webhook/webhook_params.tsx | 7 ++++++- .../json_editor_with_message_variables.tsx | 5 ++++- 5 files changed, 59 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index.test.tsx index 417a9e09086a2..b56ae35df5d06 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index.test.tsx @@ -72,17 +72,31 @@ describe('index connector validation with minimal config', () => { describe('action params validation', () => { test('action params validation succeeds when action params is valid', () => { const actionParams = { - documents: ['test'], + documents: [{ test: 1234 }], }; expect(actionTypeModel.validateParams(actionParams)).toEqual({ - errors: {}, + errors: { + documents: [], + }, }); const emptyActionParams = {}; expect(actionTypeModel.validateParams(emptyActionParams)).toEqual({ - errors: {}, + errors: { + documents: ['Document is required and should be a valid JSON object.'], + }, + }); + + const invalidDocumentActionParams = { + documents: [{}], + }; + + expect(actionTypeModel.validateParams(invalidDocumentActionParams)).toEqual({ + errors: { + documents: ['Document is required and should be a valid JSON object.'], + }, }); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index.tsx index 3ee663a5fc8a0..c0255650e0f37 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index.tsx @@ -44,8 +44,23 @@ export function getActionType(): ActionTypeModel import('./es_index_connector')), actionParamsFields: lazy(() => import('./es_index_params')), - validateParams: (): ValidationResult => { - return { errors: {} }; + validateParams: (actionParams: IndexActionParams): ValidationResult => { + const validationResult = { errors: {} }; + const errors = { + documents: new Array(), + }; + validationResult.errors = errors; + if (!actionParams.documents?.length || Object.keys(actionParams.documents[0]).length === 0) { + errors.documents.push( + i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.error.requiredDocumentJson', + { + defaultMessage: 'Document is required and should be a valid JSON object.', + } + ) + ); + } + return validationResult; }, }; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_params.tsx index e8e8cc582512e..495707db4975c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_params.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_params.tsx @@ -17,6 +17,7 @@ export const IndexParamsFields = ({ editAction, messageVariables, docLinks, + errors, }: ActionParamsProps) => { const { documents } = actionParams; @@ -24,8 +25,10 @@ export const IndexParamsFields = ({ try { const documentsJSON = JSON.parse(updatedDocuments); editAction('documents', [documentsJSON], index); - // eslint-disable-next-line no-empty - } catch (e) {} + } catch (e) { + // set document as empty to turn on the validation for non empty valid JSON object + editAction('documents', [{}], index); + } }; return ( @@ -34,7 +37,7 @@ export const IndexParamsFields = ({ messageVariables={messageVariables} paramsProperty={'documents'} inputTargetValue={ - documents && documents.length > 0 ? ((documents[0] as unknown) as string) : '' + documents && documents.length > 0 ? ((documents[0] as unknown) as string) : undefined } label={i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.indexAction.documentsFieldLabel', @@ -48,6 +51,7 @@ export const IndexParamsFields = ({ defaultMessage: 'Code editor', } )} + errors={errors.documents as string[]} onDocumentsChange={onDocumentsChange} helpText={ } + onBlur={() => { + if ( + !(documents && documents.length > 0 ? ((documents[0] as unknown) as string) : undefined) + ) { + // set document as empty to turn on the validation for non empty valid JSON object + onDocumentsChange('{}'); + } + }} /> ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_params.tsx index 1dfd9e3edc2c5..ff9ad936f224f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_params.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_params.tsx @@ -21,7 +21,7 @@ const WebhookParamsFields: React.FunctionComponent { editAction('body', json, index); }} + onBlur={() => { + if (!body) { + editAction('body', '', index); + } + }} /> ); }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/json_editor_with_message_variables.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/json_editor_with_message_variables.tsx index 0b8184fc441fd..5ea15deb53161 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/json_editor_with_message_variables.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/json_editor_with_message_variables.tsx @@ -14,12 +14,13 @@ import { ActionVariable } from '../../types'; interface Props { messageVariables?: ActionVariable[]; paramsProperty: string; - inputTargetValue: string; + inputTargetValue?: string; label: string; errors?: string[]; areaLabel?: string; onDocumentsChange: (data: string) => void; helpText?: JSX.Element; + onBlur?: () => void; } export const JsonEditorWithMessageVariables: React.FunctionComponent = ({ @@ -31,6 +32,7 @@ export const JsonEditorWithMessageVariables: React.FunctionComponent = ({ areaLabel, onDocumentsChange, helpText, + onBlur, }) => { const [cursorPosition, setCursorPosition] = useState(null); @@ -84,6 +86,7 @@ export const JsonEditorWithMessageVariables: React.FunctionComponent = ({ onDocumentsChange(convertToJson(xjson)); }} onCursorChange={(_value: any) => onClickWithMessageVariable(_value)} + onBlur={onBlur} /> );