diff --git a/x-pack/plugins/security_solution/cypress/e2e/detection_alerts/expandable_flyout/alert_details_right_panel_overview_tab.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/detection_alerts/expandable_flyout/alert_details_right_panel_overview_tab.cy.ts
index 721de71fc9fd0..7c93af0b211e7 100644
--- a/x-pack/plugins/security_solution/cypress/e2e/detection_alerts/expandable_flyout/alert_details_right_panel_overview_tab.cy.ts
+++ b/x-pack/plugins/security_solution/cypress/e2e/detection_alerts/expandable_flyout/alert_details_right_panel_overview_tab.cy.ts
@@ -8,6 +8,13 @@
import {
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_MITRE_ATTACK_DETAILS,
DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_MITRE_ATTACK_TITLE,
+ DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_DETAILS,
+ 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,
} from '../../../screens/document_expandable_flyout';
import {
expandFirstAlertExpandableFlyout,
@@ -40,5 +47,41 @@ describe.skip(
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 highlighted fields', () => {
+ cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS).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();
+ });
+ });
+
+ it('should navigate to table tab when clicking on highlighted fields view button', () => {
+ cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS).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();
+ });
+
+ // 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');
+ });
}
);
diff --git a/x-pack/plugins/security_solution/cypress/screens/document_expandable_flyout.ts b/x-pack/plugins/security_solution/cypress/screens/document_expandable_flyout.ts
index 9af6f601c6a14..00e0c33c28c4a 100644
--- a/x-pack/plugins/security_solution/cypress/screens/document_expandable_flyout.ts
+++ b/x-pack/plugins/security_solution/cypress/screens/document_expandable_flyout.ts
@@ -37,6 +37,11 @@ import {
COLLAPSE_DETAILS_BUTTON_TEST_ID,
EXPAND_DETAILS_BUTTON_TEST_ID,
FLYOUT_HEADER_TITLE_TEST_ID,
+ 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,
MITRE_ATTACK_DETAILS_TEST_ID,
MITRE_ATTACK_TITLE_TEST_ID,
} from '../../public/flyout/right/components/test_ids';
@@ -103,6 +108,17 @@ export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_MITRE_ATTACK_TITLE = getDataTe
export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_MITRE_ATTACK_DETAILS = getDataTestSubjectSelector(
MITRE_ATTACK_DETAILS_TEST_ID
);
+export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS = getDataTestSubjectSelector(
+ HIGHLIGHTED_FIELDS_TEST_ID
+);
+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_HIGHLIGHTED_FIELDS_HEADER_TITLE =
+ getDataTestSubjectSelector(HIGHLIGHTED_FIELDS_HEADER_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 =
+ getDataTestSubjectSelector(HIGHLIGHTED_FIELDS_GO_TO_TABLE_LINK);
/* Table tab */
diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/summary_view.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/summary_view.tsx
index 188047e2d8ce0..d4ddc993a9fc6 100644
--- a/x-pack/plugins/security_solution/public/common/components/event_details/summary_view.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/event_details/summary_view.tsx
@@ -83,7 +83,7 @@ const SummaryViewComponent: React.FC<{
-
+
{VIEW_ALL_FIELDS}
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/highlighted_fields.stories.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/highlighted_fields.stories.tsx
new file mode 100644
index 0000000000000..b0adfdfeb4d67
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/highlighted_fields.stories.tsx
@@ -0,0 +1,75 @@
+/*
+ * 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 { HighlightedFields } from './highlighted_fields';
+import { RightPanelContext } from '../context';
+
+export default {
+ component: HighlightedFields,
+ title: 'Flyout/HighlightedFields',
+};
+
+// 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 = () => {
+ const flyoutContextValue = {
+ openRightPanel: () => window.alert('openRightPanel called'),
+ } as unknown as ExpandableFlyoutContext;
+ const panelContextValue = {
+ eventId: 'eventId',
+ indexName: 'indexName',
+ dataFormattedForFieldBrowser: [],
+ browserFields: {},
+ } as unknown as RightPanelContext;
+
+ return (
+
+
+
+
+
+ );
+};
+
+export const Collapsed: Story = () => {
+ const flyoutContextValue = {
+ openRightPanel: () => window.alert('openRightPanel called'),
+ } as unknown as ExpandableFlyoutContext;
+ const panelContextValue = {
+ eventId: 'eventId',
+ indexName: 'indexName',
+ dataFormattedForFieldBrowser: [],
+ browserFields: {},
+ } as unknown as RightPanelContext;
+
+ return (
+
+
+
+
+
+ );
+};
+
+export const Emtpy: Story = () => {
+ const flyoutContextValue = {} as unknown as ExpandableFlyoutContext;
+ const panelContextValue = {
+ eventId: null,
+ } as unknown as RightPanelContext;
+
+ return (
+
+
+
+
+
+ );
+};
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/highlighted_fields.test.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/highlighted_fields.test.tsx
new file mode 100644
index 0000000000000..5846303ff6dab
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/highlighted_fields.test.tsx
@@ -0,0 +1,184 @@
+/*
+ * 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 { 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 { 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('', () => {
+ 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(
+
+
+
+
+
+
+
+ );
+
+ 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(
+
+
+
+
+
+
+
+ );
+
+ 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(
+
+
+
+
+
+
+
+ );
+
+ 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,
+ },
+ });
+ expect(getByTestId(HIGHLIGHTED_FIELDS_DETAILS_TEST_ID)).toBeInTheDocument();
+ });
+
+ it('should render empty component if dataFormattedForFieldBrowser is null', () => {
+ const flyoutContextValue = {} as unknown as ExpandableFlyoutContext;
+ const panelContextValue = {
+ eventId: 'eventId',
+ indexName: 'indexName',
+ dataFormattedForFieldBrowser: null,
+ browserFields: {},
+ } as unknown as RightPanelContext;
+
+ const { baseElement } = render(
+
+
+
+
+
+ );
+
+ expect(baseElement).toMatchInlineSnapshot(`
+
+
+
+ `);
+ });
+
+ it('should render empty component if browserFields is null', () => {
+ const flyoutContextValue = {} as unknown as ExpandableFlyoutContext;
+ const panelContextValue = {
+ eventId: 'eventId',
+ indexName: 'indexName',
+ dataFormattedForFieldBrowser: [],
+ browserFields: null,
+ } as unknown as RightPanelContext;
+
+ const { baseElement } = render(
+
+
+
+
+
+ );
+
+ expect(baseElement).toMatchInlineSnapshot(`
+
+
+
+ `);
+ });
+
+ it('should render empty component if eventId is null', () => {
+ const flyoutContextValue = {} as unknown as ExpandableFlyoutContext;
+ const panelContextValue = {
+ eventId: null,
+ indexName: 'indexName',
+ dataFormattedForFieldBrowser: [],
+ browserFields: {},
+ } as unknown as RightPanelContext;
+
+ const { baseElement } = render(
+
+
+
+
+
+ );
+
+ expect(baseElement).toMatchInlineSnapshot(`
+
+
+
+ `);
+ });
+});
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/highlighted_fields.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/highlighted_fields.tsx
new file mode 100644
index 0000000000000..f8f7ed46f505f
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/highlighted_fields.tsx
@@ -0,0 +1,73 @@
+/*
+ * 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 { EuiFlexGroup } from '@elastic/eui';
+import type { VFC } from 'react';
+import React, { useCallback, useState } from 'react';
+import { useExpandableFlyoutContext } from '@kbn/expandable-flyout';
+import { HIGHLIGHTED_FIELDS_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 = ({ expanded = false }) => {
+ const [isPanelExpanded, setIsPanelExpanded] = useState(expanded);
+
+ const { openRightPanel } = useExpandableFlyoutContext();
+ const { eventId, indexName, dataFormattedForFieldBrowser, browserFields } =
+ useRightPanelContext();
+
+ const goToTableTab = useCallback(() => {
+ openRightPanel({
+ id: RightPanelKey,
+ path: RightPanelTableTabPath,
+ params: {
+ id: eventId,
+ indexName,
+ },
+ });
+ }, [eventId, indexName, openRightPanel]);
+
+ if (!dataFormattedForFieldBrowser || !browserFields || !eventId) {
+ return <>>;
+ }
+
+ return (
+
+
+ {isPanelExpanded && (
+
+ )}
+
+ );
+};
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/test_ids.ts b/x-pack/plugins/security_solution/public/flyout/right/components/test_ids.ts
index b679ef7615e4d..a13de2fbf7d64 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/test_ids.ts
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/test_ids.ts
@@ -12,3 +12,8 @@ export const COLLAPSE_DETAILS_BUTTON_TEST_ID =
'securitySolutionDocumentDetailsFlyoutHeaderCollapseDetailButton';
export const MITRE_ATTACK_TITLE_TEST_ID = 'securitySolutionAlertDetailsFlyoutMitreAttackTitle';
export const MITRE_ATTACK_DETAILS_TEST_ID = 'securitySolutionAlertDetailsFlyoutMitreAttackDetails';
+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';
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/translations.ts b/x-pack/plugins/security_solution/public/flyout/right/components/translations.ts
index 8fc7f2b482589..34c39f2c65179 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/translations.ts
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/translations.ts
@@ -16,3 +16,8 @@ export const COLLAPSE_DETAILS_BUTTON = i18n.translate(
'xpack.securitySolution.flyout.documentDetails.collapseDetailButton',
{ defaultMessage: 'Collapse alert details' }
);
+
+export const HIGHLIGHTED_FIELDS_TITLE = i18n.translate(
+ 'xpack.securitySolution.flyout.documentDetails.highlightedFieldsTitle',
+ { defaultMessage: 'Highlighted fields' }
+);
diff --git a/x-pack/plugins/security_solution/public/flyout/right/index.tsx b/x-pack/plugins/security_solution/public/flyout/right/index.tsx
index 9519776c07993..33489fd6b143a 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/index.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/index.tsx
@@ -18,6 +18,7 @@ import { tabs } from './tabs';
export type RightPanelPaths = 'overview' | 'table' | 'json';
export const RightPanelKey: RightPanelProps['key'] = 'document-details-right';
+export const RightPanelTableTabPath: RightPanelProps['path'] = ['table'];
export interface RightPanelProps extends FlyoutPanel {
key: 'document-details-right';
diff --git a/x-pack/plugins/security_solution/public/flyout/right/tabs/overview_tab.tsx b/x-pack/plugins/security_solution/public/flyout/right/tabs/overview_tab.tsx
index 3681f738f7ed2..0161f198f097f 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/tabs/overview_tab.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/tabs/overview_tab.tsx
@@ -7,13 +7,22 @@
import type { FC } from 'react';
import React, { memo } from 'react';
+import { EuiPanel } from '@elastic/eui';
+import { HighlightedFields } from '../components/highlighted_fields';
import { MitreAttack } from '../components/mitre_attack';
/**
* Overview view displayed in the document details expandable flyout right section
*/
export const OverviewTab: FC = memo(() => {
- return ;
+ return (
+ <>
+
+
+
+
+ >
+ );
});
OverviewTab.displayName = 'OverviewTab';
diff --git a/x-pack/plugins/security_solution/public/flyout/right/tabs/test_ids.ts b/x-pack/plugins/security_solution/public/flyout/right/tabs/test_ids.ts
index 858cb6762fa8c..b7245bc96cb83 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/tabs/test_ids.ts
+++ b/x-pack/plugins/security_solution/public/flyout/right/tabs/test_ids.ts
@@ -5,8 +5,6 @@
* 2.0.
*/
-export const OVERVIEW_TAB_CONTENT_TEST_ID =
- 'securitySolutionDocumentDetailsFlyoutOverviewTabContent';
export const TABLE_TAB_CONTENT_TEST_ID = 'event-fields-browser';
export const TABLE_TAB_ERROR_TEST_ID = 'securitySolutionAlertDetailsFlyoutTableTabError';
export const JSON_TAB_CONTENT_TEST_ID = 'jsonView';