diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/shared/components/flyout_history_row.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/shared/components/flyout_history_row.test.tsx index 471cbae65427b..5ba5301e56d38 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/shared/components/flyout_history_row.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/shared/components/flyout_history_row.test.tsx @@ -22,6 +22,7 @@ import { } from '@kbn/expandable-flyout'; import { useRuleDetails } from '../../rule_details/hooks/use_rule_details'; import { useBasicDataFromDetailsData } from '../../document_details/shared/hooks/use_basic_data_from_details_data'; +import { useEventDetails } from '../../document_details/shared/hooks/use_event_details'; import { DocumentDetailsRightPanelKey } from '../../document_details/shared/constants/panel_keys'; import { RulePanelKey } from '../../rule_details/right'; import { NetworkPanelKey } from '../../network_details'; @@ -32,6 +33,7 @@ import { NETWORK_HISTORY_ROW_TEST_ID, RULE_HISTORY_ROW_TEST_ID, USER_HISTORY_ROW_TEST_ID, + HISTORY_ROW_LOADING_TEST_ID, } from './test_ids'; import { HostPanelKey, UserPanelKey } from '../../entity_details/shared/constants'; @@ -45,6 +47,7 @@ jest.mock('@kbn/expandable-flyout', () => ({ jest.mock('../../../detection_engine/rule_management/logic/use_rule_with_fallback'); jest.mock('../../document_details/shared/hooks/use_basic_data_from_details_data'); jest.mock('../../rule_details/hooks/use_rule_details'); +jest.mock('../../document_details/shared/hooks/use_event_details'); const flyoutContextValue = { openFlyout: jest.fn(), @@ -112,6 +115,12 @@ describe('FlyoutHistoryRow', () => { jest.mocked(useRuleDetails).mockReturnValue({ ...mockedRuleResponse, rule: { name: 'rule name' } as RuleResponse, + loading: false, + }); + (useEventDetails as jest.Mock).mockReturnValue({ + dataFormattedForFieldBrowser: {}, + getFieldsData: jest.fn(), + loading: false, }); (useBasicDataFromDetailsData as jest.Mock).mockReturnValue({ isAlert: false }); }); @@ -182,6 +191,11 @@ describe('FlyoutHistoryRow', () => { describe('DocumentDetailsHistoryRow', () => { beforeEach(() => { jest.mocked(useExpandableFlyoutApi).mockReturnValue(flyoutContextValue); + (useEventDetails as jest.Mock).mockReturnValue({ + dataFormattedForFieldBrowser: {}, + getFieldsData: jest.fn(), + loading: false, + }); }); it('should render alert title when isAlert is true and rule name is defined', () => { @@ -291,6 +305,22 @@ describe('GenericHistoryRow', () => { fireEvent.click(getByTestId(`${0}-${GENERIC_HISTORY_ROW_TEST_ID}`)); }); + it('should render empty context menu item when isLoading is true', () => { + const { getByTestId } = render( + + + + ); + expect(getByTestId(HISTORY_ROW_LOADING_TEST_ID)).toBeInTheDocument(); + }); + it('should open the flyout when clicked', () => { const { getByTestId } = render( diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/shared/components/flyout_history_row.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/shared/components/flyout_history_row.tsx index ed36c14326555..92ac1b6821781 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/shared/components/flyout_history_row.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/shared/components/flyout_history_row.tsx @@ -14,6 +14,7 @@ import { EuiFlexItem, type EuiIconProps, useEuiTheme, + EuiSkeletonText, } from '@elastic/eui'; import type { FlyoutPanelHistory } from '@kbn/expandable-flyout'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; @@ -32,6 +33,7 @@ import { NETWORK_HISTORY_ROW_TEST_ID, RULE_HISTORY_ROW_TEST_ID, USER_HISTORY_ROW_TEST_ID, + HISTORY_ROW_LOADING_TEST_ID, } from './test_ids'; import { HostPanelKey, UserPanelKey } from '../../entity_details/shared/constants'; @@ -99,7 +101,7 @@ export const FlyoutHistoryRow: FC = memo(({ item, index } * Row item for a document details */ export const DocumentDetailsHistoryRow: FC = memo(({ item, index }) => { - const { dataFormattedForFieldBrowser, getFieldsData } = useEventDetails({ + const { dataFormattedForFieldBrowser, getFieldsData, loading } = useEventDetails({ eventId: String(item?.panel?.params?.id), indexName: String(item?.panel?.params?.indexName), }); @@ -122,6 +124,7 @@ export const DocumentDetailsHistoryRow: FC = memo(({ item title={title} icon={isAlert ? 'warning' : 'analyzeEvent'} name={isAlert ? 'Alert' : 'Event'} + isLoading={loading} dataTestSubj={DOCUMENT_DETAILS_HISTORY_ROW_TEST_ID} /> ); @@ -171,7 +174,7 @@ const RowTitle: FC = memo(({ type, value }) => { */ export const RuleHistoryRow: FC = memo(({ item, index }) => { const ruleId = String(item?.panel?.params?.ruleId); - const { rule } = useRuleDetails({ ruleId }); + const { rule, loading } = useRuleDetails({ ruleId }); return ( = memo(({ item, index }) title={rule?.name ?? ''} icon={'indexSettings'} name={'Rule'} + isLoading={loading} dataTestSubj={RULE_HISTORY_ROW_TEST_ID} /> ); @@ -202,6 +206,10 @@ interface GenericHistoryRowProps extends FlyoutHistoryRowProps { * Name to display */ name: string; + /** + * Whether the row is loading + */ + isLoading?: boolean; /** * Data test subject */ @@ -212,13 +220,21 @@ interface GenericHistoryRowProps extends FlyoutHistoryRowProps { * Row item for a generic history row where the title is accessible in flyout params */ export const GenericHistoryRow: FC = memo( - ({ item, index, title, icon, name, dataTestSubj }) => { + ({ item, index, title, icon, name, isLoading, dataTestSubj }) => { const { euiTheme } = useEuiTheme(); const { openFlyout } = useExpandableFlyoutApi(); const onClick = useCallback(() => { openFlyout({ right: item.panel }); }, [openFlyout, item.panel]); + if (isLoading) { + return ( + + + + ); + } + return ( `${dataTestSubj /* History */ export const FLYOUT_HISTORY_TEST_ID = `${PREFIX}History` as const; +export const HISTORY_ROW_LOADING_TEST_ID = `${FLYOUT_HISTORY_TEST_ID}RowLoading` as const; export const FLYOUT_HISTORY_BUTTON_TEST_ID = `${FLYOUT_HISTORY_TEST_ID}Button` as const; export const FLYOUT_HISTORY_CONTEXT_PANEL_TEST_ID = `${FLYOUT_HISTORY_TEST_ID}ContextPanel` as const;