[CTI] ensures isThreatIntelModuleEnabled query for Overview page is made only once (#104523)
This commit is contained in:
parent
de9ba92340
commit
efa0476192
|
@ -6,12 +6,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ThreatIntelLinkPanelProps } from './index';
|
import { ThreatIntelLinkPanelProps } from '.';
|
||||||
import { useCtiEventCounts } from '../../containers/overview_cti_links/use_cti_event_counts';
|
import { useCtiEventCounts } from '../../containers/overview_cti_links/use_cti_event_counts';
|
||||||
import { CtiNoEvents } from './cti_no_events';
|
import { CtiNoEvents } from './cti_no_events';
|
||||||
import { CtiWithEvents } from './cti_with_events';
|
import { CtiWithEvents } from './cti_with_events';
|
||||||
|
|
||||||
export const CtiEnabledModuleComponent: React.FC<ThreatIntelLinkPanelProps> = (props) => {
|
export type CtiEnabledModuleProps = Omit<ThreatIntelLinkPanelProps, 'isThreatIntelModuleEnabled'>;
|
||||||
|
|
||||||
|
export const CtiEnabledModuleComponent: React.FC<CtiEnabledModuleProps> = (props) => {
|
||||||
const { eventCountsByDataset, totalCount } = useCtiEventCounts(props);
|
const { eventCountsByDataset, totalCount } = useCtiEventCounts(props);
|
||||||
const { to, from } = props;
|
const { to, from } = props;
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ const warning = (
|
||||||
|
|
||||||
export const CtiNoEventsComponent = ({ to, from }: { to: string; from: string }) => {
|
export const CtiNoEventsComponent = ({ to, from }: { to: string; from: string }) => {
|
||||||
const { buttonHref, listItems, isDashboardPluginDisabled } = useCtiDashboardLinks(
|
const { buttonHref, listItems, isDashboardPluginDisabled } = useCtiDashboardLinks(
|
||||||
{ ...emptyEventCountsByDataset },
|
emptyEventCountsByDataset,
|
||||||
to,
|
to,
|
||||||
from
|
from
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { isEqual } from 'lodash';
|
||||||
import { useCtiDashboardLinks } from '../../containers/overview_cti_links';
|
import { useCtiDashboardLinks } from '../../containers/overview_cti_links';
|
||||||
import { ThreatIntelPanelView } from './threat_intel_panel_view';
|
import { ThreatIntelPanelView } from './threat_intel_panel_view';
|
||||||
|
|
||||||
|
@ -38,4 +39,11 @@ export const CtiWithEventsComponent = ({
|
||||||
|
|
||||||
CtiWithEventsComponent.displayName = 'CtiWithEvents';
|
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)
|
||||||
|
);
|
||||||
|
|
|
@ -20,14 +20,9 @@ import {
|
||||||
SUB_PLUGINS_REDUCER,
|
SUB_PLUGINS_REDUCER,
|
||||||
} from '../../../common/mock';
|
} from '../../../common/mock';
|
||||||
import { mockTheme, mockProps } from './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('../../../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', () => {
|
describe('ThreatIntelLinkPanel', () => {
|
||||||
const state: State = mockGlobalState;
|
const state: State = mockGlobalState;
|
||||||
|
|
||||||
|
@ -44,7 +39,7 @@ describe('ThreatIntelLinkPanel', () => {
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<I18nProvider>
|
<I18nProvider>
|
||||||
<ThemeProvider theme={mockTheme}>
|
<ThemeProvider theme={mockTheme}>
|
||||||
<ThreatIntelLinkPanel {...mockProps} />
|
<ThreatIntelLinkPanel {...mockProps} isThreatIntelModuleEnabled={true} />
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</I18nProvider>
|
</I18nProvider>
|
||||||
</Provider>
|
</Provider>
|
||||||
|
@ -54,12 +49,11 @@ describe('ThreatIntelLinkPanel', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders CtiDisabledModule when Threat Intel module is disabled', () => {
|
it('renders CtiDisabledModule when Threat Intel module is disabled', () => {
|
||||||
useIsThreatIntelModuleEnabledMock.mockReturnValueOnce(false);
|
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<I18nProvider>
|
<I18nProvider>
|
||||||
<ThemeProvider theme={mockTheme}>
|
<ThemeProvider theme={mockTheme}>
|
||||||
<ThreatIntelLinkPanel {...mockProps} />
|
<ThreatIntelLinkPanel {...mockProps} isThreatIntelModuleEnabled={false} />
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</I18nProvider>
|
</I18nProvider>
|
||||||
</Provider>
|
</Provider>
|
||||||
|
@ -69,12 +63,11 @@ describe('ThreatIntelLinkPanel', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders null while Threat Intel module state is loading', () => {
|
it('renders null while Threat Intel module state is loading', () => {
|
||||||
useIsThreatIntelModuleEnabledMock.mockReturnValueOnce(undefined);
|
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<I18nProvider>
|
<I18nProvider>
|
||||||
<ThemeProvider theme={mockTheme}>
|
<ThemeProvider theme={mockTheme}>
|
||||||
<ThreatIntelLinkPanel {...mockProps} />
|
<ThreatIntelLinkPanel {...mockProps} isThreatIntelModuleEnabled={undefined} />
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</I18nProvider>
|
</I18nProvider>
|
||||||
</Provider>
|
</Provider>
|
||||||
|
|
|
@ -8,19 +8,18 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { GlobalTimeArgs } from '../../../common/containers/use_global_time';
|
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 { CtiEnabledModule } from './cti_enabled_module';
|
||||||
import { CtiDisabledModule } from './cti_disabled_module';
|
import { CtiDisabledModule } from './cti_disabled_module';
|
||||||
|
|
||||||
export type ThreatIntelLinkPanelProps = Pick<
|
export type ThreatIntelLinkPanelProps = Pick<
|
||||||
GlobalTimeArgs,
|
GlobalTimeArgs,
|
||||||
'from' | 'to' | 'deleteQuery' | 'setQuery'
|
'from' | 'to' | 'deleteQuery' | 'setQuery'
|
||||||
>;
|
> & {
|
||||||
|
isThreatIntelModuleEnabled: boolean | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
const ThreatIntelLinkPanelComponent: React.FC<ThreatIntelLinkPanelProps> = (props) => {
|
const ThreatIntelLinkPanelComponent: React.FC<ThreatIntelLinkPanelProps> = (props) => {
|
||||||
const isThreatIntelModuleEnabled = useIsThreatIntelModuleEnabled();
|
switch (props.isThreatIntelModuleEnabled) {
|
||||||
|
|
||||||
switch (isThreatIntelModuleEnabled) {
|
|
||||||
case true:
|
case true:
|
||||||
return <CtiEnabledModule {...props} data-test-subj="cti-enabled-module" />;
|
return <CtiEnabledModule {...props} data-test-subj="cti-enabled-module" />;
|
||||||
case false:
|
case false:
|
||||||
|
|
|
@ -6,19 +6,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useEffect, useState, useMemo } from 'react';
|
import { useEffect, useState, useMemo } from 'react';
|
||||||
import { ThreatIntelLinkPanelProps } from '../../components/overview_cti_links';
|
|
||||||
import { useRequestEventCounts } from './use_request_event_counts';
|
import { useRequestEventCounts } from './use_request_event_counts';
|
||||||
import { emptyEventCountsByDataset } from './helpers';
|
import { emptyEventCountsByDataset } from './helpers';
|
||||||
|
import { CtiEnabledModuleProps } from '../../components/overview_cti_links/cti_enabled_module';
|
||||||
|
|
||||||
export const ID = 'ctiEventCountQuery';
|
export const ID = 'ctiEventCountQuery';
|
||||||
const PREFIX = 'threatintel.';
|
const PREFIX = 'threatintel.';
|
||||||
|
|
||||||
export const useCtiEventCounts = ({
|
export const useCtiEventCounts = ({ deleteQuery, from, setQuery, to }: CtiEnabledModuleProps) => {
|
||||||
deleteQuery,
|
|
||||||
from,
|
|
||||||
setQuery,
|
|
||||||
to,
|
|
||||||
}: ThreatIntelLinkPanelProps) => {
|
|
||||||
const [isInitialLoading, setIsInitialLoading] = useState(true);
|
const [isInitialLoading, setIsInitialLoading] = useState(true);
|
||||||
|
|
||||||
const [loading, { data, inspect, totalCount, refetch }] = useRequestEventCounts(to, from);
|
const [loading, { data, inspect, totalCount, refetch }] = useRequestEventCounts(to, from);
|
||||||
|
|
|
@ -87,6 +87,7 @@ describe('Overview', () => {
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('rendering', () => {
|
describe('rendering', () => {
|
||||||
test('it DOES NOT render the Getting started text when an index is available', () => {
|
test('it DOES NOT render the Getting started text when an index is available', () => {
|
||||||
mockUseSourcererScope.mockReturnValue({
|
mockUseSourcererScope.mockReturnValue({
|
||||||
|
@ -277,4 +278,18 @@ describe('Overview', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Threat Intel Dashboard Links', () => {
|
||||||
|
it('invokes useIsThreatIntelModuleEnabled hook only once', () => {
|
||||||
|
useIsThreatIntelModuleEnabledMock.mockClear();
|
||||||
|
mount(
|
||||||
|
<TestProviders>
|
||||||
|
<MemoryRouter>
|
||||||
|
<Overview />
|
||||||
|
</MemoryRouter>
|
||||||
|
</TestProviders>
|
||||||
|
);
|
||||||
|
expect(useIsThreatIntelModuleEnabledMock).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,6 +33,7 @@ import { Sourcerer } from '../../common/components/sourcerer';
|
||||||
import { SourcererScopeName } from '../../common/store/sourcerer/model';
|
import { SourcererScopeName } from '../../common/store/sourcerer/model';
|
||||||
import { useDeepEqualSelector } from '../../common/hooks/use_selector';
|
import { useDeepEqualSelector } from '../../common/hooks/use_selector';
|
||||||
import { ThreatIntelLinkPanel } from '../components/overview_cti_links';
|
import { ThreatIntelLinkPanel } from '../components/overview_cti_links';
|
||||||
|
import { useIsThreatIntelModuleEnabled } from '../containers/overview_cti_links/use_is_threat_intel_module_enabled';
|
||||||
|
|
||||||
const SidebarFlexItem = styled(EuiFlexItem)`
|
const SidebarFlexItem = styled(EuiFlexItem)`
|
||||||
margin-right: 24px;
|
margin-right: 24px;
|
||||||
|
@ -70,6 +71,8 @@ const OverviewComponent = () => {
|
||||||
addMessage('management', 'dismissEndpointNotice');
|
addMessage('management', 'dismissEndpointNotice');
|
||||||
}, [addMessage]);
|
}, [addMessage]);
|
||||||
const { allEnabled: isIngestEnabled } = useIngestEnabledCheck();
|
const { allEnabled: isIngestEnabled } = useIngestEnabledCheck();
|
||||||
|
const isThreatIntelModuleEnabled = useIsThreatIntelModuleEnabled();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{indicesExist ? (
|
{indicesExist ? (
|
||||||
|
@ -143,6 +146,7 @@ const OverviewComponent = () => {
|
||||||
</EuiFlexItem>
|
</EuiFlexItem>
|
||||||
<EuiFlexItem grow={false}>
|
<EuiFlexItem grow={false}>
|
||||||
<ThreatIntelLinkPanel
|
<ThreatIntelLinkPanel
|
||||||
|
isThreatIntelModuleEnabled={isThreatIntelModuleEnabled}
|
||||||
deleteQuery={deleteQuery}
|
deleteQuery={deleteQuery}
|
||||||
from={from}
|
from={from}
|
||||||
setQuery={setQuery}
|
setQuery={setQuery}
|
||||||
|
|
Loading…
Reference in a new issue