diff --git a/x-pack/plugins/security_solution/cypress/e2e/detection_alerts/expandable_flyout/alert_details_right_panel.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/detection_alerts/expandable_flyout/alert_details_right_panel.cy.ts new file mode 100644 index 0000000000000..2c2340497a586 --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/e2e/detection_alerts/expandable_flyout/alert_details_right_panel.cy.ts @@ -0,0 +1,64 @@ +/* + * 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 { + ALERT_DETAILS_FLYOUT_HEADER_TITLE, + ALERT_DETAILS_FLYOUT_JSON_TAB, + ALERT_DETAILS_FLYOUT_JSON_TAB_CONTENT, + ALERT_DETAILS_FLYOUT_OVERVIEW_TAB, + ALERT_DETAILS_FLYOUT_OVERVIEW_TAB_CONTENT, + ALERT_DETAILS_FLYOUT_TABLE_TAB, + ALERT_DETAILS_FLYOUT_TABLE_TAB_CONTENT, +} from '../../../screens/alert_details_expandable_flyout'; +import { + expandFirstAlertExpandableFlyout, + openJsonTab, + openOverviewTab, + openTableTab, +} from '../../../tasks/alert_details_expandable_flyout'; +import { cleanKibana } from '../../../tasks/common'; +import { login, visit } from '../../../tasks/login'; +import { createCustomRuleEnabled } from '../../../tasks/api_calls/rules'; +import { getNewRule } from '../../../objects/rule'; +import { ALERTS_URL } from '../../../urls/navigation'; +import { waitForAlertsToPopulate } from '../../../tasks/create_new_rule'; + +// Skipping these for now as the feature is protected behind a feature flag set to false by default +// To run the tests locally, add 'securityFlyoutEnabled' in the Cypress config.ts here https://github.com/elastic/kibana/blob/main/x-pack/test/security_solution_cypress/config.ts#L50 +describe.skip('Alert details expandable flyout right panel', { testIsolation: false }, () => { + before(() => { + cleanKibana(); + login(); + createCustomRuleEnabled(getNewRule()); + visit(ALERTS_URL); + waitForAlertsToPopulate(); + expandFirstAlertExpandableFlyout(); + }); + + it('should display title in the header', () => { + cy.get(ALERT_DETAILS_FLYOUT_HEADER_TITLE) + .should('be.visible') + .and('have.text', 'Alert details'); + }); + + it('should display 3 tabs in the right section', () => { + cy.get(ALERT_DETAILS_FLYOUT_OVERVIEW_TAB).should('be.visible').and('have.text', 'Overview'); + cy.get(ALERT_DETAILS_FLYOUT_TABLE_TAB).should('be.visible').and('have.text', 'Table'); + cy.get(ALERT_DETAILS_FLYOUT_JSON_TAB).should('be.visible').and('have.text', 'JSON'); + }); + + it('should display tab content when switching tabs in the right section', () => { + openOverviewTab(); + cy.get(ALERT_DETAILS_FLYOUT_OVERVIEW_TAB_CONTENT).should('be.visible'); + + openTableTab(); + cy.get(ALERT_DETAILS_FLYOUT_TABLE_TAB_CONTENT).should('be.visible'); + + openJsonTab(); + cy.get(ALERT_DETAILS_FLYOUT_JSON_TAB_CONTENT).should('be.visible'); + }); +}); diff --git a/x-pack/plugins/security_solution/cypress/screens/alert_details_expandable_flyout.ts b/x-pack/plugins/security_solution/cypress/screens/alert_details_expandable_flyout.ts new file mode 100644 index 0000000000000..ca5ad1e7506b6 --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/screens/alert_details_expandable_flyout.ts @@ -0,0 +1,26 @@ +/* + * 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 { + JSON_TAB_TEST_ID, + OVERVIEW_TAB_TEST_ID, + TABLE_TAB_TEST_ID, +} from '../../public/flyout/right/test_ids'; +import { + JSON_TAB_CONTENT_TEST_ID, + OVERVIEW_TAB_CONTENT_TEST_ID, + TABLE_TAB_CONTENT_TEST_ID, +} from '../../public/flyout/right/tabs/test_ids'; +import { FLYOUT_HEADER_TITLE } from '../../public/flyout/right/components/test_ids'; + +export const ALERT_DETAILS_FLYOUT_HEADER_TITLE = `[data-test-subj="${FLYOUT_HEADER_TITLE}"]`; +export const ALERT_DETAILS_FLYOUT_OVERVIEW_TAB = `[data-test-subj="${OVERVIEW_TAB_TEST_ID}"]`; +export const ALERT_DETAILS_FLYOUT_TABLE_TAB = `[data-test-subj="${TABLE_TAB_TEST_ID}"]`; +export const ALERT_DETAILS_FLYOUT_JSON_TAB = `[data-test-subj="${JSON_TAB_TEST_ID}"]`; +export const ALERT_DETAILS_FLYOUT_OVERVIEW_TAB_CONTENT = `[data-test-subj="${OVERVIEW_TAB_CONTENT_TEST_ID}"]`; +export const ALERT_DETAILS_FLYOUT_TABLE_TAB_CONTENT = `[data-test-subj="${TABLE_TAB_CONTENT_TEST_ID}"]`; +export const ALERT_DETAILS_FLYOUT_JSON_TAB_CONTENT = `[data-test-subj="${JSON_TAB_CONTENT_TEST_ID}"]`; diff --git a/x-pack/plugins/security_solution/cypress/tasks/alert_details_expandable_flyout.ts b/x-pack/plugins/security_solution/cypress/tasks/alert_details_expandable_flyout.ts new file mode 100644 index 0000000000000..b03790de705e9 --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/tasks/alert_details_expandable_flyout.ts @@ -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 { + ALERT_DETAILS_FLYOUT_JSON_TAB, + ALERT_DETAILS_FLYOUT_OVERVIEW_TAB, + ALERT_DETAILS_FLYOUT_TABLE_TAB, +} from '../screens/alert_details_expandable_flyout'; +import { EXPAND_ALERT_BTN } from '../screens/alerts'; + +/** + * Find the first alert row in the alerts table then click on the expand icon button to open the flyout + */ +export const expandFirstAlertExpandableFlyout = () => { + cy.get(EXPAND_ALERT_BTN).first().click(); +}; + +/** + * Open the Overview tab in the alert details expandable flyout right section + */ +export const openOverviewTab = () => + cy.get(ALERT_DETAILS_FLYOUT_OVERVIEW_TAB).should('be.visible').click(); + +/** + * Open the Table tab in the alert details expandable flyout right section + */ +export const openTableTab = () => + cy.get(ALERT_DETAILS_FLYOUT_TABLE_TAB).should('be.visible').click(); + +/** + * Open the Json tab in the alert details expandable flyout right section + */ +export const openJsonTab = () => cy.get(ALERT_DETAILS_FLYOUT_JSON_TAB).should('be.visible').click(); diff --git a/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx b/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx index bda2e4d8d3629..264df10831fb7 100644 --- a/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx +++ b/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx @@ -12,6 +12,7 @@ import { IS_DRAGGING_CLASS_NAME } from '@kbn/securitysolution-t-grid'; import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; import type { KibanaPageTemplateProps } from '@kbn/shared-ux-page-kibana-template'; import { ExpandableFlyout, ExpandableFlyoutProvider } from '@kbn/expandable-flyout'; +import { expandableFlyoutDocumentsPanels } from '../../../flyout'; import { useSecuritySolutionNavigation } from '../../../common/components/navigation/use_security_solution_navigation'; import { TimelineId } from '../../../../common/types/timeline'; import { getTimelineShowStatusByIdSelector } from '../../../timelines/components/flyout/selectors'; @@ -107,7 +108,7 @@ export const SecuritySolutionTemplateWrapper: React.FC )} - {}} /> + {}} /> ); diff --git a/x-pack/plugins/security_solution/public/common/components/control_columns/row_action/index.tsx b/x-pack/plugins/security_solution/public/common/components/control_columns/row_action/index.tsx index a7b3395c12c5a..a292f183e2994 100644 --- a/x-pack/plugins/security_solution/public/common/components/control_columns/row_action/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/control_columns/row_action/index.tsx @@ -9,6 +9,7 @@ import type { EuiDataGridCellValueElementProps } from '@elastic/eui'; import React, { useCallback, useMemo } from 'react'; import { useDispatch } from 'react-redux'; import { useExpandableFlyoutContext } from '@kbn/expandable-flyout'; +import { RightPanelKey } from '../../../../flyout/right'; import type { SetEventsDeleted, SetEventsLoading, @@ -96,7 +97,15 @@ const RowActionComponent = ({ }; if (isSecurityFlyoutEnabled) { - openFlyout({}); + openFlyout({ + right: { + id: RightPanelKey, + params: { + id: eventId, + indexName, + }, + }, + }); } else { dispatch( dataTableActions.toggleDetailPanel({ diff --git a/x-pack/plugins/security_solution/public/flyout/README.md b/x-pack/plugins/security_solution/public/flyout/README.md new file mode 100644 index 0000000000000..43fee6ce87152 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/README.md @@ -0,0 +1,44 @@ +# expandable flyout panels + +## Description + +This folder hosts the panels that are displayed in the expandable flyout (see `@kbn/expandable-flyout` package). + +> Remember to add any new panels to the `index.tsx` at the root of the `flyout` folder. These are passed to the `@kbn/expandable-flyout` package as `registeredPanels`. + +## Notes + +At the moment, we only have a single expandable flyout for the Security Solution plugin. This flyout will be used for all documents (signals, events, indicators, assets and findings). We're using a set of generic right/left/preview panels, hence the following folder structure: + +``` +flyout +│ index.tsx +│ README.md +│ +└───right +└───left +└───preview +``` + +If different right, left or preview panels are needed, we should refactor the folder structure as follows: + +``` +flyout +│ index.tsx +│ README.md +│ +└───documents +│ └───right +│ └───left +│ └───preview +│ +└───new_type +│ └───right +│ └───left +│ └───preview +│ +└───other_new_type + └───right + └───left + └───preview +``` diff --git a/x-pack/plugins/security_solution/public/flyout/index.tsx b/x-pack/plugins/security_solution/public/flyout/index.tsx new file mode 100644 index 0000000000000..914de9cf4f315 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/index.tsx @@ -0,0 +1,28 @@ +/* + * 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 { ExpandableFlyoutProps } from '@kbn/expandable-flyout'; +import type { RightPanelProps } from './right'; +import { RightPanel, RightPanelKey } from './right'; +import { RightPanelProvider } from './right/context'; + +/** + * List of all panels that will be used within the document details expandable flyout. + * This needs to be passed to the expandable flyout registeredPanels property. + */ +export const expandableFlyoutDocumentsPanels: ExpandableFlyoutProps['registeredPanels'] = [ + { + key: RightPanelKey, + width: 500, + component: (props) => ( + + + + ), + }, +]; diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/header_title.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/header_title.tsx new file mode 100644 index 0000000000000..5878bdec75209 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/components/header_title.tsx @@ -0,0 +1,28 @@ +/* + * 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 { FC } from 'react'; +import React, { memo } from 'react'; +import { EuiSpacer, EuiTitle } from '@elastic/eui'; +import { FLYOUT_HEADER_TITLE } from './test_ids'; +import { HEADER_TITLE } from '../translations'; + +/** + * Document details flyout right section header + */ +export const HeaderTitle: FC = memo(() => { + return ( + <> + +

{HEADER_TITLE}

+
+ + + ); +}); + +HeaderTitle.displayName = 'HeaderTitle'; 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 new file mode 100644 index 0000000000000..9523ae1aa5ac2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/components/test_ids.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export const FLYOUT_HEADER_TITLE = 'securitySolutionDocumentDetailsFlyoutHeaderTitle'; diff --git a/x-pack/plugins/security_solution/public/flyout/right/content.tsx b/x-pack/plugins/security_solution/public/flyout/right/content.tsx new file mode 100644 index 0000000000000..4bf41518a0b2e --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/content.tsx @@ -0,0 +1,33 @@ +/* + * 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 { EuiFlyoutBody } from '@elastic/eui'; +import type { VFC } from 'react'; +import React, { useMemo } from 'react'; +import type { RightPanelPaths } from '.'; +import { tabs } from './tabs'; + +export interface PanelContentProps { + /** + * Id of the tab selected in the parent component to display its content + */ + selectedTabId: RightPanelPaths; +} + +/** + * Document details expandable flyout right section, that will display the content + * of the overview, table and json tabs. + */ +export const PanelContent: VFC = ({ selectedTabId }) => { + const selectedTabContent = useMemo(() => { + return tabs.find((tab) => tab.id === selectedTabId)?.content; + }, [selectedTabId]); + + return {selectedTabContent}; +}; + +PanelContent.displayName = 'PanelContent'; diff --git a/x-pack/plugins/security_solution/public/flyout/right/context.tsx b/x-pack/plugins/security_solution/public/flyout/right/context.tsx new file mode 100644 index 0000000000000..7d7c4aa991660 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/context.tsx @@ -0,0 +1,48 @@ +/* + * 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, { createContext, useContext } from 'react'; +import type { RightPanelProps } from '.'; + +export interface RightPanelContext { + /** + * Id of the document + */ + eventId: string; + /** + * Name of the index used in the parent's page + */ + indexName: string; +} + +export const RightPanelContext = createContext(undefined); + +export type RightPanelProviderProps = { + /** + * React components to render + */ + children: React.ReactNode; +} & Partial; + +export const RightPanelProvider = ({ id, indexName, children }: RightPanelProviderProps) => { + const contextValue = { + eventId: id as string, + indexName: indexName as string, + }; + + return {children}; +}; + +export const useRightPanelContext = (): RightPanelContext => { + const contextValue = useContext(RightPanelContext); + + if (!contextValue) { + throw new Error('RightPanelContext can only be used within RightPanelContext provider'); + } + + return contextValue; +}; diff --git a/x-pack/plugins/security_solution/public/flyout/right/header.tsx b/x-pack/plugins/security_solution/public/flyout/right/header.tsx new file mode 100644 index 0000000000000..9d6902bb0c3b3 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/header.tsx @@ -0,0 +1,60 @@ +/* + * 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 { EuiFlyoutHeader, EuiSpacer, EuiTab, EuiTabs } from '@elastic/eui'; +import type { VFC } from 'react'; +import React, { memo } from 'react'; +import { css } from '@emotion/react'; +import type { RightPanelPaths } from '.'; +import { tabs } from './tabs'; +import { HeaderTitle } from './components/header_title'; + +export interface PanelHeaderProps { + selectedTabId: RightPanelPaths; + setSelectedTabId: (selected: RightPanelPaths) => void; + handleOnEventClosed?: () => void; +} + +export const PanelHeader: VFC = memo( + ({ selectedTabId, setSelectedTabId, handleOnEventClosed }) => { + const onSelectedTabChanged = (id: RightPanelPaths) => setSelectedTabId(id); + const renderTabs = tabs.map((tab, index) => ( + onSelectedTabChanged(tab.id)} + isSelected={tab.id === selectedTabId} + key={index} + data-test-subj={tab['data-test-subj']} + > + {tab.name} + + )); + + return ( + + + + + + {renderTabs} + + + ); + } +); + +PanelHeader.displayName = 'PanelHeader'; diff --git a/x-pack/plugins/security_solution/public/flyout/right/index.tsx b/x-pack/plugins/security_solution/public/flyout/right/index.tsx new file mode 100644 index 0000000000000..9519776c07993 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/index.tsx @@ -0,0 +1,63 @@ +/* + * 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 { FC } from 'react'; +import React, { memo, useMemo } from 'react'; +import type { FlyoutPanel } from '@kbn/expandable-flyout'; +import { useExpandableFlyoutContext } from '@kbn/expandable-flyout'; +import { useRightPanelContext } from './context'; +import { PanelHeader } from './header'; +import { PanelContent } from './content'; +import type { RightPanelTabsType } from './tabs'; +import { tabs } from './tabs'; + +export type RightPanelPaths = 'overview' | 'table' | 'json'; + +export const RightPanelKey: RightPanelProps['key'] = 'document-details-right'; + +export interface RightPanelProps extends FlyoutPanel { + key: 'document-details-right'; + path?: RightPanelPaths[]; + params?: { + id: string; + indexName: string; + }; +} + +/** + * Panel to be displayed in the document details expandable flyout right section + */ +export const RightPanel: FC> = memo(({ path }) => { + const { openRightPanel } = useExpandableFlyoutContext(); + const { eventId, indexName } = useRightPanelContext(); + + const selectedTabId = useMemo(() => { + const defaultTab = tabs[0].id; + if (!path) return defaultTab; + return tabs.map((tab) => tab.id).find((tabId) => tabId === path[0]) ?? defaultTab; + }, [path]); + + const setSelectedTabId = (tabId: RightPanelTabsType[number]['id']) => { + openRightPanel({ + id: RightPanelKey, + path: [tabId], + params: { + id: eventId, + indexName, + }, + }); + }; + + return ( + <> + + + + ); +}); + +RightPanel.displayName = 'RightPanel'; diff --git a/x-pack/plugins/security_solution/public/flyout/right/tabs.tsx b/x-pack/plugins/security_solution/public/flyout/right/tabs.tsx new file mode 100644 index 0000000000000..89802787283fe --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/tabs.tsx @@ -0,0 +1,45 @@ +/* + * 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 { JSON_TAB_TEST_ID, OVERVIEW_TAB_TEST_ID, TABLE_TAB_TEST_ID } from './test_ids'; +import type { RightPanelPaths } from '.'; +import { JsonTab } from './tabs/json_tab'; +import { OverviewTab } from './tabs/overview_tab'; +import { TableTab } from './tabs/table_tab'; +import { JSON_TAB, OVERVIEW_TAB, TABLE_TAB } from './translations'; + +export type RightPanelTabsType = Array<{ + id: RightPanelPaths; + name: string; + content: React.ReactElement; + 'data-test-subj': string; +}>; + +/** + * Tabs to display in the document details expandable flyout right section + */ +export const tabs: RightPanelTabsType = [ + { + id: 'overview', + 'data-test-subj': OVERVIEW_TAB_TEST_ID, + name: OVERVIEW_TAB, + content: , + }, + { + id: 'table', + 'data-test-subj': TABLE_TAB_TEST_ID, + name: TABLE_TAB, + content: , + }, + { + id: 'json', + 'data-test-subj': JSON_TAB_TEST_ID, + name: JSON_TAB, + content: , + }, +]; diff --git a/x-pack/plugins/security_solution/public/flyout/right/tabs/json_tab.tsx b/x-pack/plugins/security_solution/public/flyout/right/tabs/json_tab.tsx new file mode 100644 index 0000000000000..edd6d318565d3 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/tabs/json_tab.tsx @@ -0,0 +1,20 @@ +/* + * 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 { EuiText } from '@elastic/eui'; +import type { FC } from 'react'; +import React, { memo } from 'react'; +import { JSON_TAB_CONTENT_TEST_ID } from './test_ids'; + +/** + * Json view displayed in the document details expandable flyout right section + */ +export const JsonTab: FC = memo(() => { + return {'Json tab'}; +}); + +JsonTab.displayName = 'JsonTab'; 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 new file mode 100644 index 0000000000000..57741d1379c04 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/tabs/overview_tab.tsx @@ -0,0 +1,20 @@ +/* + * 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 { FC } from 'react'; +import React, { memo } from 'react'; +import { EuiText } from '@elastic/eui'; +import { OVERVIEW_TAB_CONTENT_TEST_ID } from './test_ids'; + +/** + * Overview view displayed in the document details expandable flyout right section + */ +export const OverviewTab: FC = memo(() => { + return {'Overview tab'}; +}); + +OverviewTab.displayName = 'OverviewTab'; diff --git a/x-pack/plugins/security_solution/public/flyout/right/tabs/table_tab.tsx b/x-pack/plugins/security_solution/public/flyout/right/tabs/table_tab.tsx new file mode 100644 index 0000000000000..77edb9ffc61f9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/tabs/table_tab.tsx @@ -0,0 +1,20 @@ +/* + * 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 { EuiText } from '@elastic/eui'; +import type { FC } from 'react'; +import React, { memo } from 'react'; +import { TABLE_TAB_CONTENT_TEST_ID } from './test_ids'; + +/** + * Table view displayed in the document details expandable flyout right section + */ +export const TableTab: FC = memo(() => { + return {'Table tab'}; +}); + +TableTab.displayName = 'TableTab'; 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 new file mode 100644 index 0000000000000..6431848df6bf7 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/tabs/test_ids.ts @@ -0,0 +1,11 @@ +/* + * 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. + */ + +export const OVERVIEW_TAB_CONTENT_TEST_ID = + 'securitySolutionDocumentDetailsFlyoutOverviewTabContent'; +export const TABLE_TAB_CONTENT_TEST_ID = 'securitySolutionDocumentDetailsFlyoutTableTabContent'; +export const JSON_TAB_CONTENT_TEST_ID = 'securitySolutionDocumentDetailsFlyoutJsonTabContent'; diff --git a/x-pack/plugins/security_solution/public/flyout/right/test_ids.ts b/x-pack/plugins/security_solution/public/flyout/right/test_ids.ts new file mode 100644 index 0000000000000..3e3f16c629d2c --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/test_ids.ts @@ -0,0 +1,10 @@ +/* + * 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. + */ + +export const OVERVIEW_TAB_TEST_ID = 'securitySolutionDocumentDetailsFlyoutOverviewTab'; +export const TABLE_TAB_TEST_ID = 'securitySolutionDocumentDetailsFlyoutTableTab'; +export const JSON_TAB_TEST_ID = 'securitySolutionDocumentDetailsFlyoutJsonTab'; diff --git a/x-pack/plugins/security_solution/public/flyout/right/translations.ts b/x-pack/plugins/security_solution/public/flyout/right/translations.ts new file mode 100644 index 0000000000000..cbac395d5b029 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/translations.ts @@ -0,0 +1,26 @@ +/* + * 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 { i18n } from '@kbn/i18n'; + +export const HEADER_TITLE = i18n.translate( + 'xpack.securitySolution.flyout.documentDetails.titleLabel', + { defaultMessage: 'Title' } +); + +export const OVERVIEW_TAB = i18n.translate( + 'xpack.securitySolution.flyout.documentDetails.overviewTab', + { defaultMessage: 'Overview' } +); + +export const TABLE_TAB = i18n.translate('xpack.securitySolution.flyout.documentDetails.tableTab', { + defaultMessage: 'Table', +}); + +export const JSON_TAB = i18n.translate('xpack.securitySolution.flyout.documentDetails.jsonTab', { + defaultMessage: 'JSON', +});