diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_enabled_module.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_enabled_module.tsx index 5f7be2ac2e6b..304e8b99135d 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_enabled_module.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_enabled_module.tsx @@ -6,12 +6,14 @@ */ import React from 'react'; -import { ThreatIntelLinkPanelProps } from './index'; +import { ThreatIntelLinkPanelProps } from '.'; import { useCtiEventCounts } from '../../containers/overview_cti_links/use_cti_event_counts'; import { CtiNoEvents } from './cti_no_events'; import { CtiWithEvents } from './cti_with_events'; -export const CtiEnabledModuleComponent: React.FC = (props) => { +export type CtiEnabledModuleProps = Omit; + +export const CtiEnabledModuleComponent: React.FC = (props) => { const { eventCountsByDataset, totalCount } = useCtiEventCounts(props); const { to, from } = props; diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_no_events.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_no_events.tsx index 3adccb4f4e3f..9792b5044eab 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_no_events.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_no_events.tsx @@ -23,7 +23,7 @@ const warning = ( export const CtiNoEventsComponent = ({ to, from }: { to: string; from: string }) => { const { buttonHref, listItems, isDashboardPluginDisabled } = useCtiDashboardLinks( - { ...emptyEventCountsByDataset }, + emptyEventCountsByDataset, to, from ); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_with_events.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_with_events.tsx index f9640e9a232f..b2f7c7d761d2 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_with_events.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/cti_with_events.tsx @@ -6,6 +6,7 @@ */ import React from 'react'; +import { isEqual } from 'lodash'; import { useCtiDashboardLinks } from '../../containers/overview_cti_links'; import { ThreatIntelPanelView } from './threat_intel_panel_view'; @@ -38,4 +39,11 @@ export const CtiWithEventsComponent = ({ CtiWithEventsComponent.displayName = 'CtiWithEvents'; -export const CtiWithEvents = React.memo(CtiWithEventsComponent); +export const CtiWithEvents = React.memo( + CtiWithEventsComponent, + (prevProps, nextProps) => + prevProps.to === nextProps.to && + prevProps.from === nextProps.from && + prevProps.totalCount === nextProps.totalCount && + isEqual(prevProps.eventCountsByDataset, nextProps.eventCountsByDataset) +); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/index.test.tsx index ca3d0ddde401..56bd7c0c0dd0 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/index.test.tsx @@ -20,14 +20,9 @@ import { SUB_PLUGINS_REDUCER, } from '../../../common/mock'; import { mockTheme, mockProps } from './mock'; -import { useIsThreatIntelModuleEnabled } from '../../containers/overview_cti_links/use_is_threat_intel_module_enabled'; jest.mock('../../../common/lib/kibana'); -jest.mock('../../containers/overview_cti_links/use_is_threat_intel_module_enabled'); -const useIsThreatIntelModuleEnabledMock = useIsThreatIntelModuleEnabled as jest.Mock; -useIsThreatIntelModuleEnabledMock.mockReturnValue(true); - describe('ThreatIntelLinkPanel', () => { const state: State = mockGlobalState; @@ -44,7 +39,7 @@ describe('ThreatIntelLinkPanel', () => { - + @@ -54,12 +49,11 @@ describe('ThreatIntelLinkPanel', () => { }); it('renders CtiDisabledModule when Threat Intel module is disabled', () => { - useIsThreatIntelModuleEnabledMock.mockReturnValueOnce(false); const wrapper = mount( - + @@ -69,12 +63,11 @@ describe('ThreatIntelLinkPanel', () => { }); it('renders null while Threat Intel module state is loading', () => { - useIsThreatIntelModuleEnabledMock.mockReturnValueOnce(undefined); const wrapper = mount( - + diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/index.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/index.tsx index 1ae00face7c8..0c50bbf145b1 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/index.tsx @@ -8,19 +8,18 @@ import React from 'react'; import { GlobalTimeArgs } from '../../../common/containers/use_global_time'; -import { useIsThreatIntelModuleEnabled } from '../../containers/overview_cti_links/use_is_threat_intel_module_enabled'; import { CtiEnabledModule } from './cti_enabled_module'; import { CtiDisabledModule } from './cti_disabled_module'; export type ThreatIntelLinkPanelProps = Pick< GlobalTimeArgs, 'from' | 'to' | 'deleteQuery' | 'setQuery' ->; +> & { + isThreatIntelModuleEnabled: boolean | undefined; +}; const ThreatIntelLinkPanelComponent: React.FC = (props) => { - const isThreatIntelModuleEnabled = useIsThreatIntelModuleEnabled(); - - switch (isThreatIntelModuleEnabled) { + switch (props.isThreatIntelModuleEnabled) { case true: return ; case false: diff --git a/x-pack/plugins/security_solution/public/overview/containers/overview_cti_links/use_cti_event_counts.ts b/x-pack/plugins/security_solution/public/overview/containers/overview_cti_links/use_cti_event_counts.ts index cc06f593a06c..65e79ac6b617 100644 --- a/x-pack/plugins/security_solution/public/overview/containers/overview_cti_links/use_cti_event_counts.ts +++ b/x-pack/plugins/security_solution/public/overview/containers/overview_cti_links/use_cti_event_counts.ts @@ -6,19 +6,14 @@ */ import { useEffect, useState, useMemo } from 'react'; -import { ThreatIntelLinkPanelProps } from '../../components/overview_cti_links'; import { useRequestEventCounts } from './use_request_event_counts'; import { emptyEventCountsByDataset } from './helpers'; +import { CtiEnabledModuleProps } from '../../components/overview_cti_links/cti_enabled_module'; export const ID = 'ctiEventCountQuery'; const PREFIX = 'threatintel.'; -export const useCtiEventCounts = ({ - deleteQuery, - from, - setQuery, - to, -}: ThreatIntelLinkPanelProps) => { +export const useCtiEventCounts = ({ deleteQuery, from, setQuery, to }: CtiEnabledModuleProps) => { const [isInitialLoading, setIsInitialLoading] = useState(true); const [loading, { data, inspect, totalCount, refetch }] = useRequestEventCounts(to, from); diff --git a/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx b/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx index f003e6084b3c..cc8c0bfcf7f6 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx @@ -87,6 +87,7 @@ describe('Overview', () => { }, ]); }); + describe('rendering', () => { test('it DOES NOT render the Getting started text when an index is available', () => { mockUseSourcererScope.mockReturnValue({ @@ -277,4 +278,18 @@ describe('Overview', () => { }); }); }); + + describe('Threat Intel Dashboard Links', () => { + it('invokes useIsThreatIntelModuleEnabled hook only once', () => { + useIsThreatIntelModuleEnabledMock.mockClear(); + mount( + + + + + + ); + expect(useIsThreatIntelModuleEnabledMock).toHaveBeenCalledTimes(1); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/overview/pages/overview.tsx b/x-pack/plugins/security_solution/public/overview/pages/overview.tsx index 3c8612ed6cd9..174141db9bfb 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/overview.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/overview.tsx @@ -33,6 +33,7 @@ import { Sourcerer } from '../../common/components/sourcerer'; import { SourcererScopeName } from '../../common/store/sourcerer/model'; import { useDeepEqualSelector } from '../../common/hooks/use_selector'; import { ThreatIntelLinkPanel } from '../components/overview_cti_links'; +import { useIsThreatIntelModuleEnabled } from '../containers/overview_cti_links/use_is_threat_intel_module_enabled'; const SidebarFlexItem = styled(EuiFlexItem)` margin-right: 24px; @@ -70,6 +71,8 @@ const OverviewComponent = () => { addMessage('management', 'dismissEndpointNotice'); }, [addMessage]); const { allEnabled: isIngestEnabled } = useIngestEnabledCheck(); + const isThreatIntelModuleEnabled = useIsThreatIntelModuleEnabled(); + return ( <> {indicesExist ? ( @@ -143,6 +146,7 @@ const OverviewComponent = () => {