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 Solution] Refactor Timeline flyout to take a full page #82033

Merged
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
4cd38e5
[WIP]
patrykkopycinski Oct 27, 2020
bd4cfbb
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Oct 29, 2020
fbe8c9d
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Oct 29, 2020
31de529
cleanup
patrykkopycinski Oct 29, 2020
c83b4e2
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 2, 2020
b19570e
add styling
patrykkopycinski Nov 3, 2020
fbf4279
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 3, 2020
c35c70a
fix styling
patrykkopycinski Nov 3, 2020
77064ea
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 3, 2020
6861f26
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 4, 2020
d18603d
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 5, 2020
4971123
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 5, 2020
ea26b9e
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 8, 2020
3fa7ac1
fix types
patrykkopycinski Nov 8, 2020
09f3d9f
update cypress
patrykkopycinski Nov 8, 2020
0f92910
update tests
patrykkopycinski Nov 8, 2020
3c86b0f
fix styling
patrykkopycinski Nov 9, 2020
31f2e17
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 10, 2020
d89716c
event details flyout
patrykkopycinski Nov 10, 2020
5616aa9
Merge branch 'master' into feat/timeline-modal-full-width
kibanamachine Nov 12, 2020
dff46ca
Merge branch 'master' into feat/timeline-modal-full-width
kibanamachine Nov 16, 2020
80d25d0
Merge branch 'master' into feat/timeline-modal-full-width
kibanamachine Nov 17, 2020
a6991ec
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 17, 2020
9ccb18e
Add PR comments
patrykkopycinski Nov 17, 2020
b13fbd3
fix types
patrykkopycinski Nov 17, 2020
78a2667
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 17, 2020
5da5332
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 17, 2020
bdb556b
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 18, 2020
e3c004f
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 18, 2020
aab0be1
Add expandedEvent to the timeline model
patrykkopycinski Nov 18, 2020
d98f168
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 18, 2020
daace89
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 18, 2020
02c8b59
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 18, 2020
db49354
add expandedEvent to the redux
patrykkopycinski Nov 18, 2020
a318464
fix lint
patrykkopycinski Nov 19, 2020
a1e74ff
Merge branch 'master' into feat/timeline-modal-full-width
kibanamachine Nov 19, 2020
56fc275
Merge branch 'master' into feat/timeline-modal-full-width
kibanamachine Nov 19, 2020
5f652dc
review with Patryk
XavierM Nov 19, 2020
49970c7
Merge branch 'master' into feat/timeline-modal-full-width
kibanamachine Nov 19, 2020
d05c047
Merge branch 'master' into feat/timeline-modal-full-width
kibanamachine Nov 20, 2020
920fd22
cleanup
patrykkopycinski Nov 20, 2020
5585f8d
Merge branch 'master' into feat/timeline-modal-full-width
kibanamachine Nov 21, 2020
28602b9
Merge branch 'master' of github.com:elastic/kibana into feat/timeline…
patrykkopycinski Nov 21, 2020
b1e173c
Merge branch 'feat/timeline-modal-full-width' of github.com:patrykkop…
patrykkopycinski Nov 21, 2020
1717186
Merge branch 'master' into feat/timeline-modal-full-width
kibanamachine Nov 22, 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 @@ -41,6 +41,7 @@ describe('toggle column in timeline', () => {
it('displays a checked Toggle field checkbox for `@timestamp`, a default timeline column', () => {
expandFirstTimelineEventDetails();
cy.get(TIMESTAMP_TOGGLE_FIELD).should('be.checked');
expandFirstTimelineEventDetails();
});

it('displays an Unchecked Toggle field checkbox for `_id`, because it is NOT a default timeline column', () => {
Expand All @@ -52,19 +53,22 @@ describe('toggle column in timeline', () => {
uncheckTimestampToggleField();

cy.get(TIMESTAMP_HEADER_FIELD).should('not.exist');
expandFirstTimelineEventDetails();
});

it('adds the _id field to the timeline when the user checks the field', () => {
expandFirstTimelineEventDetails();
checkIdToggleField();

cy.get(ID_HEADER_FIELD).should('exist');
expandFirstTimelineEventDetails();
});

it('adds the _id field to the timeline via drag and drop', () => {
expandFirstTimelineEventDetails();
dragAndDropIdToggleFieldToTimeline();

cy.get(ID_HEADER_FIELD).should('exist');
expandFirstTimelineEventDetails();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ export const openTimelineUsingToggle = () => {
cy.get(TIMELINE_TOGGLE_BUTTON).click();
};

export const openTimelineIfClosed = () => {
export const openTimelineIfClosed = () =>
cy.get(MAIN_PAGE).then(($page) => {
if ($page.find(TIMELINE_TOGGLE_BUTTON).length === 1) {
openTimelineUsingToggle();
}
});
};

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import {
EuiFlexItem,
EuiIcon,
EuiPanel,
EuiText,
EuiToolTip,
EuiIconTip,
} from '@elastic/eui';
import React from 'react';
import { Draggable } from 'react-beautiful-dnd';
Expand All @@ -27,7 +27,6 @@ import { DroppableWrapper } from '../drag_and_drop/droppable_wrapper';
import { getDroppableId, getDraggableFieldId, DRAG_TYPE_FIELD } from '../drag_and_drop/helpers';
import { DraggableFieldBadge } from '../draggables/field_badge';
import { FieldName } from '../../../timelines/components/fields_browser/field_name';
import { SelectableText } from '../selectable_text';
import { OverflowField } from '../tables/helpers';
import { defaultColumnHeaderType } from '../../../timelines/components/timeline/body/column_headers/default_headers';
import { DEFAULT_COLUMN_MIN_WIDTH } from '../../../timelines/components/timeline/body/constants';
Expand Down Expand Up @@ -90,6 +89,21 @@ export const getColumns = ({
</EuiToolTip>
),
},
{
field: 'description',
name: '',
render: (description: string | null | undefined, data: EventFieldsData) => (
<EuiIconTip
aria-label={i18n.DESCRIPTION}
type="iInCircle"
color="subdued"
content={`${description || ''} ${getExampleText(data.example)}`}
/>
),
sortable: true,
truncateText: true,
width: '30px',
},
{
field: 'field',
name: i18n.FIELD,
Expand Down Expand Up @@ -187,18 +201,6 @@ export const getColumns = ({
</EuiFlexGroup>
),
},
{
field: 'description',
name: i18n.DESCRIPTION,
render: (description: string | null | undefined, data: EventFieldsData) => (
<SelectableText>
<EuiText size="xs">{`${description || ''} ${getExampleText(data.example)}`}</EuiText>
</SelectableText>
),
sortable: true,
truncateText: true,
width: '50%',
},
{
field: 'valuesConcatenated',
name: i18n.BLANK,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,12 @@ import { useMountAppended } from '../../utils/use_mount_appended';
jest.mock('../link_to');
describe('EventDetails', () => {
const mount = useMountAppended();
const onEventToggled = jest.fn();
const defaultProps = {
browserFields: mockBrowserFields,
columnHeaders: defaultHeaders,
data: mockDetailItemData,
id: mockDetailItemDataId,
view: 'table-view' as View,
onEventToggled,
onUpdateColumns: jest.fn(),
onViewSelected: jest.fn(),
timelineId: 'test',
Expand Down Expand Up @@ -66,12 +64,5 @@ describe('EventDetails', () => {
wrapper.find('[data-test-subj="eventDetails"]').find('.euiTab-isSelected').first().text()
).toEqual('Table');
});

test('it invokes `onEventToggled` when the collapse button is clicked', () => {
wrapper.find('[data-test-subj="collapse"]').first().simulate('click');
wrapper.update();

expect(onEventToggled).toHaveBeenCalled();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import { EuiLink, EuiTabbedContent, EuiTabbedContentTab } from '@elastic/eui';
import React, { useMemo } from 'react';
import React, { useCallback, useMemo } from 'react';
import styled from 'styled-components';

import { BrowserFields } from '../../containers/source';
Expand All @@ -15,9 +15,12 @@ import { OnUpdateColumns } from '../../../timelines/components/timeline/events';
import { EventFieldsBrowser } from './event_fields_browser';
import { JsonView } from './json_view';
import * as i18n from './translations';
import { COLLAPSE, COLLAPSE_EVENT } from '../../../timelines/components/timeline/body/translations';

export type View = 'table-view' | 'json-view';
export type View = EventsViewType.tableView | EventsViewType.jsonView;
export enum EventsViewType {
tableView = 'table-view',
jsonView = 'json-view',
}

const CollapseLink = styled(EuiLink)`
margin: 20px 0;
Expand All @@ -30,10 +33,9 @@ interface Props {
columnHeaders: ColumnHeaderOptions[];
data: TimelineEventsDetailsItem[];
id: string;
view: View;
onEventToggled: () => void;
view: EventsViewType;
onUpdateColumns: OnUpdateColumns;
onViewSelected: (selected: View) => void;
onViewSelected: (selected: EventsViewType) => void;
timelineId: string;
toggleColumn: (column: ColumnHeaderOptions) => void;
}
Expand All @@ -51,16 +53,19 @@ export const EventDetails = React.memo<Props>(
data,
id,
view,
onEventToggled,
onUpdateColumns,
onViewSelected,
timelineId,
toggleColumn,
}) => {
const handleTabClick = useCallback((e) => onViewSelected(e.id as EventsViewType), [
onViewSelected,
]);

const tabs: EuiTabbedContentTab[] = useMemo(
() => [
{
id: 'table-view',
id: EventsViewType.tableView,
name: i18n.TABLE,
content: (
<EventFieldsBrowser
Expand All @@ -75,7 +80,7 @@ export const EventDetails = React.memo<Props>(
),
},
{
id: 'json-view',
id: EventsViewType.jsonView,
name: i18n.JSON_VIEW,
content: <JsonView data={data} />,
},
Expand All @@ -88,11 +93,8 @@ export const EventDetails = React.memo<Props>(
<EuiTabbedContent
tabs={tabs}
selectedTab={view === 'table-view' ? tabs[0] : tabs[1]}
onTabClick={(e) => onViewSelected(e.id as View)}
onTabClick={handleTabClick}
/>
<CollapseLink aria-label={COLLAPSE} data-test-subj="collapse" onClick={onEventToggled}>
{COLLAPSE_EVENT}
</CollapseLink>
</Details>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('EventFieldsBrowser', () => {
const mount = useMountAppended();

describe('column headers', () => {
['Field', 'Value', 'Description'].forEach((header) => {
['Field', 'Value'].forEach((header) => {
test(`it renders the ${header} column header`, () => {
const wrapper = mount(
<TestProviders>
Expand Down Expand Up @@ -229,8 +229,15 @@ describe('EventFieldsBrowser', () => {
</TestProviders>
);

expect(wrapper.find('.euiTableRow').find('.euiTableRowCell').at(3).text()).toContain(
'DescriptionDate/time when the event originated. For log events this is the date/time when the event was generated, and not when it was read. Required field for all events. Example: 2016-05-23T08:05:34.853Z'
expect(
wrapper
.find('.euiTableRow')
.find('.euiTableRowCell')
.at(1)
.find('EuiIconTip')
.prop('content')
).toContain(
'Date/time when the event originated. For log events this is the date/time when the event was generated, and not when it was read. Required field for all events. Example: 2016-05-23T08:05:34.853Z'
);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,38 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React, { useCallback, useState } from 'react';
import React, { useState } from 'react';

import { BrowserFields } from '../../containers/source';
import { TimelineEventsDetailsItem } from '../../../../common/search_strategy/timeline';
import { ColumnHeaderOptions } from '../../../timelines/store/timeline/model';
import { OnUpdateColumns } from '../../../timelines/components/timeline/events';

import { EventDetails, View } from './event_details';
import { EventDetails, EventsViewType, View } from './event_details';

interface Props {
browserFields: BrowserFields;
columnHeaders: ColumnHeaderOptions[];
data: TimelineEventsDetailsItem[];
id: string;
onEventToggled: () => void;
onUpdateColumns: OnUpdateColumns;
timelineId: string;
toggleColumn: (column: ColumnHeaderOptions) => void;
}

export const StatefulEventDetails = React.memo<Props>(
({
browserFields,
columnHeaders,
data,
id,
onEventToggled,
onUpdateColumns,
timelineId,
toggleColumn,
}) => {
const [view, setView] = useState<View>('table-view');
({ browserFields, columnHeaders, data, id, onUpdateColumns, timelineId, toggleColumn }) => {
// TODO: Move to the store
const [view, setView] = useState<View>(EventsViewType.tableView);

const handleSetView = useCallback((newView) => setView(newView), []);
return (
<EventDetails
browserFields={browserFields}
columnHeaders={columnHeaders}
data={data}
id={id}
onEventToggled={onEventToggled}
onUpdateColumns={onUpdateColumns}
onViewSelected={handleSetView}
onViewSelected={setView}
timelineId={timelineId}
toggleColumn={toggleColumn}
view={view}
Expand Down
Loading