Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security Solutions][Cases] Cases Redesign #73247

Merged
merged 43 commits into from
Sep 17, 2020
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
a8f10f9
Create UserActionTimestamp component
cnasikas Jul 26, 2020
e7657d8
Improve UserActionAvatar component
cnasikas Jul 26, 2020
a76de88
Init layout
cnasikas Jul 26, 2020
1842c09
Add actions
cnasikas Jul 26, 2020
e2eee10
Add footers
cnasikas Jul 26, 2020
226feb4
Add username tooltip
cnasikas Jul 27, 2020
39df02d
Add loading spinner to avatar
cnasikas Jul 27, 2020
e7c013c
Move to comment
cnasikas Jul 27, 2020
a5aad3c
Add bottom actions
cnasikas Jul 27, 2020
20fccf7
Fix timestamp updated text
cnasikas Jul 27, 2020
433305f
Remove unused components
cnasikas Jul 27, 2020
5191e24
Fix unnecessary render
cnasikas Jul 27, 2020
e29e17a
Add username with avatar to events
cnasikas Jul 27, 2020
e1d4f0d
Init new markdown
cnasikas Sep 3, 2020
3217118
Improve markdown layout
cnasikas Sep 3, 2020
7f74dbb
Create timeline plugin
cnasikas Sep 4, 2020
f49a992
Fix unit tests
cnasikas Sep 4, 2020
0472664
Fix types
cnasikas Sep 7, 2020
3424f73
Add more tests
cnasikas Sep 8, 2020
f53bed4
Support timeline's old formatting
cnasikas Sep 10, 2020
0317e92
Rename markdown form
cnasikas Sep 10, 2020
b7646a2
Move useTimelineClick to common utils
cnasikas Sep 10, 2020
6217682
Improve tags
cnasikas Sep 10, 2020
aca89d2
Improve UserActionAvatar logic
cnasikas Sep 10, 2020
5d2f6d8
Use formatUrl
cnasikas Sep 10, 2020
0aa24bd
Improve callbacks
cnasikas Sep 10, 2020
84045d4
Improve complexity
cnasikas Sep 10, 2020
29b1892
Parse only timeline's urls
cnasikas Sep 14, 2020
432777d
Fix cypress tests
cnasikas Sep 14, 2020
5952cac
Fix copy reference link
cnasikas Sep 14, 2020
33f9397
Improve memoization
cnasikas Sep 14, 2020
488d898
Unskip tests
cnasikas Sep 14, 2020
7273287
Create UserActionContentToolbar
cnasikas Sep 14, 2020
54ed34b
Improve id
cnasikas Sep 14, 2020
aafbc26
Revert to old formatting
cnasikas Sep 16, 2020
a015a72
use useFormatUrl + simplify parser
XavierM Sep 16, 2020
6bf8009
Update rule note to use new markdown component
yctercero Sep 16, 2020
7185d51
Add translations
cnasikas Sep 16, 2020
b2f5d9d
Improve variable
cnasikas Sep 16, 2020
b544b70
Remove old markdown
cnasikas Sep 16, 2020
4c21106
Merge branch 'master' into cases_redesign
elasticmachine Sep 16, 2020
421548b
Fix cypress tests
cnasikas Sep 17, 2020
aa50719
Merge branch 'master' into cases_redesign
elasticmachine Sep 17, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,16 @@ import {
ALL_CASES_TAGS_COUNT,
} from '../screens/all_cases';
import {
ACTION,
CASE_DETAILS_DESCRIPTION,
CASE_DETAILS_PAGE_TITLE,
CASE_DETAILS_PUSH_TO_EXTERNAL_SERVICE_BTN,
CASE_DETAILS_STATUS,
CASE_DETAILS_TAGS,
CASE_DETAILS_USER_ACTION,
CASE_DETAILS_USER_ACTION_DESCRIPTION_USERNAME,
CASE_DETAILS_USER_ACTION_DESCRIPTION_EVENT,
CASE_DETAILS_USERNAMES,
PARTICIPANTS,
REPORTER,
USER,
} from '../screens/case_details';
import { TIMELINE_DESCRIPTION, TIMELINE_QUERY, TIMELINE_TITLE } from '../screens/timeline';

Expand Down Expand Up @@ -84,8 +83,8 @@ describe('Cases', () => {
const expectedTags = case1.tags.join('');
cy.get(CASE_DETAILS_PAGE_TITLE).should('have.text', case1.name);
cy.get(CASE_DETAILS_STATUS).should('have.text', 'open');
cy.get(CASE_DETAILS_USER_ACTION).eq(USER).should('have.text', case1.reporter);
cy.get(CASE_DETAILS_USER_ACTION).eq(ACTION).should('have.text', 'added description');
cy.get(CASE_DETAILS_USER_ACTION_DESCRIPTION_USERNAME).should('have.text', case1.reporter);
cy.get(CASE_DETAILS_USER_ACTION_DESCRIPTION_EVENT).should('have.text', 'added description');
cy.get(CASE_DETAILS_DESCRIPTION).should(
'have.text',
`${case1.description} ${case1.timeline.title}`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
addNewCase,
selectCase,
} from '../tasks/timeline';
import { DESCRIPTION_INPUT } from '../screens/create_new_case';
import { DESCRIPTION_INPUT, ADD_COMMENT_INPUT } from '../screens/create_new_case';
import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver';
import { caseTimeline, TIMELINE_CASE_ID } from '../objects/case';

Expand Down Expand Up @@ -66,7 +66,7 @@ describe('attach timeline to case', () => {
selectCase(TIMELINE_CASE_ID);

cy.location('origin').then((origin) => {
cy.get(DESCRIPTION_INPUT).should(
cy.get(ADD_COMMENT_INPUT).should(
'have.text',
`[${caseTimeline.title}](${origin}/app/security/timelines?timeline=(id:'${caseTimeline.id}',isOpen:!t))`
);
Expand Down
16 changes: 9 additions & 7 deletions x-pack/plugins/security_solution/cypress/screens/case_details.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/

export const ACTION = 2;

export const CASE_DETAILS_DESCRIPTION = '[data-test-subj="markdown-root"]';
export const CASE_DETAILS_DESCRIPTION =
'[data-test-subj="description-action"] [data-test-subj="user-action-markdown"]';

export const CASE_DETAILS_PAGE_TITLE = '[data-test-subj="header-page-title"]';

Expand All @@ -17,14 +16,17 @@ export const CASE_DETAILS_STATUS = '[data-test-subj="case-view-status"]';

export const CASE_DETAILS_TAGS = '[data-test-subj="case-tags"]';

export const CASE_DETAILS_TIMELINE_LINK_MARKDOWN = '[data-test-subj="markdown-timeline-link"]';
export const CASE_DETAILS_TIMELINE_LINK_MARKDOWN =
'[data-test-subj="description-action"] [data-test-subj="user-action-markdown"] button';

export const CASE_DETAILS_USER_ACTION_DESCRIPTION_EVENT =
'[data-test-subj="description-action"] .euiCommentEvent__headerEvent';

export const CASE_DETAILS_USER_ACTION = '[data-test-subj="user-action-title"] .euiFlexItem';
export const CASE_DETAILS_USER_ACTION_DESCRIPTION_USERNAME =
'[data-test-subj="description-action"] .euiCommentEvent__headerUsername';

export const CASE_DETAILS_USERNAMES = '[data-test-subj="case-view-username"]';

export const PARTICIPANTS = 1;

export const REPORTER = 0;

export const USER = 1;
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
* you may not use this file except in compliance with the Elastic License.
*/

export const ADD_COMMENT_INPUT = '[data-test-subj="add-comment"] textarea';

export const BACK_TO_CASES_BTN = '[data-test-subj="backToCases"]';

export const DESCRIPTION_INPUT = '[data-test-subj="textAreaInput"]';
export const DESCRIPTION_INPUT = '[data-test-subj="caseDescription"] textarea';

export const INSERT_TIMELINE_BTN = '[data-test-subj="insert-timeline-button"]';
export const INSERT_TIMELINE_BTN = '.euiMarkdownEditorToolbar [aria-label="Insert timeline link"]';

export const LOADING_SPINNER = '[data-test-subj="create-case-loading-spinner"]';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
INSERT_TIMELINE_BTN,
LOADING_SPINNER,
TAGS_INPUT,
TIMELINE,
TIMELINE_SEARCHBOX,
TITLE_INPUT,
} from '../screens/create_new_case';
Expand Down Expand Up @@ -43,9 +42,6 @@ export const createNewCaseWithTimeline = (newCase: TestCase) => {

cy.get(INSERT_TIMELINE_BTN).click({ force: true });
cy.get(TIMELINE_SEARCHBOX).type(`${newCase.timeline.title}{enter}`);
cy.get(TIMELINE).should('be.visible');
cy.wait(300);
cy.get(TIMELINE).eq(0).click({ force: true });

cy.get(SUBMIT_BTN).click({ force: true });
cy.get(LOADING_SPINNER).should('exist');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import styled from 'styled-components';
import { CommentRequest } from '../../../../../case/common/api';
import { usePostComment } from '../../containers/use_post_comment';
import { Case } from '../../containers/types';
import { MarkdownEditorForm } from '../../../common/components/markdown_editor/form';
import { MarkdownEditorForm } from '../../../common/components/markdown_editor/eui_form';
import { InsertTimelinePopover } from '../../../timelines/components/timeline/insert_timeline_popover';
import { useInsertTimeline } from '../../../timelines/components/timeline/insert_timeline_popover/use_insert_timeline';
import { Form, useForm, UseField, useFormData } from '../../../shared_imports';

import * as i18n from './translations';
import { schema } from './schema';
import { useTimelineClick } from '../utils/use_timeline_click';
import { useTimelineClick } from '../../../common/utils/timeline/use_timeline_click';

const MySpinner = styled(EuiLoadingSpinner)`
position: absolute;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,34 +114,41 @@ describe('CaseView ', () => {
expect(wrapper.find(`[data-test-subj="case-view-title"]`).first().prop('title')).toEqual(
data.title
);

expect(wrapper.find(`[data-test-subj="case-view-status"]`).first().text()).toEqual(
data.status
);

expect(
wrapper
.find(`[data-test-subj="case-view-tag-list"] [data-test-subj="case-tag-coke"]`)
.find(`[data-test-subj="case-view-tag-list"] [data-test-subj="tag-coke"]`)
.first()
.text()
).toEqual(data.tags[0]);

expect(
wrapper
.find(`[data-test-subj="case-view-tag-list"] [data-test-subj="case-tag-pepsi"]`)
.find(`[data-test-subj="case-view-tag-list"] [data-test-subj="tag-pepsi"]`)
.first()
.text()
).toEqual(data.tags[1]);

expect(wrapper.find(`[data-test-subj="case-view-username"]`).first().text()).toEqual(
data.createdBy.username
);

expect(wrapper.contains(`[data-test-subj="case-view-closedAt"]`)).toBe(false);

expect(wrapper.find(`[data-test-subj="case-view-createdAt"]`).first().prop('value')).toEqual(
data.createdAt
);

expect(
wrapper
.find(`[data-test-subj="description-action"] [data-test-subj="user-action-markdown"]`)
.first()
.prop('raw')
).toEqual(data.description);
.text()
).toBe(data.description);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ import { schema } from './schema';
import { InsertTimelinePopover } from '../../../timelines/components/timeline/insert_timeline_popover';
import { useInsertTimeline } from '../../../timelines/components/timeline/insert_timeline_popover/use_insert_timeline';
import * as i18n from '../../translations';
import { MarkdownEditorForm } from '../../../common/components//markdown_editor/form';
import { MarkdownEditorForm } from '../../../common/components/markdown_editor/eui_form';
import { useGetTags } from '../../containers/use_get_tags';
import { getCaseDetailsUrl } from '../../../common/components/link_to';
import { useTimelineClick } from '../utils/use_timeline_click';
import { useTimelineClick } from '../../../common/utils/timeline/use_timeline_click';

export const CommonUseField = getUseField({ component: Field });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ describe('TagList ', () => {
fetchTags,
}));
});

it('Renders no tags, and then edit', () => {
const wrapper = mount(
<TestProviders>
Expand All @@ -69,6 +70,7 @@ describe('TagList ', () => {
expect(wrapper.find(`[data-test-subj="no-tags"]`).last().exists()).toBeFalsy();
expect(wrapper.find(`[data-test-subj="edit-tags"]`).last().exists()).toBeTruthy();
});

it('Edit tag on submit', async () => {
const wrapper = mount(
<TestProviders>
Expand All @@ -81,6 +83,7 @@ describe('TagList ', () => {
await waitFor(() => expect(onSubmit).toBeCalledWith(sampleTags));
});
});

it('Tag options render with new tags added', () => {
const wrapper = mount(
<TestProviders>
Expand All @@ -92,6 +95,7 @@ describe('TagList ', () => {
wrapper.find(`[data-test-subj="caseTags"] [data-test-subj="input"]`).first().prop('options')
).toEqual([{ label: 'coke' }, { label: 'pepsi' }, { label: 'rad' }, { label: 'dude' }]);
});

it('Cancels on cancel', async () => {
const props = {
...defaultProps,
Expand All @@ -102,17 +106,19 @@ describe('TagList ', () => {
<TagList {...props} />
</TestProviders>
);
expect(wrapper.find(`[data-test-subj="case-tag-pepsi"]`).last().exists()).toBeTruthy();

expect(wrapper.find(`[data-test-subj="tag-pepsi"]`).last().exists()).toBeTruthy();
wrapper.find(`[data-test-subj="tag-list-edit-button"]`).last().simulate('click');
await act(async () => {
expect(wrapper.find(`[data-test-subj="case-tag-pepsi"]`).last().exists()).toBeFalsy();
expect(wrapper.find(`[data-test-subj="tag-pepsi"]`).last().exists()).toBeFalsy();
wrapper.find(`[data-test-subj="edit-tags-cancel"]`).last().simulate('click');
await waitFor(() => {
wrapper.update();
expect(wrapper.find(`[data-test-subj="case-tag-pepsi"]`).last().exists()).toBeTruthy();
expect(wrapper.find(`[data-test-subj="tag-pepsi"]`).last().exists()).toBeTruthy();
});
});
});

it('Renders disabled button', () => {
const props = { ...defaultProps, disabled: true };
const wrapper = mount(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import {
EuiHorizontalRule,
EuiFlexGroup,
EuiFlexItem,
EuiBadgeGroup,
EuiBadge,
EuiButton,
EuiButtonEmpty,
EuiButtonIcon,
Expand All @@ -25,6 +23,8 @@ import { schema } from './schema';
import { CommonUseField } from '../create';
import { useGetTags } from '../../containers/use_get_tags';

import { Tags } from './tags';

interface TagListProps {
disabled?: boolean;
isLoading: boolean;
Expand Down Expand Up @@ -99,15 +99,7 @@ export const TagList = React.memo(
<EuiHorizontalRule margin="xs" />
<MyFlexGroup gutterSize="xs" data-test-subj="case-tags">
{tags.length === 0 && !isEditTags && <p data-test-subj="no-tags">{i18n.NO_TAGS}</p>}
<EuiBadgeGroup>
{tags.length > 0 &&
!isEditTags &&
tags.map((tag) => (
<EuiBadge data-test-subj={`case-tag-${tag}`} color="hollow" key={tag}>
{tag}
</EuiBadge>
))}
</EuiBadgeGroup>
{!isEditTags && <Tags tags={tags} color="hollow" />}
{isEditTags && (
<EuiFlexGroup data-test-subj="edit-tags" direction="column">
<EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React, { memo } from 'react';
import { EuiBadgeGroup, EuiBadge, EuiBadgeGroupProps } from '@elastic/eui';

interface TagsProps {
tags: string[];
color?: string;
gutterSize?: EuiBadgeGroupProps['gutterSize'];
}

const TagsComponent: React.FC<TagsProps> = ({ tags, color = 'default', gutterSize }) => {
return (
<>
{tags.length > 0 && (
<EuiBadgeGroup gutterSize={gutterSize}>
{tags.map((tag) => (
<EuiBadge data-test-subj={`tag-${tag}`} color={color} key={tag}>
{tag}
</EuiBadge>
))}
</EuiBadgeGroup>
)}
</>
);
};

export const Tags = memo(TagsComponent);
Loading