mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Security Solution] add expandable flyout investigation section (#153807)
This commit is contained in:
parent
b5deb19d4f
commit
ee72588faa
13 changed files with 282 additions and 229 deletions
|
@ -92,8 +92,6 @@ describe.skip('Alert details expandable flyout left panel', { testIsolation: fal
|
|||
.and('have.text', 'Session view');
|
||||
|
||||
openGraphAnalyzer();
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_VISUALIZE_TAB_GRAPH_ANALYZER_CONTENT)
|
||||
.should('be.visible')
|
||||
.and('have.text', 'Analyzer graph');
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_VISUALIZE_TAB_GRAPH_ANALYZER_CONTENT).should('be.visible');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,9 +12,9 @@ import {
|
|||
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK,
|
||||
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_CONTENT,
|
||||
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_EVENT_TYPE_ROW,
|
||||
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS,
|
||||
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON,
|
||||
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_TITLE,
|
||||
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_SECTION_HEADER,
|
||||
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_SECTION_CONTENT,
|
||||
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_DESCRIPTION_SECTION_HEADER,
|
||||
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_DESCRIPTION_SECTION_CONTENT,
|
||||
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_REASON_TITLE,
|
||||
|
@ -27,6 +27,7 @@ import {
|
|||
expandFirstAlertExpandableFlyout,
|
||||
openOverviewTab,
|
||||
toggleOverviewTabDescriptionSection,
|
||||
toggleOverviewTabInvestigationSection,
|
||||
} from '../../../tasks/document_expandable_flyout';
|
||||
import { cleanKibana } from '../../../tasks/common';
|
||||
import { login, visit } from '../../../tasks/login';
|
||||
|
@ -89,11 +90,6 @@ describe.skip(
|
|||
.and('contain.text', rule.name);
|
||||
});
|
||||
|
||||
it('should display mitre attack', () => {
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_MITRE_ATTACK_TITLE).should('be.visible');
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_MITRE_ATTACK_DETAILS).should('be.visible');
|
||||
});
|
||||
|
||||
it('should display mitre attack', () => {
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_MITRE_ATTACK_TITLE)
|
||||
.should('be.visible')
|
||||
|
@ -112,45 +108,40 @@ describe.skip(
|
|||
describe('investigation section', () => {
|
||||
before(() => {
|
||||
toggleOverviewTabDescriptionSection();
|
||||
toggleOverviewTabInvestigationSection();
|
||||
});
|
||||
|
||||
it('should display description section header and content', () => {
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_SECTION_HEADER)
|
||||
.should('be.visible')
|
||||
.and('have.text', 'Investigation');
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_SECTION_CONTENT).should(
|
||||
'be.visible'
|
||||
);
|
||||
});
|
||||
|
||||
it('should display highlighted fields', () => {
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS)
|
||||
.scrollIntoView()
|
||||
.within(() => {
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON)
|
||||
.should('be.visible')
|
||||
.click();
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_TITLE)
|
||||
.should('be.visible')
|
||||
.and('have.text', 'Highlighted fields');
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_DETAILS).should(
|
||||
'be.visible'
|
||||
);
|
||||
|
||||
// close highlighted fields to reset the view for next test
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON)
|
||||
.should('be.visible')
|
||||
.click();
|
||||
});
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_TITLE)
|
||||
.should('be.visible')
|
||||
.and('have.text', 'Highlighted fields');
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_DETAILS).should(
|
||||
'be.visible'
|
||||
);
|
||||
});
|
||||
|
||||
it('should navigate to table tab when clicking on highlighted fields view button', () => {
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS)
|
||||
.scrollIntoView()
|
||||
.within(() => {
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON)
|
||||
.should('be.visible')
|
||||
.click();
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK)
|
||||
.should('be.visible')
|
||||
.click();
|
||||
});
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK)
|
||||
.should('be.visible')
|
||||
.click();
|
||||
|
||||
// the table component is rendered within a dom element with overflow, so Cypress isn't finding it
|
||||
// this next line is a hack that scrolls to a specific element in the table
|
||||
// (in the middle of it vertically) to ensure Cypress finds it
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_EVENT_TYPE_ROW).scrollIntoView();
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_CONTENT).should('be.visible');
|
||||
|
||||
// go back to Overview tab to reset view for next test
|
||||
openOverviewTab();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -49,8 +49,10 @@ import {
|
|||
HIGHLIGHTED_FIELDS_DETAILS_TEST_ID,
|
||||
HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK,
|
||||
HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON_TEST_ID,
|
||||
HIGHLIGHTED_FIELDS_HEADER_TITLE_TEST_ID,
|
||||
HIGHLIGHTED_FIELDS_TEST_ID,
|
||||
HIGHLIGHTED_FIELDS_TITLE_TEST_ID,
|
||||
INVESTIGATION_SECTION_CONTENT_TEST_ID,
|
||||
INVESTIGATION_SECTION_HEADER_TEST_ID,
|
||||
MITRE_ATTACK_DETAILS_TEST_ID,
|
||||
MITRE_ATTACK_TITLE_TEST_ID,
|
||||
REASON_DETAILS_TEST_ID,
|
||||
|
@ -154,8 +156,13 @@ export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS = getDataTe
|
|||
);
|
||||
export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON =
|
||||
getDataTestSubjectSelector(HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON_TEST_ID);
|
||||
export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_SECTION_HEADER =
|
||||
getDataTestSubjectSelector(INVESTIGATION_SECTION_HEADER_TEST_ID);
|
||||
export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_SECTION_CONTENT =
|
||||
getDataTestSubjectSelector(INVESTIGATION_SECTION_CONTENT_TEST_ID);
|
||||
|
||||
export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_HEADER_TITLE =
|
||||
getDataTestSubjectSelector(HIGHLIGHTED_FIELDS_HEADER_TITLE_TEST_ID);
|
||||
getDataTestSubjectSelector(HIGHLIGHTED_FIELDS_TITLE_TEST_ID);
|
||||
export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_DETAILS =
|
||||
getDataTestSubjectSelector(HIGHLIGHTED_FIELDS_DETAILS_TEST_ID);
|
||||
export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK =
|
||||
|
|
|
@ -14,6 +14,7 @@ import {
|
|||
DOCUMENT_DETAILS_FLYOUT_INVESTIGATIONS_TAB,
|
||||
DOCUMENT_DETAILS_FLYOUT_JSON_TAB,
|
||||
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB,
|
||||
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_SECTION_HEADER,
|
||||
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_DESCRIPTION_SECTION_HEADER,
|
||||
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB,
|
||||
DOCUMENT_DETAILS_FLYOUT_TABLE_TAB_CLEAR_FILTER,
|
||||
|
@ -59,7 +60,17 @@ export const scrollWithinDocumentDetailsExpandableFlyoutRightSection = (x: numbe
|
|||
* Open the Overview tab in the document details expandable flyout right section
|
||||
*/
|
||||
export const openOverviewTab = () =>
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB).should('be.visible').click();
|
||||
cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB).scrollIntoView().should('be.visible').click();
|
||||
|
||||
/**
|
||||
* Toggle the Overview tab description section in the document details expandable flyout right section
|
||||
*/
|
||||
export const toggleOverviewTabInvestigationSection = () =>
|
||||
cy
|
||||
.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_SECTION_HEADER)
|
||||
.scrollIntoView()
|
||||
.should('be.visible')
|
||||
.click();
|
||||
|
||||
/**
|
||||
* Toggle the Overview tab description section in the document details expandable flyout right section
|
||||
|
@ -67,6 +78,7 @@ export const openOverviewTab = () =>
|
|||
export const toggleOverviewTabDescriptionSection = () =>
|
||||
cy
|
||||
.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_DESCRIPTION_SECTION_HEADER)
|
||||
.scrollIntoView()
|
||||
.should('be.visible')
|
||||
.click();
|
||||
|
||||
|
|
|
@ -19,27 +19,7 @@ export default {
|
|||
// TODO ideally we would want to have some data here, but we need to spent some time getting all the foundation items for storybook
|
||||
// (ReduxStoreProvider, CellActionsProvider...) similarly to how it was done for the TestProvidersComponent
|
||||
// see ticket https://github.com/elastic/security-team/issues/6223
|
||||
export const Expanded: Story<void> = () => {
|
||||
const flyoutContextValue = {
|
||||
openRightPanel: () => window.alert('openRightPanel called'),
|
||||
} as unknown as ExpandableFlyoutContext;
|
||||
const panelContextValue = {
|
||||
eventId: 'eventId',
|
||||
indexName: 'indexName',
|
||||
dataFormattedForFieldBrowser: [],
|
||||
browserFields: {},
|
||||
} as unknown as RightPanelContext;
|
||||
|
||||
return (
|
||||
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
|
||||
<RightPanelContext.Provider value={panelContextValue}>
|
||||
<HighlightedFields expanded={true} />
|
||||
</RightPanelContext.Provider>
|
||||
</ExpandableFlyoutContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const Collapsed: Story<void> = () => {
|
||||
export const Default: Story<void> = () => {
|
||||
const flyoutContextValue = {
|
||||
openRightPanel: () => window.alert('openRightPanel called'),
|
||||
} as unknown as ExpandableFlyoutContext;
|
||||
|
|
|
@ -8,130 +8,41 @@
|
|||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { RightPanelContext } from '../context';
|
||||
import {
|
||||
HIGHLIGHTED_FIELDS_DETAILS_TEST_ID,
|
||||
HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK,
|
||||
HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON_TEST_ID,
|
||||
HIGHLIGHTED_FIELDS_HEADER_TITLE_TEST_ID,
|
||||
} from './test_ids';
|
||||
import { HIGHLIGHTED_FIELDS_DETAILS_TEST_ID, HIGHLIGHTED_FIELDS_TITLE_TEST_ID } from './test_ids';
|
||||
import { ExpandableFlyoutContext } from '@kbn/expandable-flyout/src/context';
|
||||
import { HighlightedFields } from './highlighted_fields';
|
||||
import { RightPanelKey, RightPanelTableTabPath } from '..';
|
||||
import { getMockTheme } from '../../../common/lib/kibana/kibana_react.mock';
|
||||
import { ThemeProvider } from 'styled-components';
|
||||
|
||||
const mockTheme = getMockTheme({
|
||||
eui: {
|
||||
euiSizeL: '10px',
|
||||
},
|
||||
});
|
||||
|
||||
describe('<HighlightedFields />', () => {
|
||||
it('should render the component collapsed', () => {
|
||||
const flyoutContextValue = {
|
||||
openRightPanel: jest.fn(),
|
||||
} as unknown as ExpandableFlyoutContext;
|
||||
const panelContextValue = {
|
||||
eventId: 'eventId',
|
||||
indexName: 'indexName',
|
||||
dataFormattedForFieldBrowser: [],
|
||||
browserFields: {},
|
||||
} as unknown as RightPanelContext;
|
||||
|
||||
const { getByTestId } = render(
|
||||
<ThemeProvider theme={mockTheme}>
|
||||
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
|
||||
<RightPanelContext.Provider value={panelContextValue}>
|
||||
<HighlightedFields />
|
||||
</RightPanelContext.Provider>
|
||||
</ExpandableFlyoutContext.Provider>
|
||||
</ThemeProvider>
|
||||
);
|
||||
|
||||
expect(getByTestId(HIGHLIGHTED_FIELDS_HEADER_TITLE_TEST_ID)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render the component expanded', () => {
|
||||
const flyoutContextValue = {
|
||||
openRightPanel: jest.fn(),
|
||||
} as unknown as ExpandableFlyoutContext;
|
||||
const panelContextValue = {
|
||||
eventId: 'eventId',
|
||||
indexName: 'indexName',
|
||||
dataFormattedForFieldBrowser: [],
|
||||
browserFields: {},
|
||||
} as unknown as RightPanelContext;
|
||||
|
||||
const { getByTestId } = render(
|
||||
<ThemeProvider theme={mockTheme}>
|
||||
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
|
||||
<RightPanelContext.Provider value={panelContextValue}>
|
||||
<HighlightedFields expanded={true} />
|
||||
</RightPanelContext.Provider>
|
||||
</ExpandableFlyoutContext.Provider>
|
||||
</ThemeProvider>
|
||||
);
|
||||
|
||||
expect(getByTestId(HIGHLIGHTED_FIELDS_HEADER_TITLE_TEST_ID)).toBeInTheDocument();
|
||||
expect(getByTestId(HIGHLIGHTED_FIELDS_DETAILS_TEST_ID)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should expand details when clicking on header', () => {
|
||||
const flyoutContextValue = {
|
||||
openRightPanel: jest.fn(),
|
||||
} as unknown as ExpandableFlyoutContext;
|
||||
const panelContextValue = {
|
||||
eventId: 'eventId',
|
||||
indexName: 'indexName',
|
||||
dataFormattedForFieldBrowser: [],
|
||||
browserFields: {},
|
||||
} as unknown as RightPanelContext;
|
||||
|
||||
const { getByTestId } = render(
|
||||
<ThemeProvider theme={mockTheme}>
|
||||
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
|
||||
<RightPanelContext.Provider value={panelContextValue}>
|
||||
<HighlightedFields />
|
||||
</RightPanelContext.Provider>
|
||||
</ExpandableFlyoutContext.Provider>
|
||||
</ThemeProvider>
|
||||
);
|
||||
|
||||
getByTestId(HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON_TEST_ID).click();
|
||||
expect(getByTestId(HIGHLIGHTED_FIELDS_DETAILS_TEST_ID)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should navigate to table tab when clicking on the link button', () => {
|
||||
const flyoutContextValue = {
|
||||
openRightPanel: jest.fn(),
|
||||
} as unknown as ExpandableFlyoutContext;
|
||||
const panelContextValue = {
|
||||
eventId: 'eventId',
|
||||
indexName: 'indexName',
|
||||
dataFormattedForFieldBrowser: [],
|
||||
browserFields: {},
|
||||
} as unknown as RightPanelContext;
|
||||
|
||||
const { getByTestId } = render(
|
||||
<ThemeProvider theme={mockTheme}>
|
||||
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
|
||||
<RightPanelContext.Provider value={panelContextValue}>
|
||||
<HighlightedFields />
|
||||
</RightPanelContext.Provider>
|
||||
</ExpandableFlyoutContext.Provider>
|
||||
</ThemeProvider>
|
||||
);
|
||||
|
||||
getByTestId(HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON_TEST_ID).click();
|
||||
getByTestId(HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK).click();
|
||||
expect(flyoutContextValue.openRightPanel).toHaveBeenCalledWith({
|
||||
id: RightPanelKey,
|
||||
path: RightPanelTableTabPath,
|
||||
params: {
|
||||
id: panelContextValue.eventId,
|
||||
indexName: panelContextValue.indexName,
|
||||
it('should render the component', () => {
|
||||
const mockTheme = getMockTheme({
|
||||
eui: {
|
||||
euiSizeL: '10px',
|
||||
},
|
||||
});
|
||||
const flyoutContextValue = {
|
||||
openRightPanel: jest.fn(),
|
||||
} as unknown as ExpandableFlyoutContext;
|
||||
const panelContextValue = {
|
||||
eventId: 'eventId',
|
||||
indexName: 'indexName',
|
||||
dataFormattedForFieldBrowser: [],
|
||||
browserFields: {},
|
||||
} as unknown as RightPanelContext;
|
||||
|
||||
const { getByTestId } = render(
|
||||
<ThemeProvider theme={mockTheme}>
|
||||
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
|
||||
<RightPanelContext.Provider value={panelContextValue}>
|
||||
<HighlightedFields />
|
||||
</RightPanelContext.Provider>
|
||||
</ExpandableFlyoutContext.Provider>
|
||||
</ThemeProvider>
|
||||
);
|
||||
|
||||
expect(getByTestId(HIGHLIGHTED_FIELDS_TITLE_TEST_ID)).toBeInTheDocument();
|
||||
expect(getByTestId(HIGHLIGHTED_FIELDS_DETAILS_TEST_ID)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render empty component if dataFormattedForFieldBrowser is null', () => {
|
||||
|
|
|
@ -5,27 +5,17 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiFlexGroup } from '@elastic/eui';
|
||||
import type { VFC } from 'react';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import type { FC } from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
import { useExpandableFlyoutContext } from '@kbn/expandable-flyout';
|
||||
import { HIGHLIGHTED_FIELDS_TEST_ID } from './test_ids';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle } from '@elastic/eui';
|
||||
import { HIGHLIGHTED_FIELDS_DETAILS_TEST_ID, HIGHLIGHTED_FIELDS_TITLE_TEST_ID } from './test_ids';
|
||||
import { AlertSummaryView } from '../../../common/components/event_details/alert_summary_view';
|
||||
import { HIGHLIGHTED_FIELDS_TITLE } from './translations';
|
||||
import { HeaderSection } from '../../../common/components/header_section';
|
||||
import { useRightPanelContext } from '../context';
|
||||
import { RightPanelKey, RightPanelTableTabPath } from '..';
|
||||
|
||||
export interface HighlightedFieldsProps {
|
||||
/**
|
||||
* Boolean to allow the component to be expanded or collapsed on first render
|
||||
*/
|
||||
expanded?: boolean;
|
||||
}
|
||||
|
||||
export const HighlightedFields: VFC<HighlightedFieldsProps> = ({ expanded = false }) => {
|
||||
const [isPanelExpanded, setIsPanelExpanded] = useState(expanded);
|
||||
|
||||
export const HighlightedFields: FC = () => {
|
||||
const { openRightPanel } = useExpandableFlyoutContext();
|
||||
const { eventId, indexName, dataFormattedForFieldBrowser, browserFields } =
|
||||
useRightPanelContext();
|
||||
|
@ -46,28 +36,26 @@ export const HighlightedFields: VFC<HighlightedFieldsProps> = ({ expanded = fals
|
|||
}
|
||||
|
||||
return (
|
||||
<EuiFlexGroup gutterSize="none" direction="column" data-test-subj={HIGHLIGHTED_FIELDS_TEST_ID}>
|
||||
<HeaderSection
|
||||
alignHeader="center"
|
||||
hideSubtitle
|
||||
outerDirection="row"
|
||||
title={HIGHLIGHTED_FIELDS_TITLE}
|
||||
titleSize="xs"
|
||||
toggleQuery={setIsPanelExpanded}
|
||||
toggleStatus={isPanelExpanded}
|
||||
/>
|
||||
{isPanelExpanded && (
|
||||
<AlertSummaryView
|
||||
data={dataFormattedForFieldBrowser}
|
||||
eventId={eventId}
|
||||
browserFields={browserFields}
|
||||
isDraggable={false}
|
||||
scopeId={'global'}
|
||||
title={HIGHLIGHTED_FIELDS_TITLE}
|
||||
isReadOnly={false} // TODO: set properly
|
||||
goToTable={goToTableTab}
|
||||
/>
|
||||
)}
|
||||
<EuiFlexGroup direction="column" gutterSize="s">
|
||||
<EuiFlexItem data-test-subj={HIGHLIGHTED_FIELDS_TITLE_TEST_ID}>
|
||||
<EuiTitle size="xxs">
|
||||
<h5>{HIGHLIGHTED_FIELDS_TITLE}</h5>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem data-test-subj={HIGHLIGHTED_FIELDS_DETAILS_TEST_ID}>
|
||||
<EuiPanel hasBorder hasShadow={false}>
|
||||
<AlertSummaryView // TODO consider using x-pack/plugins/security_solution/public/common/components/event_details/summary_view.tsx instead if the link to the table have to be removed
|
||||
data={dataFormattedForFieldBrowser}
|
||||
eventId={eventId}
|
||||
browserFields={browserFields}
|
||||
isDraggable={false}
|
||||
scopeId={'global'}
|
||||
title={''}
|
||||
isReadOnly={false} // TODO: set properly
|
||||
goToTable={goToTableTab}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import type { Story } from '@storybook/react';
|
||||
import { ExpandableFlyoutContext } from '@kbn/expandable-flyout/src/context';
|
||||
import { InvestigationSection } from './investigation_section';
|
||||
import { mockDataFormattedForFieldBrowser, mockSearchHit } from '../mocks/mock_context';
|
||||
import { RightPanelContext } from '../context';
|
||||
|
||||
const flyoutContextValue = {} as unknown as ExpandableFlyoutContext;
|
||||
const panelContextValue = {
|
||||
dataFormattedForFieldBrowser: mockDataFormattedForFieldBrowser,
|
||||
searchHit: mockSearchHit,
|
||||
} as unknown as RightPanelContext;
|
||||
|
||||
export default {
|
||||
component: InvestigationSection,
|
||||
title: 'Flyout/InvestigationSection',
|
||||
};
|
||||
|
||||
export const Expand: Story<void> = () => {
|
||||
return (
|
||||
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
|
||||
<RightPanelContext.Provider value={panelContextValue}>
|
||||
<InvestigationSection />
|
||||
</RightPanelContext.Provider>
|
||||
</ExpandableFlyoutContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const Collapse: Story<void> = () => {
|
||||
return (
|
||||
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
|
||||
<RightPanelContext.Provider value={panelContextValue}>
|
||||
<InvestigationSection expanded={false} />
|
||||
</RightPanelContext.Provider>
|
||||
</ExpandableFlyoutContext.Provider>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import {
|
||||
INVESTIGATION_SECTION_CONTENT_TEST_ID,
|
||||
INVESTIGATION_SECTION_HEADER_TEST_ID,
|
||||
} from './test_ids';
|
||||
import { RightPanelContext } from '../context';
|
||||
import { InvestigationSection } from './investigation_section';
|
||||
import { ExpandableFlyoutContext } from '@kbn/expandable-flyout/src/context';
|
||||
|
||||
const flyoutContextValue = {} as unknown as ExpandableFlyoutContext;
|
||||
const panelContextValue = {} as unknown as RightPanelContext;
|
||||
|
||||
describe('<InvestigationSection />', () => {
|
||||
it('should render the component collapsed', () => {
|
||||
const { getByTestId } = render(
|
||||
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
|
||||
<RightPanelContext.Provider value={panelContextValue}>
|
||||
<InvestigationSection />
|
||||
</RightPanelContext.Provider>
|
||||
</ExpandableFlyoutContext.Provider>
|
||||
);
|
||||
|
||||
expect(getByTestId(INVESTIGATION_SECTION_HEADER_TEST_ID)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render the component expanded', () => {
|
||||
const { getByTestId } = render(
|
||||
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
|
||||
<RightPanelContext.Provider value={panelContextValue}>
|
||||
<InvestigationSection expanded={true} />
|
||||
</RightPanelContext.Provider>
|
||||
</ExpandableFlyoutContext.Provider>
|
||||
);
|
||||
|
||||
expect(getByTestId(INVESTIGATION_SECTION_HEADER_TEST_ID)).toBeInTheDocument();
|
||||
expect(getByTestId(INVESTIGATION_SECTION_CONTENT_TEST_ID)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should expand the component when clicking on the arrow on header', () => {
|
||||
const { getByTestId } = render(
|
||||
<ExpandableFlyoutContext.Provider value={flyoutContextValue}>
|
||||
<RightPanelContext.Provider value={panelContextValue}>
|
||||
<InvestigationSection />
|
||||
</RightPanelContext.Provider>
|
||||
</ExpandableFlyoutContext.Provider>
|
||||
);
|
||||
|
||||
getByTestId(INVESTIGATION_SECTION_HEADER_TEST_ID).click();
|
||||
expect(getByTestId(INVESTIGATION_SECTION_CONTENT_TEST_ID)).toBeInTheDocument();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { VFC } from 'react';
|
||||
import React from 'react';
|
||||
import { ExpandableSection } from './expandable_section';
|
||||
import { HighlightedFields } from './highlighted_fields';
|
||||
import { INVESTIGATION_SECTION_TEST_ID } from './test_ids';
|
||||
import { INVESTIGATION_TITLE } from './translations';
|
||||
|
||||
export interface DescriptionSectionProps {
|
||||
/**
|
||||
* Boolean to allow the component to be expanded or collapsed on first render
|
||||
*/
|
||||
expanded?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Most top section of the overview tab. It contains the description, reason and mitre attack information (for a document of type alert).
|
||||
*/
|
||||
export const InvestigationSection: VFC<DescriptionSectionProps> = ({ expanded = false }) => {
|
||||
return (
|
||||
<ExpandableSection
|
||||
expanded={expanded}
|
||||
title={INVESTIGATION_TITLE}
|
||||
data-test-subj={INVESTIGATION_SECTION_TEST_ID}
|
||||
>
|
||||
<HighlightedFields />
|
||||
</ExpandableSection>
|
||||
);
|
||||
};
|
||||
|
||||
InvestigationSection.displayName = 'InvestigationSection';
|
|
@ -7,11 +7,23 @@
|
|||
|
||||
import { CONTENT_TEST_ID, HEADER_TEST_ID } from './expandable_section';
|
||||
|
||||
/* Header */
|
||||
|
||||
export const FLYOUT_HEADER_TITLE_TEST_ID = 'securitySolutionDocumentDetailsFlyoutHeaderTitle';
|
||||
export const EXPAND_DETAILS_BUTTON_TEST_ID =
|
||||
'securitySolutionDocumentDetailsFlyoutHeaderExpandDetailButton';
|
||||
export const COLLAPSE_DETAILS_BUTTON_TEST_ID =
|
||||
'securitySolutionDocumentDetailsFlyoutHeaderCollapseDetailButton';
|
||||
export const FLYOUT_HEADER_SEVERITY_TITLE_TEST_ID =
|
||||
'securitySolutionAlertDetailsFlyoutHeaderSeverityTitle';
|
||||
export const FLYOUT_HEADER_SEVERITY_VALUE_TEST_ID = 'severity';
|
||||
export const FLYOUT_HEADER_RISK_SCORE_TITLE_TEST_ID =
|
||||
'securitySolutionAlertDetailsFlyoutHeaderRiskScoreTitle';
|
||||
export const FLYOUT_HEADER_RISK_SCORE_VALUE_TEST_ID =
|
||||
'securitySolutionAlertDetailsFlyoutHeaderRiskScoreValue';
|
||||
|
||||
/* Description section */
|
||||
|
||||
export const DESCRIPTION_SECTION_TEST_ID =
|
||||
'securitySolutionDocumentDetailsFlyoutDescriptionSection';
|
||||
export const DESCRIPTION_SECTION_HEADER_TEST_ID = DESCRIPTION_SECTION_TEST_ID + HEADER_TEST_ID;
|
||||
|
@ -25,15 +37,18 @@ export const REASON_TITLE_TEST_ID = 'securitySolutionDocumentDetailsFlyoutReason
|
|||
export const REASON_DETAILS_TEST_ID = 'securitySolutionDocumentDetailsFlyoutReasonDetails';
|
||||
export const MITRE_ATTACK_TITLE_TEST_ID = 'securitySolutionAlertDetailsFlyoutMitreAttackTitle';
|
||||
export const MITRE_ATTACK_DETAILS_TEST_ID = 'securitySolutionAlertDetailsFlyoutMitreAttackDetails';
|
||||
export const FLYOUT_HEADER_SEVERITY_TITLE_TEST_ID =
|
||||
'securitySolutionAlertDetailsFlyoutHeaderSeverityTitle';
|
||||
export const FLYOUT_HEADER_SEVERITY_VALUE_TEST_ID = 'severity';
|
||||
export const FLYOUT_HEADER_RISK_SCORE_TITLE_TEST_ID =
|
||||
'securitySolutionAlertDetailsFlyoutHeaderRiskScoreTitle';
|
||||
export const FLYOUT_HEADER_RISK_SCORE_VALUE_TEST_ID =
|
||||
'securitySolutionAlertDetailsFlyoutHeaderRiskScoreValue';
|
||||
|
||||
/* Investigation section */
|
||||
|
||||
export const INVESTIGATION_SECTION_TEST_ID =
|
||||
'securitySolutionDocumentDetailsFlyoutInvestigationSection';
|
||||
export const INVESTIGATION_SECTION_HEADER_TEST_ID = INVESTIGATION_SECTION_TEST_ID + HEADER_TEST_ID;
|
||||
export const INVESTIGATION_SECTION_CONTENT_TEST_ID =
|
||||
INVESTIGATION_SECTION_TEST_ID + CONTENT_TEST_ID;
|
||||
export const HIGHLIGHTED_FIELDS_TITLE_TEST_ID =
|
||||
'securitySolutionDocumentDetailsFlyoutHighlightedFieldsTitle';
|
||||
export const HIGHLIGHTED_FIELDS_DETAILS_TEST_ID =
|
||||
'securitySolutionDocumentDetailsFlyoutHighlightedFieldsDetails';
|
||||
export const HIGHLIGHTED_FIELDS_TEST_ID = 'securitySolutionDocumentDetailsFlyoutHighlightedFields';
|
||||
export const HIGHLIGHTED_FIELDS_HEADER_EXPAND_ICON_TEST_ID = 'query-toggle-header';
|
||||
export const HIGHLIGHTED_FIELDS_HEADER_TITLE_TEST_ID = 'header-section-title';
|
||||
export const HIGHLIGHTED_FIELDS_DETAILS_TEST_ID = 'summary-view';
|
||||
export const HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK = 'summary-view-go-to-table-link';
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
/* Header */
|
||||
|
||||
export const EXPAND_DETAILS_BUTTON = i18n.translate(
|
||||
'xpack.securitySolution.flyout.documentDetails.expandDetailButton',
|
||||
{ defaultMessage: 'Expand alert details' }
|
||||
|
@ -36,6 +38,8 @@ export const RISK_SCORE_TITLE = i18n.translate(
|
|||
}
|
||||
);
|
||||
|
||||
/* Description section */
|
||||
|
||||
export const DESCRIPTION_TITLE = i18n.translate(
|
||||
'xpack.securitySolution.flyout.documentDetails.descriptionTitle',
|
||||
{
|
||||
|
@ -83,6 +87,15 @@ export const DOCUMENT_REASON_TITLE = i18n.translate(
|
|||
}
|
||||
);
|
||||
|
||||
/* Investigation section */
|
||||
|
||||
export const INVESTIGATION_TITLE = i18n.translate(
|
||||
'xpack.securitySolution.flyout.documentDetails.investigationSectionTitle',
|
||||
{
|
||||
defaultMessage: 'Investigation',
|
||||
}
|
||||
);
|
||||
|
||||
export const HIGHLIGHTED_FIELDS_TITLE = i18n.translate(
|
||||
'xpack.securitySolution.flyout.documentDetails.highlightedFieldsTitle',
|
||||
{ defaultMessage: 'Highlighted fields' }
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
import type { FC } from 'react';
|
||||
import React, { memo } from 'react';
|
||||
import { EuiHorizontalRule, EuiPanel } from '@elastic/eui';
|
||||
import { EuiHorizontalRule } from '@elastic/eui';
|
||||
import { InvestigationSection } from '../components/investigation_section';
|
||||
import { DescriptionSection } from '../components/description_section';
|
||||
import { HighlightedFields } from '../components/highlighted_fields';
|
||||
|
||||
/**
|
||||
* Overview view displayed in the document details expandable flyout right section
|
||||
|
@ -19,9 +19,7 @@ export const OverviewTab: FC = memo(() => {
|
|||
<>
|
||||
<DescriptionSection />
|
||||
<EuiHorizontalRule margin="l" />
|
||||
<EuiPanel hasBorder hasShadow={false}>
|
||||
<HighlightedFields />
|
||||
</EuiPanel>
|
||||
<InvestigationSection />
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue