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] flyout UI adjustment #108192

Merged
merged 13 commits into from
Aug 16, 2021
4 changes: 4 additions & 0 deletions x-pack/plugins/security_solution/cypress/screens/timeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ export const ID_FIELD = '[data-test-subj="timeline"] [data-test-subj="field-name

export const ID_TOGGLE_FIELD = '[data-test-subj="toggle-field-_id"]';

export const ID_HOVER_ACTION_OVERFLOW_BTN = '[data-test-subj="more-actions-_id"]';

export const LOCKED_ICON = '[data-test-subj="timeline-date-picker-lock-button"]';

export const UNLOCKED_ICON = '[data-test-subj="timeline-date-picker-unlock-button"]';
Expand Down Expand Up @@ -266,3 +268,5 @@ export const TIMELINE_TAB_CONTENT_PINNED = '[data-test-subj="timeline-tab-conten

export const TIMELINE_TAB_CONTENT_GRAPHS_NOTES =
'[data-test-subj="timeline-tab-content-graph-notes"]';

export const TIMESTAMP_HOVER_ACTION_OVERFLOW_BTN = '[data-test-subj="more-actions-@timestamp"]';
17 changes: 17 additions & 0 deletions x-pack/plugins/security_solution/cypress/tasks/timeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
ID_FIELD,
ID_HEADER_FIELD,
ID_TOGGLE_FIELD,
ID_HOVER_ACTION_OVERFLOW_BTN,
NOTES_TAB_BUTTON,
NOTES_TEXT_AREA,
OPEN_TIMELINE_ICON,
Expand Down Expand Up @@ -64,6 +65,7 @@ import {
TIMELINE_CREATE_TEMPLATE_FROM_TIMELINE_BTN,
TIMELINE_COLLAPSED_ITEMS_BTN,
TIMELINE_TAB_CONTENT_EQL,
TIMESTAMP_HOVER_ACTION_OVERFLOW_BTN,
} from '../screens/timeline';
import { REFRESH_BUTTON, TIMELINE } from '../screens/timelines';

Expand Down Expand Up @@ -189,7 +191,14 @@ export const attachTimelineToExistingCase = () => {
cy.get(ATTACH_TIMELINE_TO_EXISTING_CASE_ICON).click({ force: true });
};

const clickIdHoverActionOverflowButton = () => {
cy.get(ID_HOVER_ACTION_OVERFLOW_BTN).should('exist');

cy.get(ID_HOVER_ACTION_OVERFLOW_BTN).click({ force: true });
};

export const clickIdToggleField = () => {
clickIdHoverActionOverflowButton();
cy.get(ID_HEADER_FIELD).should('not.exist');

cy.get(ID_TOGGLE_FIELD).click({
Expand Down Expand Up @@ -294,7 +303,15 @@ export const unpinFirstEvent = () => {
cy.get(PIN_EVENT).first().click({ force: true });
};

const clickTimestampHoverActionOverflowButton = () => {
cy.get(TIMESTAMP_HOVER_ACTION_OVERFLOW_BTN).should('exist');

cy.get(TIMESTAMP_HOVER_ACTION_OVERFLOW_BTN).click({ force: true });
};

export const clickTimestampToggleField = () => {
clickTimestampHoverActionOverflowButton();

cy.get(TIMESTAMP_TOGGLE_FIELD).should('exist');

cy.get(TIMESTAMP_TOGGLE_FIELD).click({ force: true });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { TestProviders } from '../../mock';
import { useMountAppended } from '../../utils/use_mount_appended';
import { mockBrowserFields } from '../../containers/source/mock';
import { EventFieldsData } from './types';
import { get } from 'lodash/fp';

jest.mock('../../lib/kibana');
interface Column {
Expand Down Expand Up @@ -78,13 +79,13 @@ describe('getColumns', () => {
});
});

describe('add to timeline', () => {
test('it renders an add to timeline button', () => {
describe('overflow button', () => {
test('it renders an overflow button', () => {
const wrapper = mount(
<TestProviders>{actionsColumn.render(testValue, testData)}</TestProviders>
) as ReactWrapper;

expect(wrapper.find('[data-test-subj="hover-actions-add-timeline"]').exists()).toBeTruthy();
expect(wrapper.find('[data-test-subj="more-actions-agent.id"]').exists()).toBeTruthy();
});
});

Expand All @@ -95,8 +96,32 @@ describe('getColumns', () => {
) as ReactWrapper;

expect(
wrapper.find('[data-test-subj="hover-actions-toggle-column"]').exists()
).toBeTruthy();
get(['items', 0, 'key'], wrapper.find('[data-test-subj="more-actions-agent.id"]').props())
).toEqual('hover-actions-toggle-column');
});
});

describe('add to timeline', () => {
test('it renders an add to timeline button', () => {
const wrapper = mount(
<TestProviders>{actionsColumn.render(testValue, testData)}</TestProviders>
) as ReactWrapper;

expect(
get(['items', 1, 'key'], wrapper.find('[data-test-subj="more-actions-agent.id"]').props())
).toEqual('hover-actions-add-timeline');
});
});

describe('topN', () => {
test('it renders a show topN button', () => {
const wrapper = mount(
<TestProviders>{actionsColumn.render(testValue, testData)}</TestProviders>
) as ReactWrapper;

expect(
get(['items', 2, 'key'], wrapper.find('[data-test-subj="more-actions-agent.id"]').props())
).toEqual('hover-actions-show-top-n');
});
});

Expand All @@ -106,7 +131,9 @@ describe('getColumns', () => {
<TestProviders>{actionsColumn.render(testValue, testData)}</TestProviders>
) as ReactWrapper;

expect(wrapper.find('[data-test-subj="hover-actions-copy-button"]').exists()).toBeTruthy();
expect(
get(['items', 3, 'key'], wrapper.find('[data-test-subj="more-actions-agent.id"]').props())
).toEqual('hover-actions-copy-button');
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { EventFieldsBrowser } from './event_fields_browser';
import { mockBrowserFields } from '../../containers/source/mock';
import { useMountAppended } from '../../utils/use_mount_appended';
import { TimelineTabs } from '../../../../common/types/timeline';
import { get } from 'lodash/fp';

jest.mock('../../lib/kibana');

Expand Down Expand Up @@ -116,7 +117,7 @@ describe('EventFieldsBrowser', () => {
expect(wrapper.find('[data-test-subj="hover-actions-filter-out"]').exists()).toBeTruthy();
});

test('it renders an add to timeline button', () => {
test('it renders an overflow button', () => {
const wrapper = mount(
<TestProviders>
<EventFieldsBrowser
Expand All @@ -129,7 +130,7 @@ describe('EventFieldsBrowser', () => {
</TestProviders>
);

expect(wrapper.find('[data-test-subj="hover-actions-add-timeline"]').exists()).toBeTruthy();
expect(wrapper.find('[data-test-subj="more-actions-@timestamp"]').exists()).toBeTruthy();
});

test('it renders a column toggle button', () => {
Expand All @@ -146,8 +147,26 @@ describe('EventFieldsBrowser', () => {
);

expect(
wrapper.find('[data-test-subj="hover-actions-toggle-column"]').first().exists()
).toBeTruthy();
get(['items', 0, 'key'], wrapper.find('[data-test-subj="more-actions-@timestamp"]').props())
).toEqual('hover-actions-toggle-column');
});

test('it renders an add to timeline button', () => {
const wrapper = mount(
<TestProviders>
<EventFieldsBrowser
browserFields={mockBrowserFields}
data={mockDetailItemData}
eventId={eventId}
timelineId="test"
timelineTabType={TimelineTabs.query}
/>
</TestProviders>
);

expect(
get(['items', 1, 'key'], wrapper.find('[data-test-subj="more-actions-@timestamp"]').props())
).toEqual('hover-actions-add-timeline');
});

test('it renders a copy button', () => {
Expand All @@ -163,7 +182,9 @@ describe('EventFieldsBrowser', () => {
</TestProviders>
);

expect(wrapper.find('[data-test-subj="hover-actions-copy-button"]').exists()).toBeTruthy();
expect(
get(['items', 2, 'key'], wrapper.find('[data-test-subj="more-actions-@timestamp"]').props())
).toEqual('hover-actions-copy-button');
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,13 @@ const StyledEuiInMemoryTable = styled(EuiInMemoryTable as any)`
font-size: ${({ theme }) => theme.eui.euiFontSizeXS};
font-family: ${({ theme }) => theme.eui.euiCodeFontFamily};

.eventFieldsTable__hoverActionButtons {
&:focus-within {
.timelines__hoverActionButton,
.securitySolution__hoverActionButton {
opacity: 1;
}
.hoverActions-active {
.timelines__hoverActionButton,
.securitySolution__hoverActionButton {
opacity: 1;
}
}

&:hover {
.timelines__hoverActionButton,
.securitySolution__hoverActionButton {
Expand All @@ -110,9 +109,6 @@ const StyledEuiInMemoryTable = styled(EuiInMemoryTable as any)`
opacity: 0;
} */
opacity: 0;
&:focus {
opacity: 1;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ export const getSummaryColumns = (
name: '',
},
{
className: 'flyoutOverviewDescription',
field: 'description',
truncateText: false,
render: DescriptionComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@ export const StyledEuiInMemoryTable = styled(EuiInMemoryTable as any)`
.euiTableHeaderCell .euiTableCellContent {
padding: 0;
}

.flyoutOverviewDescription {
.hoverActions-active {
.timelines__hoverActionButton,
.securitySolution__hoverActionButton {
opacity: 1;
}
}

&:hover {
.timelines__hoverActionButton,
.securitySolution__hoverActionButton {
opacity: 1;
}
}
}
`;

export const SummaryViewComponent: React.FC<{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,16 @@ export const ActionCell: React.FC<Props> = React.memo(
});
}, []);

const closeTopN = useCallback(() => {
setShowTopN(false);
}, []);

return (
<HoverActions
closeTopN={closeTopN}
dataType={data.type}
dataProvider={actionCellConfig?.dataProvider}
enableOverflowButton={true}
field={data.field}
goGetTimelineId={setGoGetTimelineId}
isObjectArray={data.isObjectArray}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import React, { useMemo } from 'react';
import { EuiButtonEmpty, EuiButtonIcon, EuiPopover, EuiToolTip } from '@elastic/eui';
import { EuiButtonEmpty, EuiButtonIcon, EuiContextMenuItem, EuiToolTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { StatefulTopN } from '../../top_n';
import { TimelineId } from '../../../../../common/types/timeline';
Expand All @@ -24,7 +24,7 @@ const SHOW_TOP = (fieldName: string) =>

interface Props {
/** `Component` is only used with `EuiDataGrid`; the grid keeps a reference to `Component` for show / hide functionality */
Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon;
Component?: typeof EuiButtonEmpty | typeof EuiButtonIcon | typeof EuiContextMenuItem;
field: string;
onClick: () => void;
onFilterAdded?: () => void;
Expand Down Expand Up @@ -64,6 +64,7 @@ export const ShowTopNButton: React.FC<Props> = React.memo(
<Component
aria-label={SHOW_TOP(field)}
data-test-subj="show-top-field"
icon="visBarVertical"
iconType="visBarVertical"
onClick={onClick}
title={SHOW_TOP(field)}
Expand All @@ -84,17 +85,15 @@ export const ShowTopNButton: React.FC<Props> = React.memo(
);

return showTopN ? (
<EuiPopover button={button} isOpen={showTopN} closePopover={onClick}>
<StatefulTopN
browserFields={browserFields}
field={field}
indexPattern={indexPattern}
onFilterAdded={onFilterAdded}
timelineId={timelineId ?? undefined}
toggleTopN={onClick}
value={value}
/>
</EuiPopover>
<StatefulTopN
browserFields={browserFields}
field={field}
indexPattern={indexPattern}
onFilterAdded={onFilterAdded}
timelineId={timelineId ?? undefined}
toggleTopN={onClick}
value={value}
/>
) : showTooltip ? (
<EuiToolTip
content={
Expand Down
Loading