', () => {
expect(getByTestId(INVESTIGATION_GUIDE_NO_DATA_TEST_ID)).toBeInTheDocument();
});
- it('should render null when dataFormattedForFieldBrowser is null', () => {
- const mockContext = {
- ...mockContextValue,
- dataFormattedForFieldBrowser: null,
- };
- (useInvestigationGuide as jest.Mock).mockReturnValue({
- loading: false,
- error: false,
- });
- const { container } = render(renderInvestigationGuide(mockContext));
- expect(container).toBeEmptyDOMElement();
- });
-
- it('should render null useInvestigationGuide errors out', () => {
+ it('should render no data message when useInvestigationGuide errors out', () => {
(useInvestigationGuide as jest.Mock).mockReturnValue({
loading: false,
error: true,
});
- const { container } = render(renderInvestigationGuide());
- expect(container).toBeEmptyDOMElement();
+ const { getByTestId } = render(renderInvestigationGuide());
+ expect(getByTestId(INVESTIGATION_GUIDE_NO_DATA_TEST_ID)).toBeInTheDocument();
});
});
diff --git a/x-pack/plugins/security_solution/public/flyout/left/components/investigation_guide.tsx b/x-pack/plugins/security_solution/public/flyout/left/components/investigation_guide.tsx
index 2d0fe038f3c63..8cf39210bbac7 100644
--- a/x-pack/plugins/security_solution/public/flyout/left/components/investigation_guide.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/left/components/investigation_guide.tsx
@@ -26,10 +26,6 @@ export const InvestigationGuide: React.FC = () => {
dataFormattedForFieldBrowser,
});
- if (!dataFormattedForFieldBrowser || error) {
- return null;
- }
-
if (loading) {
return (
{
return (
<>
- {basicAlertData.ruleId && ruleNote ? (
+ {!error && basicAlertData.ruleId && ruleNote ? (
{
expect(getByTestId(PREVALENCE_DETAILS_LOADING_TEST_ID)).toBeInTheDocument();
});
- it('should render error if call errors out', () => {
+ it('should render no data message if call errors out', () => {
(usePrevalence as jest.Mock).mockReturnValue({
loading: false,
error: true,
@@ -231,66 +231,6 @@ describe('PrevalenceDetails', () => {
);
- expect(getByTestId(PREVALENCE_DETAILS_TABLE_ERROR_TEST_ID)).toBeInTheDocument();
- });
-
- it('should render error if event is null', () => {
- const contextValue = {
- ...panelContextValue,
- eventId: null,
- } as unknown as LeftPanelContext;
- (usePrevalence as jest.Mock).mockReturnValue({
- loading: false,
- error: true,
- data: [],
- });
-
- const { getByTestId } = render(
-
-
-
- );
-
- expect(getByTestId(PREVALENCE_DETAILS_TABLE_ERROR_TEST_ID)).toBeInTheDocument();
- });
-
- it('should render error if dataFormattedForFieldBrowser is null', () => {
- const contextValue = {
- ...panelContextValue,
- dataFormattedForFieldBrowser: null,
- };
- (usePrevalence as jest.Mock).mockReturnValue({
- loading: false,
- error: true,
- data: [],
- });
-
- const { getByTestId } = render(
-
-
-
- );
-
- expect(getByTestId(PREVALENCE_DETAILS_TABLE_ERROR_TEST_ID)).toBeInTheDocument();
- });
-
- it('should render error if browserFields is null', () => {
- const contextValue = {
- ...panelContextValue,
- browserFields: null,
- };
- (usePrevalence as jest.Mock).mockReturnValue({
- loading: false,
- error: true,
- data: [],
- });
-
- const { getByTestId } = render(
-
-
-
- );
-
- expect(getByTestId(PREVALENCE_DETAILS_TABLE_ERROR_TEST_ID)).toBeInTheDocument();
+ expect(getByTestId(`${PREVALENCE_DETAILS_TABLE_NO_DATA_TEST_ID}Error`)).toBeInTheDocument();
});
});
diff --git a/x-pack/plugins/security_solution/public/flyout/left/components/prevalence_details.tsx b/x-pack/plugins/security_solution/public/flyout/left/components/prevalence_details.tsx
index c58c138264ef5..cd4283613a453 100644
--- a/x-pack/plugins/security_solution/public/flyout/left/components/prevalence_details.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/left/components/prevalence_details.tsx
@@ -10,7 +10,6 @@ import React, { useMemo, useState } from 'react';
import type { EuiBasicTableColumn, OnTimeChangeProps } from '@elastic/eui';
import {
EuiCallOut,
- EuiEmptyPrompt,
EuiFlexGroup,
EuiFlexItem,
EuiInMemoryTable,
@@ -28,10 +27,8 @@ import { useLicense } from '../../../common/hooks/use_license';
import { InvestigateInTimelineButton } from '../../../common/components/event_details/table/investigate_in_timeline_button';
import type { PrevalenceData } from '../../shared/hooks/use_prevalence';
import { usePrevalence } from '../../shared/hooks/use_prevalence';
-import { ERROR_MESSAGE, ERROR_TITLE } from '../../shared/translations';
import {
HOST_TITLE,
- PREVALENCE_ERROR_MESSAGE,
PREVALENCE_TABLE_ALERT_COUNT_COLUMN_TITLE,
PREVALENCE_TABLE_COUNT_COLUMN_TITLE,
PREVALENCE_TABLE_DOC_COUNT_COLUMN_TITLE,
@@ -49,7 +46,6 @@ import {
PREVALENCE_DETAILS_LOADING_TEST_ID,
PREVALENCE_DETAILS_TABLE_ALERT_COUNT_CELL_TEST_ID,
PREVALENCE_DETAILS_TABLE_DOC_COUNT_CELL_TEST_ID,
- PREVALENCE_DETAILS_TABLE_ERROR_TEST_ID,
PREVALENCE_DETAILS_TABLE_HOST_PREVALENCE_CELL_TEST_ID,
PREVALENCE_DETAILS_TABLE_VALUE_CELL_TEST_ID,
PREVALENCE_DETAILS_TABLE_FIELD_CELL_TEST_ID,
@@ -208,8 +204,7 @@ const columns: Array> = [
* Prevalence table displayed in the document details expandable flyout left section under the Insights tab
*/
export const PrevalenceDetails: React.FC = () => {
- const { browserFields, dataFormattedForFieldBrowser, eventId, investigationFields } =
- useLeftPanelContext();
+ const { dataFormattedForFieldBrowser, investigationFields } = useLeftPanelContext();
const isPlatinumPlus = useLicense().isPlatinumPlus();
@@ -273,18 +268,6 @@ export const PrevalenceDetails: React.FC = () => {
);
}
- if (!eventId || !dataFormattedForFieldBrowser || !browserFields || error) {
- return (
- {ERROR_TITLE(PREVALENCE_ERROR_MESSAGE)}}
- body={{ERROR_MESSAGE(PREVALENCE_ERROR_MESSAGE)}
}
- data-test-subj={PREVALENCE_DETAILS_TABLE_ERROR_TEST_ID}
- />
- );
- }
-
const upsell = (
<>
@@ -309,7 +292,7 @@ export const PrevalenceDetails: React.FC = () => {
return (
<>
- {!isPlatinumPlus && upsell}
+ {!error && !isPlatinumPlus && upsell}
values: { hostName },
});
-export const PREVALENCE_ERROR_MESSAGE = i18n.translate(
- 'xpack.securitySolution.flyout.prevalenceErrorMessage',
- {
- defaultMessage: 'prevalence',
- }
-);
-
export const PREVALENCE_NO_DATA_MESSAGE = i18n.translate(
'xpack.securitySolution.flyout.prevalenceNoDataMessage',
{
diff --git a/x-pack/plugins/security_solution/public/flyout/left/context.tsx b/x-pack/plugins/security_solution/public/flyout/left/context.tsx
index 15de2dfc9a78d..a791dcbf5fb5a 100644
--- a/x-pack/plugins/security_solution/public/flyout/left/context.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/left/context.tsx
@@ -6,24 +6,15 @@
*/
import type { BrowserFields, TimelineEventsDetailsItem } from '@kbn/timelines-plugin/common';
-import { css } from '@emotion/react';
-import React, { createContext, useContext, useMemo } from 'react';
-import { EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui';
+import React, { createContext, memo, useContext, useMemo } from 'react';
import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs';
+import { useEventDetails } from '../shared/hooks/use_event_details';
+import { FlyoutError } from '../shared/components/flyout_error';
+import { FlyoutLoading } from '../shared/components/flyout_loading';
import type { SearchHit } from '../../../common/search_strategy';
import type { LeftPanelProps } from '.';
import type { GetFieldsData } from '../../common/hooks/use_get_fields_data';
-import { useGetFieldsData } from '../../common/hooks/use_get_fields_data';
-import { useTimelineEventsDetails } from '../../timelines/containers/details';
-import {
- getAlertIndexAlias,
- useBasicDataFromDetailsData,
-} from '../../timelines/components/side_panel/event_details/helpers';
-import { useSpaceId } from '../../common/hooks/use_space_id';
-import { useRouteSpy } from '../../common/utils/route/use_route_spy';
-import { SecurityPageName } from '../../../common/constants';
-import { SourcererScopeName } from '../../common/store/sourcerer/model';
-import { useSourcererDataView } from '../../common/containers/sourcerer';
+import { useBasicDataFromDetailsData } from '../../timelines/components/side_panel/event_details/helpers';
import { useRuleWithFallback } from '../../detection_engine/rule_management/logic/use_rule_with_fallback';
export interface LeftPanelContext {
@@ -42,19 +33,19 @@ export interface LeftPanelContext {
/**
* An object containing fields by type
*/
- browserFields: BrowserFields | null;
+ browserFields: BrowserFields;
/**
* An object with top level fields from the ECS object
*/
- dataAsNestedObject: Ecs | null;
+ dataAsNestedObject: Ecs;
/**
* An array of field objects with category and value
*/
- dataFormattedForFieldBrowser: TimelineEventsDetailsItem[] | null;
+ dataFormattedForFieldBrowser: TimelineEventsDetailsItem[];
/**
* The actual raw document object
*/
- searchHit: SearchHit | undefined;
+ searchHit: SearchHit;
/**
* User defined fields to highlight (defined on the rule)
*/
@@ -74,69 +65,66 @@ export type LeftPanelProviderProps = {
children: React.ReactNode;
} & Partial;
-export const LeftPanelProvider = ({ id, indexName, scopeId, children }: LeftPanelProviderProps) => {
- const currentSpaceId = useSpaceId();
- const eventIndex = indexName ? getAlertIndexAlias(indexName, currentSpaceId) ?? indexName : '';
- const [{ pageName }] = useRouteSpy();
- const sourcererScope =
- pageName === SecurityPageName.detections
- ? SourcererScopeName.detections
- : SourcererScopeName.default;
- const sourcererDataView = useSourcererDataView(sourcererScope);
- const [loading, dataFormattedForFieldBrowser, searchHit, dataAsNestedObject] =
- useTimelineEventsDetails({
- indexName: eventIndex,
- eventId: id ?? '',
- runtimeMappings: sourcererDataView.runtimeMappings,
- skip: !id,
- });
- const getFieldsData = useGetFieldsData(searchHit?.fields);
- const { ruleId } = useBasicDataFromDetailsData(dataFormattedForFieldBrowser);
- const { rule: maybeRule } = useRuleWithFallback(ruleId);
-
- const contextValue = useMemo(
- () =>
- id && indexName && scopeId
- ? {
- eventId: id,
- indexName,
- scopeId,
- browserFields: sourcererDataView.browserFields,
- dataAsNestedObject,
- dataFormattedForFieldBrowser,
- searchHit,
- investigationFields: maybeRule?.investigation_fields?.field_names ?? [],
- getFieldsData,
- }
- : undefined,
- [
- id,
- indexName,
- scopeId,
- sourcererDataView.browserFields,
+export const LeftPanelProvider = memo(
+ ({ id, indexName, scopeId, children }: LeftPanelProviderProps) => {
+ const {
+ browserFields,
dataAsNestedObject,
dataFormattedForFieldBrowser,
- searchHit,
- maybeRule?.investigation_fields,
getFieldsData,
- ]
- );
+ loading,
+ searchHit,
+ } = useEventDetails({ eventId: id, indexName });
+
+ const { ruleId } = useBasicDataFromDetailsData(dataFormattedForFieldBrowser);
+ const { rule: maybeRule } = useRuleWithFallback(ruleId);
- if (loading) {
- return (
-
-
-
+ const contextValue = useMemo(
+ () =>
+ id &&
+ indexName &&
+ scopeId &&
+ dataAsNestedObject &&
+ dataFormattedForFieldBrowser &&
+ searchHit
+ ? {
+ eventId: id,
+ indexName,
+ scopeId,
+ browserFields,
+ dataAsNestedObject,
+ dataFormattedForFieldBrowser,
+ searchHit,
+ investigationFields: maybeRule?.investigation_fields?.field_names ?? [],
+ getFieldsData,
+ }
+ : undefined,
+ [
+ id,
+ indexName,
+ scopeId,
+ browserFields,
+ dataAsNestedObject,
+ dataFormattedForFieldBrowser,
+ searchHit,
+ maybeRule?.investigation_fields,
+ getFieldsData,
+ ]
);
+
+ if (loading) {
+ return ;
+ }
+
+ if (!contextValue) {
+ return ;
+ }
+
+ return {children};
}
+);
- return {children};
-};
+LeftPanelProvider.displayName = 'LeftPanelProvider';
export const useLeftPanelContext = () => {
const contextValue = useContext(LeftPanelContext);
diff --git a/x-pack/plugins/security_solution/public/flyout/left/hooks/use_threat_intelligence_details.test.ts b/x-pack/plugins/security_solution/public/flyout/left/hooks/use_threat_intelligence_details.test.ts
index 1e92ff0a6bd45..14319c8fa4404 100644
--- a/x-pack/plugins/security_solution/public/flyout/left/hooks/use_threat_intelligence_details.test.ts
+++ b/x-pack/plugins/security_solution/public/flyout/left/hooks/use_threat_intelligence_details.test.ts
@@ -19,6 +19,7 @@ import {
type GetBasicDataFromDetailsData,
useBasicDataFromDetailsData,
} from '../../../timelines/components/side_panel/event_details/helpers';
+import { mockContextValue } from '../mocks/mock_context';
jest.mock('../../../timelines/containers/details');
jest.mock('../../../common/containers/sourcerer');
@@ -63,20 +64,7 @@ describe('useThreatIntelligenceDetails', () => {
() => {},
]);
- jest.mocked(useLeftPanelContext).mockReturnValue({
- indexName: 'test-index',
- eventId: 'test-event-id',
- getFieldsData: () => null,
- dataFormattedForFieldBrowser: null,
- scopeId: 'test-scope-id',
- browserFields: null,
- searchHit: {
- _id: 'testId',
- _index: 'testIndex',
- },
- dataAsNestedObject: null,
- investigationFields: [],
- });
+ jest.mocked(useLeftPanelContext).mockReturnValue(mockContextValue);
});
afterEach(() => {
diff --git a/x-pack/plugins/security_solution/public/flyout/left/tabs/investigation_tab.tsx b/x-pack/plugins/security_solution/public/flyout/left/tabs/investigation_tab.tsx
index ce0629d790b2b..f52c25cf586d9 100644
--- a/x-pack/plugins/security_solution/public/flyout/left/tabs/investigation_tab.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/left/tabs/investigation_tab.tsx
@@ -9,17 +9,11 @@ import React, { memo } from 'react';
import { EuiPanel } from '@elastic/eui';
import { InvestigationGuide } from '../components/investigation_guide';
import { INVESTIGATION_TAB_CONTENT_TEST_ID } from './test_ids';
-import { useLeftPanelContext } from '../context';
/**
* Investigations view displayed in the document details expandable flyout left section
*/
export const InvestigationTab: React.FC = memo(() => {
- const { dataFormattedForFieldBrowser } = useLeftPanelContext();
- if (dataFormattedForFieldBrowser == null) {
- return null;
- }
-
return (
diff --git a/x-pack/plugins/security_solution/public/flyout/preview/components/alert_reason_preview.test.tsx b/x-pack/plugins/security_solution/public/flyout/preview/components/alert_reason_preview.test.tsx
index 30076fd3ca1d2..f84983e5ce13b 100644
--- a/x-pack/plugins/security_solution/public/flyout/preview/components/alert_reason_preview.test.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/preview/components/alert_reason_preview.test.tsx
@@ -31,17 +31,4 @@ describe('', () => {
);
expect(getByTestId(ALERT_REASON_PREVIEW_BODY_TEST_ID)).toBeInTheDocument();
});
-
- it('should render null is dataAsNestedObject is null', () => {
- const contextValue = {
- ...mockContextValue,
- dataAsNestedObject: null,
- };
- const { queryByTestId } = render(
-
-
-
- );
- expect(queryByTestId(ALERT_REASON_PREVIEW_BODY_TEST_ID)).not.toBeInTheDocument();
- });
});
diff --git a/x-pack/plugins/security_solution/public/flyout/preview/components/alert_reason_preview.tsx b/x-pack/plugins/security_solution/public/flyout/preview/components/alert_reason_preview.tsx
index 985c2bb288fa2..e7460c1042788 100644
--- a/x-pack/plugins/security_solution/public/flyout/preview/components/alert_reason_preview.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/preview/components/alert_reason_preview.tsx
@@ -29,16 +29,13 @@ export const AlertReasonPreview: React.FC = () => {
const { dataAsNestedObject, scopeId } = usePreviewPanelContext();
const renderer = useMemo(
- () =>
- dataAsNestedObject != null
- ? getRowRenderer({ data: dataAsNestedObject, rowRenderers: defaultRowRenderers })
- : null,
+ () => getRowRenderer({ data: dataAsNestedObject, rowRenderers: defaultRowRenderers }),
[dataAsNestedObject]
);
const rowRenderer = useMemo(
() =>
- renderer && dataAsNestedObject
+ renderer
? renderer.renderRow({
contextId: 'event-details',
data: dataAsNestedObject,
@@ -49,7 +46,7 @@ export const AlertReasonPreview: React.FC = () => {
[renderer, dataAsNestedObject, scopeId]
);
- if (!dataAsNestedObject || !renderer) {
+ if (!renderer) {
return null;
}
diff --git a/x-pack/plugins/security_solution/public/flyout/preview/context.tsx b/x-pack/plugins/security_solution/public/flyout/preview/context.tsx
index 005ef1dcdb258..c99fbbd0456b9 100644
--- a/x-pack/plugins/security_solution/public/flyout/preview/context.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/preview/context.tsx
@@ -5,17 +5,13 @@
* 2.0.
*/
-import React, { createContext, useContext, useMemo } from 'react';
+import React, { createContext, memo, useContext, useMemo } from 'react';
import type { DataViewBase } from '@kbn/es-query';
import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs';
-import { SecurityPageName } from '@kbn/security-solution-navigation';
+import { useEventDetails } from '../shared/hooks/use_event_details';
+import { FlyoutError } from '../shared/components/flyout_error';
+import { FlyoutLoading } from '../shared/components/flyout_loading';
import type { PreviewPanelProps } from '.';
-import { SourcererScopeName } from '../../common/store/sourcerer/model';
-import { useSourcererDataView } from '../../common/containers/sourcerer';
-import { useTimelineEventsDetails } from '../../timelines/containers/details';
-import { getAlertIndexAlias } from '../../timelines/components/side_panel/event_details/helpers';
-import { useSpaceId } from '../../common/hooks/use_space_id';
-import { useRouteSpy } from '../../common/utils/route/use_route_spy';
export interface PreviewPanelContext {
/**
@@ -41,7 +37,7 @@ export interface PreviewPanelContext {
/**
* An object with top level fields from the ECS object
*/
- dataAsNestedObject: Ecs | null;
+ dataAsNestedObject: Ecs;
}
export const PreviewPanelContext = createContext(undefined);
@@ -53,47 +49,43 @@ export type PreviewPanelProviderProps = {
children: React.ReactNode;
} & Partial;
-export const PreviewPanelProvider = ({
- id,
- indexName,
- scopeId,
- ruleId,
- children,
-}: PreviewPanelProviderProps) => {
- const currentSpaceId = useSpaceId();
- const eventIndex = indexName ? getAlertIndexAlias(indexName, currentSpaceId) ?? indexName : '';
- const [{ pageName }] = useRouteSpy();
- const sourcererScope =
- pageName === SecurityPageName.detections
- ? SourcererScopeName.detections
- : SourcererScopeName.default;
- const sourcererDataView = useSourcererDataView(sourcererScope);
- const [_, __, ___, dataAsNestedObject] = useTimelineEventsDetails({
- indexName: eventIndex,
- eventId: id ?? '',
- runtimeMappings: sourcererDataView.runtimeMappings,
- skip: !id,
- });
+export const PreviewPanelProvider = memo(
+ ({ id, indexName, scopeId, ruleId, children }: PreviewPanelProviderProps) => {
+ const { dataAsNestedObject, indexPattern, loading } = useEventDetails({
+ eventId: id,
+ indexName,
+ });
- const contextValue = useMemo(
- () =>
- id && indexName && scopeId
- ? {
- eventId: id,
- indexName,
- scopeId,
- ruleId: ruleId ?? '',
- indexPattern: sourcererDataView.indexPattern,
- dataAsNestedObject,
- }
- : undefined,
- [id, indexName, scopeId, ruleId, sourcererDataView.indexPattern, dataAsNestedObject]
- );
+ const contextValue = useMemo(
+ () =>
+ id && indexName && scopeId && dataAsNestedObject
+ ? {
+ eventId: id,
+ indexName,
+ scopeId,
+ ruleId: ruleId ?? '',
+ indexPattern,
+ dataAsNestedObject,
+ }
+ : undefined,
+ [id, indexName, scopeId, ruleId, indexPattern, dataAsNestedObject]
+ );
- return (
- {children}
- );
-};
+ if (loading) {
+ return ;
+ }
+
+ if (!contextValue) {
+ return ;
+ }
+
+ return (
+ {children}
+ );
+ }
+);
+
+PreviewPanelProvider.displayName = 'PreviewPanelProvider';
export const usePreviewPanelContext = (): PreviewPanelContext => {
const contextValue = useContext(PreviewPanelContext);
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/analyzer_preview_container.test.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/analyzer_preview_container.test.tsx
index 9892cfe3adf25..cecddeec1b987 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/analyzer_preview_container.test.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/analyzer_preview_container.test.tsx
@@ -35,7 +35,6 @@ jest.mock('react-router-dom', () => {
});
const panelContextValue = {
- dataAsNestedObject: null,
dataFormattedForFieldBrowser: mockDataFormattedForFieldBrowser,
} as unknown as RightPanelContext;
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/analyzer_preview_container.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/analyzer_preview_container.tsx
index 632a34e169f71..ede2169fce268 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/analyzer_preview_container.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/analyzer_preview_container.tsx
@@ -31,7 +31,7 @@ export const AnalyzerPreviewContainer: React.FC = () => {
const { dataAsNestedObject } = useRightPanelContext();
// decide whether to show the analyzer preview or not
- const isEnabled = isInvestigateInResolverActionEnabled(dataAsNestedObject || undefined);
+ const isEnabled = isInvestigateInResolverActionEnabled(dataAsNestedObject);
const dispatch = useDispatch();
const { startTransaction } = useStartTransaction();
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/description.test.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/description.test.tsx
index f80d7c1939661..48b12f31599cf 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/description.test.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/description.test.tsx
@@ -48,7 +48,7 @@ const flyoutContextValue = {
openPreviewPanel: jest.fn(),
} as unknown as ExpandableFlyoutContext;
-const panelContextValue = (dataFormattedForFieldBrowser: TimelineEventsDetailsItem[] | null) =>
+const panelContextValue = (dataFormattedForFieldBrowser: TimelineEventsDetailsItem[]) =>
({
eventId: 'event id',
indexName: 'indexName',
@@ -94,17 +94,6 @@ describe('', () => {
expect(getByTestId(DESCRIPTION_TITLE_TEST_ID)).toHaveTextContent(DOCUMENT_DESCRIPTION_TITLE);
});
- it('should render null if dataFormattedForFieldBrowser is null', () => {
- const panelContext = {
- ...panelContextValue([ruleUuid, ruleDescription, ruleName]),
- dataFormattedForFieldBrowser: null,
- } as unknown as RightPanelContext;
-
- const { container } = renderDescription(panelContext);
-
- expect(container).toBeEmptyDOMElement();
- });
-
it('should open preview panel when clicking on button', () => {
const panelContext = panelContextValue([ruleUuid, ruleDescription, ruleName]);
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/description.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/description.tsx
index 6c4d49d9d6b4c..521609a4c267c 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/description.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/description.tsx
@@ -73,10 +73,6 @@ export const Description: FC = () => {
[ruleName, openRulePreview, ruleId]
);
- if (!dataFormattedForFieldBrowser) {
- return null;
- }
-
const hasRuleDescription = ruleDescription && ruleDescription.length > 0;
return (
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/entities_overview.test.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/entities_overview.test.tsx
index 528b839bb218c..9c79f100bf9e2 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/entities_overview.test.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/entities_overview.test.tsx
@@ -117,55 +117,4 @@ describe('', () => {
expect(queryByTestId(INSIGHTS_ENTITIES_NO_DATA_TEST_ID)).toBeInTheDocument();
});
-
- it('should not render if eventId is null', () => {
- const contextValue = {
- ...mockContextValue,
- eventId: null,
- } as unknown as RightPanelContext;
-
- const { container } = render(
-
-
-
-
-
- );
-
- expect(container).toBeEmptyDOMElement();
- });
-
- it('should not render if indexName is null', () => {
- const contextValue = {
- ...mockContextValue,
- indexName: null,
- } as unknown as RightPanelContext;
-
- const { container } = render(
-
-
-
-
-
- );
-
- expect(container).toBeEmptyDOMElement();
- });
-
- it('should not render if scopeId is null', () => {
- const contextValue = {
- ...mockContextValue,
- scopeId: null,
- } as unknown as RightPanelContext;
-
- const { container } = render(
-
-
-
-
-
- );
-
- expect(container).toBeEmptyDOMElement();
- });
});
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/entities_overview.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/entities_overview.tsx
index efab7fa9f6d03..920b54be950c1 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/entities_overview.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/entities_overview.tsx
@@ -42,10 +42,6 @@ export const EntitiesOverview: React.FC = () => {
});
}, [eventId, openLeftPanel, indexName, scopeId]);
- if (!eventId || !indexName || !scopeId) {
- return null;
- }
-
return (
<>
', () => {
expect(container).toBeEmptyDOMElement();
});
-
- it('should render empty component if dataFormattedForFieldBrowser is null', () => {
- const panelContextValue = {
- dataFormattedForFieldBrowser: null,
- scopeId: 'scopeId',
- } as unknown as RightPanelContext;
- (useHighlightedFields as jest.Mock).mockReturnValue({
- field: {
- values: ['value'],
- },
- });
-
- const { container } = render(
-
-
-
- );
-
- expect(container).toBeEmptyDOMElement();
- });
});
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
index 8a1724dd98d5a..f6944df60396a 100644
--- 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
@@ -100,7 +100,7 @@ export const HighlightedFields: FC = () => {
[highlightedFields, scopeId]
);
- if (!dataFormattedForFieldBrowser || items.length === 0) {
+ if (items.length === 0) {
return null;
}
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/insights_section.test.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/insights_section.test.tsx
index 9f6c5b20b2b07..85bf1d891e344 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/insights_section.test.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/insights_section.test.tsx
@@ -10,7 +10,7 @@ import { render } from '@testing-library/react';
import { RightPanelContext } from '../context';
import { INSIGHTS_HEADER_TEST_ID } from './test_ids';
import { TestProviders } from '../../../common/mock';
-import { mockGetFieldsData } from '../mocks/mock_context';
+import { mockDataFormattedForFieldBrowser, mockGetFieldsData } from '../mocks/mock_context';
import { InsightsSection } from './insights_section';
import { useAlertPrevalence } from '../../../common/containers/alerts/use_alert_prevalence';
@@ -63,6 +63,7 @@ describe('', () => {
it('should render insights component as expanded when expanded is true', () => {
const contextValue = {
eventId: 'some_Id',
+ dataFormattedForFieldBrowser: mockDataFormattedForFieldBrowser,
getFieldsData: mockGetFieldsData,
} as unknown as RightPanelContext;
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/investigation_guide.test.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/investigation_guide.test.tsx
index ecac8547c6a51..a3d6c932b6f14 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/investigation_guide.test.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/investigation_guide.test.tsx
@@ -67,28 +67,14 @@ describe('', () => {
expect(getByTestId(INVESTIGATION_GUIDE_NO_DATA_TEST_ID)).toBeInTheDocument();
});
- it('should not render investigation guide button when dataFormattedForFieldBrowser is null', () => {
- (useInvestigationGuide as jest.Mock).mockReturnValue({
- loading: false,
- error: false,
- show: false,
- });
- const mockContext = {
- ...mockContextValue,
- dataFormattedForFieldBrowser: null,
- };
- const { container } = render(renderInvestigationGuide(mockContext));
- expect(container).toBeEmptyDOMElement();
- });
-
- it('should render null when useInvestigationGuide errors out', () => {
+ it('should render no data message when useInvestigationGuide errors out', () => {
(useInvestigationGuide as jest.Mock).mockReturnValue({
loading: false,
error: true,
show: false,
});
- const { container } = render(renderInvestigationGuide());
- expect(container).toBeEmptyDOMElement();
+ const { getByTestId } = render(renderInvestigationGuide());
+ expect(getByTestId(INVESTIGATION_GUIDE_NO_DATA_TEST_ID)).toBeInTheDocument();
});
});
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/investigation_guide.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/investigation_guide.tsx
index 4816577495c70..2175e67bbef53 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/investigation_guide.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/investigation_guide.tsx
@@ -48,10 +48,6 @@ export const InvestigationGuide: React.FC = () => {
});
}, [eventId, indexName, openLeftPanel, scopeId]);
- if (!dataFormattedForFieldBrowser || error) {
- return null;
- }
-
if (loading) {
return (
{
- {basicAlertData.ruleId && ruleNote ? (
+ {!error && basicAlertData.ruleId && ruleNote ? (
', () => {
beforeEach(() => {
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/prevalence_overview.test.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/prevalence_overview.test.tsx
index 96abc4689771e..affaaca1e27bf 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/prevalence_overview.test.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/prevalence_overview.test.tsx
@@ -129,54 +129,6 @@ describe('', () => {
expect(queryByTestId(valueDataTestSubj2)).not.toBeInTheDocument();
});
- it('should render null if eventId is null', () => {
- (usePrevalence as jest.Mock).mockReturnValue({
- loading: false,
- error: false,
- data: [],
- });
- const contextValue = {
- ...mockContextValue,
- eventId: null,
- } as unknown as RightPanelContext;
-
- const { container } = render(renderPrevalenceOverview(contextValue));
-
- expect(container).toBeEmptyDOMElement();
- });
-
- it('should render null if browserFields is null', () => {
- (usePrevalence as jest.Mock).mockReturnValue({
- loading: false,
- error: false,
- data: [],
- });
- const contextValue = {
- ...mockContextValue,
- browserFields: null,
- };
-
- const { container } = render(renderPrevalenceOverview(contextValue));
-
- expect(container).toBeEmptyDOMElement();
- });
-
- it('should render null if dataFormattedForFieldBrowser is null', () => {
- (usePrevalence as jest.Mock).mockReturnValue({
- loading: false,
- error: false,
- data: [],
- });
- const contextValue = {
- ...mockContextValue,
- dataFormattedForFieldBrowser: null,
- };
-
- const { container } = render(renderPrevalenceOverview(contextValue));
-
- expect(container).toBeEmptyDOMElement();
- });
-
it('should navigate to left section Insights tab when clicking on button', () => {
(usePrevalence as jest.Mock).mockReturnValue({
loading: false,
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/prevalence_overview.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/prevalence_overview.tsx
index 309925c21d98b..53e2d636d4bb6 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/prevalence_overview.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/prevalence_overview.tsx
@@ -27,14 +27,8 @@ const DEFAULT_TO = 'now';
* The component fetches the necessary data at once. The loading and error states are handled by the ExpandablePanel component.
*/
export const PrevalenceOverview: FC = () => {
- const {
- eventId,
- indexName,
- browserFields,
- dataFormattedForFieldBrowser,
- scopeId,
- investigationFields,
- } = useRightPanelContext();
+ const { eventId, indexName, dataFormattedForFieldBrowser, scopeId, investigationFields } =
+ useRightPanelContext();
const { openLeftPanel } = useExpandableFlyoutContext();
const goToCorrelationsTab = useCallback(() => {
@@ -73,10 +67,6 @@ export const PrevalenceOverview: FC = () => {
[data]
);
- if (!eventId || !browserFields || !dataFormattedForFieldBrowser) {
- return null;
- }
-
return (
', () => {
expect(getByTestId(REASON_TITLE_TEST_ID)).toBeInTheDocument();
});
- it('should render null if dataFormattedForFieldBrowser is null', () => {
- const panelContext = {
- ...panelContextValue,
- dataFormattedForFieldBrowser: null,
- } as unknown as RightPanelContext;
-
- const { container } = renderReason(panelContext);
-
- expect(container).toBeEmptyDOMElement();
- });
-
it('should render no reason if the field is null', () => {
const panelContext = {
...panelContextValue,
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/reason.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/reason.tsx
index b356809917973..e7cd3c7fddf11 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/reason.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/reason.tsx
@@ -70,10 +70,6 @@ export const Reason: FC = () => {
[openRulePreview]
);
- if (!dataFormattedForFieldBrowser) {
- return null;
- }
-
return (
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/session_preview_container.test.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/session_preview_container.test.tsx
index 8db5d4a9cacf5..0568c740f1de4 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/session_preview_container.test.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/session_preview_container.test.tsx
@@ -26,7 +26,6 @@ jest.mock('../hooks/use_session_preview');
jest.mock('../../../common/hooks/use_license');
const panelContextValue = {
- dataAsNestedObject: null,
getFieldsData: mockGetFieldsData,
} as unknown as RightPanelContext;
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/status.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/status.tsx
index fa3a0c6f2ab14..359b889398261 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/status.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/status.tsx
@@ -47,7 +47,7 @@ export const DocumentStatus: FC = () => {
eventId,
contextId: scopeId,
scopeId,
- browserFields: browserFields || {},
+ browserFields,
item,
})
);
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/threat_intelligence_overview.test.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/threat_intelligence_overview.test.tsx
index 70d8fce2d5c64..4d3d3334862ba 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/threat_intelligence_overview.test.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/threat_intelligence_overview.test.tsx
@@ -14,10 +14,7 @@ import { ThreatIntelligenceOverview } from './threat_intelligence_overview';
import { LeftPanelInsightsTab, LeftPanelKey } from '../../left';
import { useFetchThreatIntelligence } from '../hooks/use_fetch_threat_intelligence';
import { THREAT_INTELLIGENCE_TAB_ID } from '../../left/components/threat_intelligence_details';
-import {
- INSIGHTS_THREAT_INTELLIGENCE_CONTAINER_TEST_ID,
- INSIGHTS_THREAT_INTELLIGENCE_TEST_ID,
-} from './test_ids';
+import { INSIGHTS_THREAT_INTELLIGENCE_TEST_ID } from './test_ids';
import {
EXPANDABLE_PANEL_CONTENT_TEST_ID,
EXPANDABLE_PANEL_HEADER_TITLE_ICON_TEST_ID,
@@ -142,35 +139,6 @@ describe('', () => {
expect(getAllByTestId(LOADING_TEST_ID)).toHaveLength(2);
});
- it('should render null when eventId is null', () => {
- (useFetchThreatIntelligence as jest.Mock).mockReturnValue({
- loading: false,
- });
- const contextValue = {
- ...panelContextValue,
- eventId: null,
- } as unknown as RightPanelContext;
-
- const { getByTestId } = render(renderThreatIntelligenceOverview(contextValue));
-
- expect(getByTestId(INSIGHTS_THREAT_INTELLIGENCE_CONTAINER_TEST_ID)).toBeEmptyDOMElement();
- });
-
- it('should render null when dataFormattedForFieldBrowser is null', () => {
- (useFetchThreatIntelligence as jest.Mock).mockReturnValue({
- loading: false,
- error: true,
- });
- const contextValue = {
- ...panelContextValue,
- dataFormattedForFieldBrowser: null,
- } as unknown as RightPanelContext;
-
- const { getByTestId } = render(renderThreatIntelligenceOverview(contextValue));
-
- expect(getByTestId(INSIGHTS_THREAT_INTELLIGENCE_CONTAINER_TEST_ID)).toBeEmptyDOMElement();
- });
-
it('should navigate to left section Insights tab when clicking on button', () => {
(useFetchThreatIntelligence as jest.Mock).mockReturnValue({
loading: false,
diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/threat_intelligence_overview.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/threat_intelligence_overview.tsx
index 6e8c1f3c6dded..42253e61effe2 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/components/threat_intelligence_overview.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/components/threat_intelligence_overview.tsx
@@ -48,17 +48,10 @@ export const ThreatIntelligenceOverview: FC = () => {
});
}, [eventId, openLeftPanel, indexName, scopeId]);
- const {
- loading: threatIntelLoading,
- error: threatIntelError,
- threatMatchesCount,
- threatEnrichmentsCount,
- } = useFetchThreatIntelligence({
+ const { loading, threatMatchesCount, threatEnrichmentsCount } = useFetchThreatIntelligence({
dataFormattedForFieldBrowser,
});
- const error: boolean = !eventId || !dataFormattedForFieldBrowser || threatIntelError;
-
return (
{
data-test-subj={`${INSIGHTS_THREAT_INTELLIGENCE_TEST_ID}Container`}
>
;
-export const RightPanelProvider = ({
- id,
- indexName,
- scopeId,
- children,
-}: RightPanelProviderProps) => {
- const currentSpaceId = useSpaceId();
- // TODO Replace getAlertIndexAlias way to retrieving the eventIndex with the GET /_alias
- // https://github.com/elastic/kibana/issues/113063
- const eventIndex = indexName ? getAlertIndexAlias(indexName, currentSpaceId) ?? indexName : '';
- const [{ pageName }] = useRouteSpy();
- const sourcererScope =
- pageName === SecurityPageName.detections
- ? SourcererScopeName.detections
- : SourcererScopeName.default;
- const sourcererDataView = useSourcererDataView(sourcererScope);
- const [loading, dataFormattedForFieldBrowser, searchHit, dataAsNestedObject, refetchFlyoutData] =
- useTimelineEventsDetails({
- indexName: eventIndex,
- eventId: id ?? '',
- runtimeMappings: sourcererDataView.runtimeMappings,
- skip: !id,
- });
- const getFieldsData = useGetFieldsData(searchHit?.fields);
- const { ruleId } = useBasicDataFromDetailsData(dataFormattedForFieldBrowser);
- const { rule: maybeRule } = useRuleWithFallback(ruleId);
-
- const contextValue = useMemo(
- () =>
- id && indexName && scopeId
- ? {
- eventId: id,
- indexName,
- scopeId,
- browserFields: sourcererDataView.browserFields,
- dataAsNestedObject,
- dataFormattedForFieldBrowser,
- searchHit,
- investigationFields: maybeRule?.investigation_fields?.field_names ?? [],
- refetchFlyoutData,
- getFieldsData,
- }
- : undefined,
- [
- id,
- maybeRule,
- indexName,
- scopeId,
- sourcererDataView.browserFields,
+export const RightPanelProvider = memo(
+ ({ id, indexName, scopeId, children }: RightPanelProviderProps) => {
+ const {
+ browserFields,
dataAsNestedObject,
dataFormattedForFieldBrowser,
- searchHit,
- refetchFlyoutData,
getFieldsData,
- ]
- );
+ loading,
+ refetchFlyoutData,
+ searchHit,
+ } = useEventDetails({ eventId: id, indexName });
- if (loading) {
- return (
-
-
-
+ const { ruleId } = useBasicDataFromDetailsData(dataFormattedForFieldBrowser);
+ const { rule: maybeRule } = useRuleWithFallback(ruleId);
+
+ const contextValue = useMemo(
+ () =>
+ id &&
+ indexName &&
+ scopeId &&
+ dataAsNestedObject &&
+ dataFormattedForFieldBrowser &&
+ searchHit
+ ? {
+ eventId: id,
+ indexName,
+ scopeId,
+ browserFields,
+ dataAsNestedObject,
+ dataFormattedForFieldBrowser,
+ searchHit,
+ investigationFields: maybeRule?.investigation_fields?.field_names ?? [],
+ refetchFlyoutData,
+ getFieldsData,
+ }
+ : undefined,
+ [
+ id,
+ maybeRule,
+ indexName,
+ scopeId,
+ browserFields,
+ dataAsNestedObject,
+ dataFormattedForFieldBrowser,
+ searchHit,
+ refetchFlyoutData,
+ getFieldsData,
+ ]
);
+
+ if (loading) {
+ return ;
+ }
+
+ if (!contextValue) {
+ return ;
+ }
+
+ return {children};
}
+);
- return {children};
-};
+RightPanelProvider.displayName = 'RightPanelProvider';
export const useRightPanelContext = (): RightPanelContext => {
const contextValue = useContext(RightPanelContext);
diff --git a/x-pack/plugins/security_solution/public/flyout/right/footer.tsx b/x-pack/plugins/security_solution/public/flyout/right/footer.tsx
index b411470ee386f..b11f1ad1f0013 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/footer.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/footer.tsx
@@ -44,10 +44,6 @@ export const PanelFooter: FC = () => {
[eventId, indexName, openRightPanel, scopeId, showHostIsolationPanel]
);
- if (!dataFormattedForFieldBrowser || !dataAsNestedObject) {
- return null;
- }
-
return (
{
hookResult = renderHook(() => useFetchThreatIntelligence({ dataFormattedForFieldBrowser }));
expect(hookResult.result.current.loading).toEqual(false);
- expect(hookResult.result.current.error).toEqual(false);
expect(hookResult.result.current.threatMatches).toHaveLength(1);
expect(hookResult.result.current.threatMatchesCount).toEqual(1);
expect(hookResult.result.current.threatEnrichments).toHaveLength(1);
@@ -121,7 +120,6 @@ describe('useFetchThreatIntelligence', () => {
hookResult = renderHook(() => useFetchThreatIntelligence({ dataFormattedForFieldBrowser }));
expect(hookResult.result.current.loading).toEqual(false);
- expect(hookResult.result.current.error).toEqual(false);
expect(hookResult.result.current.threatMatches).toHaveLength(2);
expect(hookResult.result.current.threatMatchesCount).toEqual(2);
expect(hookResult.result.current.threatEnrichments).toHaveLength(2);
@@ -148,7 +146,6 @@ describe('useFetchThreatIntelligence', () => {
hookResult = renderHook(() => useFetchThreatIntelligence({ dataFormattedForFieldBrowser }));
expect(hookResult.result.current.loading).toEqual(false);
- expect(hookResult.result.current.error).toEqual(false);
expect(hookResult.result.current.threatMatches).toHaveLength(1);
expect(hookResult.result.current.threatMatchesCount).toEqual(1);
expect(hookResult.result.current.threatEnrichments).toEqual(undefined);
@@ -176,7 +173,6 @@ describe('useFetchThreatIntelligence', () => {
hookResult = renderHook(() => useFetchThreatIntelligence({ dataFormattedForFieldBrowser }));
expect(hookResult.result.current.loading).toEqual(false);
- expect(hookResult.result.current.error).toEqual(false);
expect(hookResult.result.current.threatMatches).toEqual(undefined);
expect(hookResult.result.current.threatMatchesCount).toEqual(0);
expect(hookResult.result.current.threatEnrichments).toHaveLength(1);
@@ -192,28 +188,6 @@ describe('useFetchThreatIntelligence', () => {
hookResult = renderHook(() => useFetchThreatIntelligence({ dataFormattedForFieldBrowser }));
expect(hookResult.result.current.loading).toEqual(true);
- expect(hookResult.result.current.error).toEqual(false);
- expect(hookResult.result.current.threatMatches).toEqual(undefined);
- expect(hookResult.result.current.threatMatchesCount).toEqual(0);
- expect(hookResult.result.current.threatEnrichments).toEqual(undefined);
- expect(hookResult.result.current.threatEnrichmentsCount).toEqual(0);
- });
-
- it('should return error true', () => {
- (useInvestigationTimeEnrichment as jest.Mock).mockReturnValue({
- result: {
- enrichments: [],
- totalCount: 0,
- },
- loading: false,
- });
-
- hookResult = renderHook(() =>
- useFetchThreatIntelligence({ dataFormattedForFieldBrowser: null })
- );
-
- expect(hookResult.result.current.loading).toEqual(false);
- expect(hookResult.result.current.error).toEqual(true);
expect(hookResult.result.current.threatMatches).toEqual(undefined);
expect(hookResult.result.current.threatMatchesCount).toEqual(0);
expect(hookResult.result.current.threatEnrichments).toEqual(undefined);
diff --git a/x-pack/plugins/security_solution/public/flyout/right/hooks/use_fetch_threat_intelligence.ts b/x-pack/plugins/security_solution/public/flyout/right/hooks/use_fetch_threat_intelligence.ts
index 37971e755f48b..3b495ad52bc60 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/hooks/use_fetch_threat_intelligence.ts
+++ b/x-pack/plugins/security_solution/public/flyout/right/hooks/use_fetch_threat_intelligence.ts
@@ -23,7 +23,7 @@ export interface UseThreatIntelligenceParams {
/**
* An array of field objects with category and value
*/
- dataFormattedForFieldBrowser: TimelineEventsDetailsItem[] | null;
+ dataFormattedForFieldBrowser: TimelineEventsDetailsItem[];
}
export interface UseThreatIntelligenceResult {
@@ -31,10 +31,6 @@ export interface UseThreatIntelligenceResult {
* Returns true while the threat intelligence data is being queried
*/
loading: boolean;
- /**
- * Returns true if the dataFormattedForFieldBrowser property is null
- */
- error: boolean;
/**
* Threat matches (from an indicator match rule)
*/
@@ -99,7 +95,6 @@ export const useFetchThreatIntelligence = ({
return {
loading,
- error: !dataFormattedForFieldBrowser,
threatMatches,
threatMatchesCount: (threatMatches || []).length,
threatEnrichments,
diff --git a/x-pack/plugins/security_solution/public/flyout/right/mocks/mock_right_panel_context.ts b/x-pack/plugins/security_solution/public/flyout/right/mocks/mock_right_panel_context.ts
index 38b69703356c0..33144d8c405cd 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/mocks/mock_right_panel_context.ts
+++ b/x-pack/plugins/security_solution/public/flyout/right/mocks/mock_right_panel_context.ts
@@ -5,8 +5,15 @@
* 2.0.
*/
+import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs';
+import type { SearchHit } from '../../../../common/search_strategy';
import type { RightPanelContext } from '../context';
-import { mockDataFormattedForFieldBrowser, mockGetFieldsData } from './mock_context';
+import {
+ mockDataAsNestedObject,
+ mockDataFormattedForFieldBrowser,
+ mockGetFieldsData,
+ mockSearchHit,
+} from './mock_context';
/**
* Mock contextValue for right panel context
@@ -18,8 +25,8 @@ export const mockContextValue: RightPanelContext = {
getFieldsData: mockGetFieldsData,
dataFormattedForFieldBrowser: mockDataFormattedForFieldBrowser,
browserFields: {},
- dataAsNestedObject: null,
- searchHit: undefined,
+ dataAsNestedObject: mockDataAsNestedObject as unknown as Ecs,
+ searchHit: mockSearchHit as unknown as SearchHit,
investigationFields: [],
refetchFlyoutData: jest.fn(),
};
diff --git a/x-pack/plugins/security_solution/public/flyout/right/tabs/json_tab.test.tsx b/x-pack/plugins/security_solution/public/flyout/right/tabs/json_tab.test.tsx
index f714a3c7839e5..dac048913c49b 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/tabs/json_tab.test.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/tabs/json_tab.test.tsx
@@ -9,7 +9,7 @@ import React from 'react';
import { render } from '@testing-library/react';
import { RightPanelContext } from '../context';
import { JsonTab } from './json_tab';
-import { JSON_TAB_ERROR_TEST_ID, JSON_TAB_CONTENT_TEST_ID } from './test_ids';
+import { JSON_TAB_CONTENT_TEST_ID } from './test_ids';
describe('', () => {
it('should render code block component', () => {
@@ -27,22 +27,4 @@ describe('', () => {
expect(getByTestId(JSON_TAB_CONTENT_TEST_ID)).toBeInTheDocument();
});
-
- it('should render error message on invalid searchHit', () => {
- const contextValue = {
- searchHit: null,
- } as unknown as RightPanelContext;
-
- const { getByTestId, getByText } = render(
-
-
-
- );
-
- expect(getByTestId(JSON_TAB_ERROR_TEST_ID)).toBeInTheDocument();
- expect(getByText('Unable to display document information')).toBeInTheDocument();
- expect(
- getByText('There was an error displaying the document fields and values')
- ).toBeInTheDocument();
- });
});
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
index 54322959d5326..b49bbca6f5705 100644
--- 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
@@ -5,12 +5,8 @@
* 2.0.
*/
-import { EuiEmptyPrompt } from '@elastic/eui';
import type { FC } from 'react';
import React, { memo } from 'react';
-import { DOCUMENT_ERROR_DETAILS, DOCUMENT_ERROR_TITLE } from './translations';
-import { JSON_TAB_ERROR_TEST_ID } from './test_ids';
-import { ERROR_TITLE, ERROR_MESSAGE } from '../../shared/translations';
import { JsonView } from '../../../common/components/event_details/json_view';
import { useRightPanelContext } from '../context';
@@ -20,18 +16,6 @@ import { useRightPanelContext } from '../context';
export const JsonTab: FC = memo(() => {
const { searchHit } = useRightPanelContext();
- if (!searchHit) {
- return (
- {ERROR_TITLE(DOCUMENT_ERROR_TITLE)}}
- body={{ERROR_MESSAGE(DOCUMENT_ERROR_DETAILS)}
}
- data-test-subj={JSON_TAB_ERROR_TEST_ID}
- />
- );
- }
-
return ;
});
diff --git a/x-pack/plugins/security_solution/public/flyout/right/tabs/table_tab.test.tsx b/x-pack/plugins/security_solution/public/flyout/right/tabs/table_tab.test.tsx
index 16e0d84cd083a..d93cf67abc620 100644
--- a/x-pack/plugins/security_solution/public/flyout/right/tabs/table_tab.test.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/right/tabs/table_tab.test.tsx
@@ -8,7 +8,7 @@
import React from 'react';
import { render } from '@testing-library/react';
import { RightPanelContext } from '../context';
-import { TABLE_TAB_ERROR_TEST_ID, TABLE_TAB_CONTENT_TEST_ID } from './test_ids';
+import { TABLE_TAB_CONTENT_TEST_ID } from './test_ids';
import { TableTab } from './table_tab';
import { TestProviders } from '../../../common/mock';
@@ -40,64 +40,4 @@ describe('', () => {
expect(getByTestId(TABLE_TAB_CONTENT_TEST_ID)).toBeInTheDocument();
});
-
- it('should render error message on null browserFields', () => {
- const contextValue = {
- eventId: 'some_Id',
- browserFields: null,
- dataFormattedForFieldBrowser: [],
- } as unknown as RightPanelContext;
-
- const { getByTestId, getByText } = render(
-
-
-
- );
-
- expect(getByTestId(TABLE_TAB_ERROR_TEST_ID)).toBeInTheDocument();
- expect(getByText('Unable to display document information')).toBeInTheDocument();
- expect(
- getByText('There was an error displaying the document fields and values')
- ).toBeInTheDocument();
- });
-
- it('should render error message on null dataFormattedForFieldBrowser', () => {
- const contextValue = {
- eventId: 'some_Id',
- browserFields: {},
- dataFormattedForFieldBrowser: null,
- } as unknown as RightPanelContext;
-
- const { getByTestId, getByText } = render(
-
-
-
- );
-
- expect(getByTestId(TABLE_TAB_ERROR_TEST_ID)).toBeInTheDocument();
- expect(getByText('Unable to display document information')).toBeInTheDocument();
- expect(
- getByText('There was an error displaying the document fields and values')
- ).toBeInTheDocument();
- });
-
- it('should render error message on null eventId', () => {
- const contextValue = {
- eventId: null,
- browserFields: {},
- dataFormattedForFieldBrowser: [],
- } as unknown as RightPanelContext;
-
- const { getByTestId, getByText } = render(
-
-
-
- );
-
- expect(getByTestId(TABLE_TAB_ERROR_TEST_ID)).toBeInTheDocument();
- expect(getByText('Unable to display document information')).toBeInTheDocument();
- expect(
- getByText('There was an error displaying the document fields and values')
- ).toBeInTheDocument();
- });
});
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
index 7f3d0f45d63af..4f0fac3097679 100644
--- 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
@@ -7,13 +7,9 @@
import type { FC } from 'react';
import React, { memo } from 'react';
-import { EuiEmptyPrompt } from '@elastic/eui';
-import { DOCUMENT_ERROR_DETAILS, DOCUMENT_ERROR_TITLE } from './translations';
-import { ERROR_TITLE, ERROR_MESSAGE } from '../../shared/translations';
import { TimelineTabs } from '../../../../common/types';
import { EventFieldsBrowser } from '../../../common/components/event_details/event_fields_browser';
import { useRightPanelContext } from '../context';
-import { TABLE_TAB_ERROR_TEST_ID } from './test_ids';
/**
* Table view displayed in the document details expandable flyout right section
@@ -21,18 +17,6 @@ import { TABLE_TAB_ERROR_TEST_ID } from './test_ids';
export const TableTab: FC = memo(() => {
const { browserFields, dataFormattedForFieldBrowser, eventId } = useRightPanelContext();
- if (!browserFields || !eventId || !dataFormattedForFieldBrowser) {
- return (
- {ERROR_TITLE(DOCUMENT_ERROR_TITLE)}}
- body={{ERROR_MESSAGE(DOCUMENT_ERROR_DETAILS)}
}
- data-test-subj={TABLE_TAB_ERROR_TEST_ID}
- />
- );
- }
-
return (
', () => {
+ it('should render error title and body', () => {
+ const { getByTestId } = render();
+ expect(getByTestId(FLYOUT_ERROR_TEST_ID)).toBeInTheDocument();
+ expect(getByTestId(FLYOUT_ERROR_TEST_ID)).toHaveTextContent(ERROR_TITLE(FLYOUT_ERROR));
+ expect(getByTestId(FLYOUT_ERROR_TEST_ID)).toHaveTextContent(ERROR_MESSAGE(FLYOUT_ERROR));
+ });
+});
diff --git a/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_error.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_error.tsx
new file mode 100644
index 0000000000000..700ba9850b75d
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_error.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 { EuiEmptyPrompt, EuiFlexItem } from '@elastic/eui';
+import { ERROR_MESSAGE, ERROR_TITLE, FLYOUT_ERROR } from '../translations';
+import { FLYOUT_ERROR_TEST_ID } from '../test_ids';
+
+/**
+ * Use this when you need to show an error state in the flyout
+ */
+export const FlyoutError: React.VFC = () => (
+
+ {ERROR_TITLE(FLYOUT_ERROR)}}
+ body={{ERROR_MESSAGE(FLYOUT_ERROR)}
}
+ data-test-subj={FLYOUT_ERROR_TEST_ID}
+ />
+
+);
+
+FlyoutError.displayName = 'FlyoutError';
diff --git a/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_loading.test.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_loading.test.tsx
new file mode 100644
index 0000000000000..e7889d30526c5
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_loading.test.tsx
@@ -0,0 +1,18 @@
+/*
+ * 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 { FLYOUT_LOADING_TEST_ID } from '../test_ids';
+import { FlyoutLoading } from './flyout_loading';
+
+describe('', () => {
+ it('should render loading', () => {
+ const { getByTestId } = render();
+ expect(getByTestId(FLYOUT_LOADING_TEST_ID)).toBeInTheDocument();
+ });
+});
diff --git a/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_loading.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_loading.tsx
new file mode 100644
index 0000000000000..e1186c6257efd
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_loading.tsx
@@ -0,0 +1,27 @@
+/*
+ * 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 { EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui';
+import { css } from '@emotion/react';
+import { FLYOUT_LOADING_TEST_ID } from '../test_ids';
+
+/**
+ * Use this when you need to show a loading state in the flyout
+ */
+export const FlyoutLoading: React.VFC = () => (
+
+
+
+);
+
+FlyoutLoading.displayName = 'FlyoutLoading';
diff --git a/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_event_details.test.tsx b/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_event_details.test.tsx
new file mode 100644
index 0000000000000..0a092271e1ddd
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_event_details.test.tsx
@@ -0,0 +1,51 @@
+/*
+ * 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 { RenderHookResult } from '@testing-library/react-hooks';
+import { renderHook } from '@testing-library/react-hooks';
+import type { UseEventDetailsParams, UseEventDetailsResult } from './use_event_details';
+import { useEventDetails } from './use_event_details';
+import { useSpaceId } from '../../../common/hooks/use_space_id';
+import { useRouteSpy } from '../../../common/utils/route/use_route_spy';
+import { useSourcererDataView } from '../../../common/containers/sourcerer';
+import { useTimelineEventsDetails } from '../../../timelines/containers/details';
+import { useGetFieldsData } from '../../../common/hooks/use_get_fields_data';
+
+jest.mock('../../../common/hooks/use_space_id');
+jest.mock('../../../common/utils/route/use_route_spy');
+jest.mock('../../../common/containers/sourcerer');
+jest.mock('../../../timelines/containers/details');
+jest.mock('../../../common/hooks/use_get_fields_data');
+
+const eventId = 'eventId';
+const indexName = 'indexName';
+
+describe('useEventDetails', () => {
+ let hookResult: RenderHookResult;
+
+ it('should return all properties', () => {
+ jest.mocked(useSpaceId).mockReturnValue('default');
+ (useRouteSpy as jest.Mock).mockReturnValue([{ pageName: 'alerts' }]);
+ (useSourcererDataView as jest.Mock).mockReturnValue({
+ browserFields: {},
+ indexPattern: {},
+ });
+ (useTimelineEventsDetails as jest.Mock).mockReturnValue([false, [], {}, {}, jest.fn()]);
+ jest.mocked(useGetFieldsData).mockReturnValue((field: string) => field);
+
+ hookResult = renderHook(() => useEventDetails({ eventId, indexName }));
+
+ expect(hookResult.result.current.browserFields).toEqual({});
+ expect(hookResult.result.current.dataAsNestedObject).toEqual({});
+ expect(hookResult.result.current.dataFormattedForFieldBrowser).toEqual([]);
+ expect(hookResult.result.current.getFieldsData('test')).toEqual('test');
+ expect(hookResult.result.current.indexPattern).toEqual({});
+ expect(hookResult.result.current.loading).toEqual(false);
+ expect(hookResult.result.current.refetchFlyoutData()).toEqual(undefined);
+ expect(hookResult.result.current.searchHit).toEqual({});
+ });
+});
diff --git a/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_event_details.ts b/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_event_details.ts
new file mode 100644
index 0000000000000..91e371cd3b0b6
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_event_details.ts
@@ -0,0 +1,104 @@
+/*
+ * 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 { BrowserFields, TimelineEventsDetailsItem } from '@kbn/timelines-plugin/common';
+import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs';
+import { SecurityPageName } from '@kbn/security-solution-navigation';
+import type { DataViewBase } from '@kbn/es-query';
+import { useSpaceId } from '../../../common/hooks/use_space_id';
+import { getAlertIndexAlias } from '../../../timelines/components/side_panel/event_details/helpers';
+import { useRouteSpy } from '../../../common/utils/route/use_route_spy';
+import { SourcererScopeName } from '../../../common/store/sourcerer/model';
+import { useSourcererDataView } from '../../../common/containers/sourcerer';
+import { useTimelineEventsDetails } from '../../../timelines/containers/details';
+import { useGetFieldsData } from '../../../common/hooks/use_get_fields_data';
+import type { SearchHit } from '../../../../common/search_strategy';
+import type { GetFieldsData } from '../../../common/hooks/use_get_fields_data';
+
+export interface UseEventDetailsParams {
+ /**
+ * Id of the document
+ */
+ eventId: string | undefined;
+ /**
+ * Name of the index used in the parent's page
+ */
+ indexName: string | undefined;
+}
+
+export interface UseEventDetailsResult {
+ /**
+ * An object containing fields by type
+ */
+ browserFields: BrowserFields;
+ /**
+ * An object with top level fields from the ECS object
+ */
+ dataAsNestedObject: Ecs | null;
+ /**
+ * An array of field objects with category and value
+ */
+ dataFormattedForFieldBrowser: TimelineEventsDetailsItem[] | null;
+ /**
+ * Retrieves searchHit values for the provided field
+ */
+ getFieldsData: GetFieldsData;
+ /**
+ * Index pattern for rule details
+ */
+ indexPattern: DataViewBase;
+ /**
+ * Whether the data is loading
+ */
+ loading: boolean;
+ /**
+ * Promise to trigger a data refresh
+ */
+ refetchFlyoutData: () => Promise;
+ /**
+ * The actual raw document object
+ */
+ searchHit: SearchHit | undefined;
+}
+
+/**
+ * Hook to retrieve event details for alert details flyout contexts
+ */
+export const useEventDetails = ({
+ eventId,
+ indexName,
+}: UseEventDetailsParams): UseEventDetailsResult => {
+ const currentSpaceId = useSpaceId();
+ // TODO Replace getAlertIndexAlias way to retrieving the eventIndex with the GET /_alias
+ // https://github.com/elastic/kibana/issues/113063
+ const eventIndex = indexName ? getAlertIndexAlias(indexName, currentSpaceId) ?? indexName : '';
+ const [{ pageName }] = useRouteSpy();
+ const sourcererScope =
+ pageName === SecurityPageName.detections
+ ? SourcererScopeName.detections
+ : SourcererScopeName.default;
+ const sourcererDataView = useSourcererDataView(sourcererScope);
+ const [loading, dataFormattedForFieldBrowser, searchHit, dataAsNestedObject, refetchFlyoutData] =
+ useTimelineEventsDetails({
+ indexName: eventIndex,
+ eventId: eventId ?? '',
+ runtimeMappings: sourcererDataView.runtimeMappings,
+ skip: !eventId,
+ });
+ const getFieldsData = useGetFieldsData(searchHit?.fields);
+
+ return {
+ browserFields: sourcererDataView.browserFields,
+ dataAsNestedObject,
+ dataFormattedForFieldBrowser,
+ getFieldsData,
+ indexPattern: sourcererDataView.indexPattern,
+ loading,
+ refetchFlyoutData,
+ searchHit,
+ };
+};
diff --git a/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_highlighted_fields.ts b/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_highlighted_fields.ts
index ab7de04a021ce..f9fa147c8395a 100644
--- a/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_highlighted_fields.ts
+++ b/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_highlighted_fields.ts
@@ -18,7 +18,7 @@ export interface UseHighlightedFieldsParams {
/**
* An array of field objects with category and value
*/
- dataFormattedForFieldBrowser: TimelineEventsDetailsItem[] | null;
+ dataFormattedForFieldBrowser: TimelineEventsDetailsItem[];
/**
* An array of fields user has selected to highlight, defined on rule
*/
@@ -45,8 +45,6 @@ export const useHighlightedFields = ({
dataFormattedForFieldBrowser,
investigationFields,
}: UseHighlightedFieldsParams): UseHighlightedFieldsResult => {
- if (!dataFormattedForFieldBrowser) return {};
-
const eventCategories = getEventCategoriesFromData(dataFormattedForFieldBrowser);
const eventCodeField = find(
diff --git a/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_investigation_guide.ts b/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_investigation_guide.ts
index 66d2183ad64fe..cc546a43241d2 100644
--- a/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_investigation_guide.ts
+++ b/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_investigation_guide.ts
@@ -14,7 +14,7 @@ export interface UseInvestigationGuideParams {
/**
* An array of field objects with category and value
*/
- dataFormattedForFieldBrowser: TimelineEventsDetailsItem[] | null;
+ dataFormattedForFieldBrowser: TimelineEventsDetailsItem[];
}
export interface UseInvestigationGuideResult {
diff --git a/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_prevalence.ts b/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_prevalence.ts
index a7b110f92e740..a78295139d724 100644
--- a/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_prevalence.ts
+++ b/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_prevalence.ts
@@ -38,7 +38,7 @@ export interface UsePrevalenceParams {
/**
* An array of field objects with category and value
*/
- dataFormattedForFieldBrowser: TimelineEventsDetailsItem[] | null;
+ dataFormattedForFieldBrowser: TimelineEventsDetailsItem[];
/**
* User defined fields to highlight (defined on the rule)
*/
diff --git a/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_show_related_alerts_by_ancestry.ts b/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_show_related_alerts_by_ancestry.ts
index 85fde8e6732b3..fe2ccb518abe0 100644
--- a/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_show_related_alerts_by_ancestry.ts
+++ b/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_show_related_alerts_by_ancestry.ts
@@ -24,11 +24,11 @@ export interface UseShowRelatedAlertsByAncestryParams {
/**
* An object with top level fields from the ECS object
*/
- dataAsNestedObject: Ecs | null;
+ dataAsNestedObject: Ecs;
/**
* An array of field objects with category and value
*/
- dataFormattedForFieldBrowser: TimelineEventsDetailsItem[] | null;
+ dataFormattedForFieldBrowser: TimelineEventsDetailsItem[];
}
export interface UseShowRelatedAlertsByAncestryResult {
@@ -57,9 +57,7 @@ export const useShowRelatedAlertsByAncestry = ({
const isRelatedAlertsByProcessAncestryEnabled = useIsExperimentalFeatureEnabled(
'insightsRelatedAlertsByProcessAncestry'
);
- const hasProcessEntityInfo = isInvestigateInResolverActionEnabled(
- dataAsNestedObject || undefined
- );
+ const hasProcessEntityInfo = isInvestigateInResolverActionEnabled(dataAsNestedObject);
const originalDocumentId = getField(getFieldsData(ANCESTOR_ID));
diff --git a/x-pack/plugins/security_solution/public/flyout/shared/test_ids.ts b/x-pack/plugins/security_solution/public/flyout/shared/test_ids.ts
new file mode 100644
index 0000000000000..f49c1a34173b2
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/flyout/shared/test_ids.ts
@@ -0,0 +1,13 @@
+/*
+ * 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.
+ */
+
+/* Visualization tab */
+
+const PREFIX = 'securitySolutionDocumentDetailsFlyout' as const;
+
+export const FLYOUT_ERROR_TEST_ID = `${PREFIX}Error` as const;
+export const FLYOUT_LOADING_TEST_ID = `${PREFIX}Loading` as const;
diff --git a/x-pack/plugins/security_solution/public/flyout/shared/translations.ts b/x-pack/plugins/security_solution/public/flyout/shared/translations.ts
index b58e106cb26b1..5ecf772c5c0c0 100644
--- a/x-pack/plugins/security_solution/public/flyout/shared/translations.ts
+++ b/x-pack/plugins/security_solution/public/flyout/shared/translations.ts
@@ -7,6 +7,10 @@
import { i18n } from '@kbn/i18n';
+export const FLYOUT_ERROR = i18n.translate('xpack.securitySolution.flyout.documentDetails.error', {
+ defaultMessage: 'data',
+});
+
export const ERROR_TITLE = (title: string) =>
i18n.translate('xpack.securitySolution.flyout.errorTitle', {
values: { title },
diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json
index ad1f9d581caa0..a1cbafb3b2f92 100644
--- a/x-pack/plugins/translations/translations/fr-FR.json
+++ b/x-pack/plugins/translations/translations/fr-FR.json
@@ -33165,7 +33165,6 @@
"xpack.securitySolution.flyout.entities.relatedHostsTitle": "Hôtes associés",
"xpack.securitySolution.flyout.entities.relatedUsersTitle": "Utilisateurs associés",
"xpack.securitySolution.flyout.entities.usersInfoTitle": "Informations sur l’utilisateur",
- "xpack.securitySolution.flyout.prevalenceErrorMessage": "prévalence",
"xpack.securitySolution.flyout.prevalenceTableAlertCountColumnTitle": "Nombre d'alertes",
"xpack.securitySolution.flyout.prevalenceTableDocCountColumnTitle": "Compte du document",
"xpack.securitySolution.flyout.response.title": "Réponses",
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index feb4f26c63bea..e275190a0f41e 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -33164,7 +33164,6 @@
"xpack.securitySolution.flyout.entities.relatedHostsTitle": "関連するホスト",
"xpack.securitySolution.flyout.entities.relatedUsersTitle": "関連するユーザー",
"xpack.securitySolution.flyout.entities.usersInfoTitle": "ユーザー情報",
- "xpack.securitySolution.flyout.prevalenceErrorMessage": "発生率",
"xpack.securitySolution.flyout.prevalenceTableAlertCountColumnTitle": "アラート件数",
"xpack.securitySolution.flyout.prevalenceTableDocCountColumnTitle": "ドキュメントカウント",
"xpack.securitySolution.flyout.response.title": "対応",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index bce73e0732ed3..46a78f100abbe 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -33160,7 +33160,6 @@
"xpack.securitySolution.flyout.entities.relatedHostsTitle": "相关主机",
"xpack.securitySolution.flyout.entities.relatedUsersTitle": "相关用户",
"xpack.securitySolution.flyout.entities.usersInfoTitle": "用户信息",
- "xpack.securitySolution.flyout.prevalenceErrorMessage": "普及率",
"xpack.securitySolution.flyout.prevalenceTableAlertCountColumnTitle": "告警计数",
"xpack.securitySolution.flyout.prevalenceTableDocCountColumnTitle": "文档计数",
"xpack.securitySolution.flyout.response.title": "响应",
diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/discover/cell_actions.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/discover/cell_actions.cy.ts
index 468b3cdf2f6fc..4360df7bf6798 100644
--- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/discover/cell_actions.cy.ts
+++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/discover/cell_actions.cy.ts
@@ -27,7 +27,7 @@ describe(
`Discover Datagrid Cell Actions`,
{
env: { ftrConfig: { enableExperimental: ['discoverInTimeline'] } },
- tags: ['@ess', '@serverless', '@brokenInServerless'],
+ tags: ['@serverless', '@brokenInServerless'],
},
() => {
beforeEach(() => {