mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Security Solution] Add validations for insight form in timeline and rules (#161034)
## Summary Currently user can add a note in timeline with invalid markdown syntax in insight forms. Same goes to the investigation guide in rule creation -> About. ### Before **In timeline -> Notes**  **On rules -> about**  ### After **Timeline -> Notes** Add note button should be disabled if markdown is invalid  **On rules -> about** Field is red if markdown is invalid  ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
70ed200434
commit
08a57b9e3a
7 changed files with 49 additions and 12 deletions
|
@ -30,6 +30,7 @@ interface MarkdownEditorProps {
|
|||
dataTestSubj?: string;
|
||||
height?: number;
|
||||
autoFocusDisabled?: boolean;
|
||||
setIsMarkdownInvalid: (value: boolean) => void;
|
||||
}
|
||||
|
||||
type EuiMarkdownEditorRef = ElementRef<typeof EuiMarkdownEditor>;
|
||||
|
@ -41,11 +42,27 @@ export interface MarkdownEditorRef {
|
|||
}
|
||||
|
||||
const MarkdownEditorComponent = forwardRef<MarkdownEditorRef, MarkdownEditorProps>(
|
||||
({ onChange, value, ariaLabel, editorId, dataTestSubj, height, autoFocusDisabled }, ref) => {
|
||||
(
|
||||
{
|
||||
onChange,
|
||||
value,
|
||||
ariaLabel,
|
||||
editorId,
|
||||
dataTestSubj,
|
||||
height,
|
||||
autoFocusDisabled,
|
||||
setIsMarkdownInvalid,
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const [markdownErrorMessages, setMarkdownErrorMessages] = useState([]);
|
||||
const onParse = useCallback((err, { messages }) => {
|
||||
setMarkdownErrorMessages(err ? [err] : messages);
|
||||
}, []);
|
||||
const onParse = useCallback(
|
||||
(err, { messages }) => {
|
||||
setMarkdownErrorMessages(err ? [err] : messages);
|
||||
setIsMarkdownInvalid(err ? true : false);
|
||||
},
|
||||
[setIsMarkdownInvalid]
|
||||
);
|
||||
const editorRef = useRef<EuiMarkdownEditorRef>(null);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { forwardRef } from 'react';
|
||||
import React, { forwardRef, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import type { EuiMarkdownEditorProps } from '@elastic/eui';
|
||||
import { EuiFormRow, EuiFlexItem, EuiFlexGroup } from '@elastic/eui';
|
||||
|
@ -34,6 +34,7 @@ export const MarkdownEditorForm = React.memo(
|
|||
forwardRef<MarkdownEditorRef, MarkdownEditorFormProps>(
|
||||
({ id, field, dataTestSubj, idAria, bottomRightContent }, ref) => {
|
||||
const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field);
|
||||
const [isMarkdownInvalid, setIsMarkdownInvalid] = useState(false);
|
||||
|
||||
return (
|
||||
<EuiFormRow
|
||||
|
@ -42,7 +43,7 @@ export const MarkdownEditorForm = React.memo(
|
|||
error={errorMessage}
|
||||
fullWidth
|
||||
helpText={field.helpText}
|
||||
isInvalid={isInvalid}
|
||||
isInvalid={isInvalid || isMarkdownInvalid}
|
||||
label={field.label}
|
||||
labelAppend={field.labelAppend}
|
||||
>
|
||||
|
@ -54,6 +55,7 @@ export const MarkdownEditorForm = React.memo(
|
|||
onChange={field.setValue}
|
||||
value={field.value as string}
|
||||
data-test-subj={`${dataTestSubj}-markdown-editor`}
|
||||
setIsMarkdownInvalid={setIsMarkdownInvalid}
|
||||
/>
|
||||
{bottomRightContent && (
|
||||
<BottomContentWrapper justifyContent={'flexEnd'}>
|
||||
|
|
|
@ -10,6 +10,7 @@ exports[`NewNote renders correctly 1`] = `
|
|||
dataTestSubj="add-a-note"
|
||||
height={200}
|
||||
onChange={[MockFunction]}
|
||||
setIsMarkdownInvalid={[MockFunction]}
|
||||
value="The contents of a new note"
|
||||
/>
|
||||
</NewNoteTabs>
|
||||
|
|
|
@ -41,6 +41,7 @@ describe('AddNote', () => {
|
|||
newNote: note,
|
||||
onCancelAddNote: jest.fn(),
|
||||
updateNewNote: jest.fn(),
|
||||
setIsMarkdownInvalid: jest.fn(),
|
||||
};
|
||||
|
||||
test('renders correctly', () => {
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
EuiFlexItem,
|
||||
EuiScreenReaderOnly,
|
||||
} from '@elastic/eui';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
|
@ -56,6 +56,7 @@ export const AddNote = React.memo<{
|
|||
}>(({ associateNote, newNote, onCancelAddNote, updateNewNote, autoFocusDisabled = false }) => {
|
||||
const dispatch = useDispatch();
|
||||
const authenticatedUser = useCurrentUser();
|
||||
const [isMarkdownInvalid, setIsMarkdownInvalid] = useState(false);
|
||||
const updateNote = useCallback(
|
||||
(note: Note) => dispatch(appActions.updateNote({ note })),
|
||||
[dispatch]
|
||||
|
@ -88,8 +89,8 @@ export const AddNote = React.memo<{
|
|||
);
|
||||
|
||||
const isAddNoteDisabled = useMemo(() => {
|
||||
return newNote.trim().length === 0;
|
||||
}, [newNote]);
|
||||
return newNote.trim().length === 0 || isMarkdownInvalid;
|
||||
}, [newNote, isMarkdownInvalid]);
|
||||
|
||||
return (
|
||||
<AddNotesContainer onKeyDown={onKeyDown} role="dialog">
|
||||
|
@ -102,6 +103,7 @@ export const AddNote = React.memo<{
|
|||
noteInputHeight={200}
|
||||
updateNewNote={updateNewNote}
|
||||
autoFocusDisabled={autoFocusDisabled}
|
||||
setIsMarkdownInvalid={setIsMarkdownInvalid}
|
||||
/>
|
||||
<ButtonsContainer gutterSize="none">
|
||||
{onCancelAddNote != null ? (
|
||||
|
|
|
@ -15,13 +15,25 @@ describe('NewNote', () => {
|
|||
|
||||
test('renders correctly', () => {
|
||||
const wrapper = shallow(
|
||||
<NewNote noteInputHeight={200} note={note} updateNewNote={jest.fn()} />
|
||||
<NewNote
|
||||
noteInputHeight={200}
|
||||
note={note}
|
||||
updateNewNote={jest.fn()}
|
||||
setIsMarkdownInvalid={jest.fn()}
|
||||
/>
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('it renders a text area containing the contents of a new (raw) note', () => {
|
||||
const wrapper = mount(<NewNote noteInputHeight={200} note={note} updateNewNote={jest.fn()} />);
|
||||
const wrapper = mount(
|
||||
<NewNote
|
||||
noteInputHeight={200}
|
||||
note={note}
|
||||
updateNewNote={jest.fn()}
|
||||
setIsMarkdownInvalid={jest.fn()}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper.find('[data-test-subj="add-a-note"] .euiMarkdownEditorDropZone').first().text()
|
||||
|
|
|
@ -25,7 +25,8 @@ export const NewNote = React.memo<{
|
|||
note: string;
|
||||
updateNewNote: UpdateInternalNewNote;
|
||||
autoFocusDisabled?: boolean;
|
||||
}>(({ note, noteInputHeight, updateNewNote, autoFocusDisabled = false }) => {
|
||||
setIsMarkdownInvalid: (value: boolean) => void;
|
||||
}>(({ note, noteInputHeight, updateNewNote, autoFocusDisabled = false, setIsMarkdownInvalid }) => {
|
||||
return (
|
||||
<NewNoteTabs data-test-subj="new-note-tabs">
|
||||
<MarkdownEditor
|
||||
|
@ -35,6 +36,7 @@ export const NewNote = React.memo<{
|
|||
dataTestSubj="add-a-note"
|
||||
height={noteInputHeight}
|
||||
autoFocusDisabled={autoFocusDisabled}
|
||||
setIsMarkdownInvalid={setIsMarkdownInvalid}
|
||||
/>
|
||||
</NewNoteTabs>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue