mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Security Solution] expandable flyout - add paywall to prevalence details (#165382)
This commit is contained in:
parent
88c04e5c94
commit
8267c56322
5 changed files with 196 additions and 21 deletions
|
@ -11,11 +11,18 @@ import { LeftPanelContext } from '../context';
|
||||||
import { PrevalenceDetails } from './prevalence_details';
|
import { PrevalenceDetails } from './prevalence_details';
|
||||||
import {
|
import {
|
||||||
PREVALENCE_DETAILS_LOADING_TEST_ID,
|
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_ERROR_TEST_ID,
|
||||||
|
PREVALENCE_DETAILS_TABLE_FIELD_CELL_TEST_ID,
|
||||||
|
PREVALENCE_DETAILS_TABLE_HOST_PREVALENCE_CELL_TEST_ID,
|
||||||
PREVALENCE_DETAILS_TABLE_TEST_ID,
|
PREVALENCE_DETAILS_TABLE_TEST_ID,
|
||||||
|
PREVALENCE_DETAILS_TABLE_USER_PREVALENCE_CELL_TEST_ID,
|
||||||
|
PREVALENCE_DETAILS_TABLE_VALUE_CELL_TEST_ID,
|
||||||
} from './test_ids';
|
} from './test_ids';
|
||||||
import { usePrevalence } from '../../shared/hooks/use_prevalence';
|
import { usePrevalence } from '../../shared/hooks/use_prevalence';
|
||||||
import { TestProviders } from '../../../common/mock';
|
import { TestProviders } from '../../../common/mock';
|
||||||
|
import { licenseService } from '../../../common/hooks/use_license';
|
||||||
|
|
||||||
jest.mock('../../shared/hooks/use_prevalence');
|
jest.mock('../../shared/hooks/use_prevalence');
|
||||||
|
|
||||||
|
@ -27,6 +34,17 @@ jest.mock('react-redux', () => {
|
||||||
useDispatch: () => mockDispatch,
|
useDispatch: () => mockDispatch,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
jest.mock('../../../common/hooks/use_license', () => {
|
||||||
|
const licenseServiceInstance = {
|
||||||
|
isPlatinumPlus: jest.fn(),
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
licenseService: licenseServiceInstance,
|
||||||
|
useLicense: () => {
|
||||||
|
return licenseServiceInstance;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const panelContextValue = {
|
const panelContextValue = {
|
||||||
eventId: 'event id',
|
eventId: 'event id',
|
||||||
|
@ -36,7 +54,13 @@ const panelContextValue = {
|
||||||
} as unknown as LeftPanelContext;
|
} as unknown as LeftPanelContext;
|
||||||
|
|
||||||
describe('PrevalenceDetails', () => {
|
describe('PrevalenceDetails', () => {
|
||||||
it('should render the table', () => {
|
const licenseServiceMock = licenseService as jest.Mocked<typeof licenseService>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
licenseServiceMock.isPlatinumPlus.mockReturnValue(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render the table with all columns if license is platinum', () => {
|
||||||
const field1 = 'field1';
|
const field1 = 'field1';
|
||||||
const field2 = 'field2';
|
const field2 = 'field2';
|
||||||
(usePrevalence as jest.Mock).mockReturnValue({
|
(usePrevalence as jest.Mock).mockReturnValue({
|
||||||
|
@ -62,7 +86,7 @@ describe('PrevalenceDetails', () => {
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const { getByTestId } = render(
|
const { getByTestId, getAllByTestId, queryByTestId } = render(
|
||||||
<TestProviders>
|
<TestProviders>
|
||||||
<LeftPanelContext.Provider value={panelContextValue}>
|
<LeftPanelContext.Provider value={panelContextValue}>
|
||||||
<PrevalenceDetails />
|
<PrevalenceDetails />
|
||||||
|
@ -71,6 +95,74 @@ describe('PrevalenceDetails', () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(getByTestId(PREVALENCE_DETAILS_TABLE_TEST_ID)).toBeInTheDocument();
|
expect(getByTestId(PREVALENCE_DETAILS_TABLE_TEST_ID)).toBeInTheDocument();
|
||||||
|
expect(getAllByTestId(PREVALENCE_DETAILS_TABLE_FIELD_CELL_TEST_ID).length).toBeGreaterThan(1);
|
||||||
|
expect(getAllByTestId(PREVALENCE_DETAILS_TABLE_VALUE_CELL_TEST_ID).length).toBeGreaterThan(1);
|
||||||
|
expect(
|
||||||
|
getAllByTestId(PREVALENCE_DETAILS_TABLE_ALERT_COUNT_CELL_TEST_ID).length
|
||||||
|
).toBeGreaterThan(1);
|
||||||
|
expect(getAllByTestId(PREVALENCE_DETAILS_TABLE_DOC_COUNT_CELL_TEST_ID).length).toBeGreaterThan(
|
||||||
|
1
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
getAllByTestId(PREVALENCE_DETAILS_TABLE_HOST_PREVALENCE_CELL_TEST_ID).length
|
||||||
|
).toBeGreaterThan(1);
|
||||||
|
expect(
|
||||||
|
getAllByTestId(PREVALENCE_DETAILS_TABLE_USER_PREVALENCE_CELL_TEST_ID).length
|
||||||
|
).toBeGreaterThan(1);
|
||||||
|
expect(queryByTestId(`${PREVALENCE_DETAILS_TABLE_TEST_ID}UpSell`)).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render the table with only basic columns if license is not platinum', () => {
|
||||||
|
const field1 = 'field1';
|
||||||
|
const field2 = 'field2';
|
||||||
|
(usePrevalence as jest.Mock).mockReturnValue({
|
||||||
|
loading: false,
|
||||||
|
error: false,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
field: field1,
|
||||||
|
value: 'value1',
|
||||||
|
alertCount: 1,
|
||||||
|
docCount: 1,
|
||||||
|
hostPrevalence: 0.05,
|
||||||
|
userPrevalence: 0.1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: field2,
|
||||||
|
value: 'value2',
|
||||||
|
alertCount: 1,
|
||||||
|
docCount: 1,
|
||||||
|
hostPrevalence: 0.5,
|
||||||
|
userPrevalence: 0.05,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
licenseServiceMock.isPlatinumPlus.mockReturnValue(false);
|
||||||
|
|
||||||
|
const { getByTestId, getAllByTestId } = render(
|
||||||
|
<TestProviders>
|
||||||
|
<LeftPanelContext.Provider value={panelContextValue}>
|
||||||
|
<PrevalenceDetails />
|
||||||
|
</LeftPanelContext.Provider>
|
||||||
|
</TestProviders>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(getByTestId(PREVALENCE_DETAILS_TABLE_TEST_ID)).toBeInTheDocument();
|
||||||
|
expect(getAllByTestId(PREVALENCE_DETAILS_TABLE_FIELD_CELL_TEST_ID).length).toBeGreaterThan(1);
|
||||||
|
expect(getAllByTestId(PREVALENCE_DETAILS_TABLE_VALUE_CELL_TEST_ID).length).toBeGreaterThan(1);
|
||||||
|
expect(
|
||||||
|
getAllByTestId(PREVALENCE_DETAILS_TABLE_ALERT_COUNT_CELL_TEST_ID).length
|
||||||
|
).toBeGreaterThan(1);
|
||||||
|
expect(getAllByTestId(PREVALENCE_DETAILS_TABLE_DOC_COUNT_CELL_TEST_ID).length).toBeGreaterThan(
|
||||||
|
1
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
getAllByTestId(PREVALENCE_DETAILS_TABLE_HOST_PREVALENCE_CELL_TEST_ID).length
|
||||||
|
).toBeGreaterThan(1);
|
||||||
|
expect(
|
||||||
|
getAllByTestId(PREVALENCE_DETAILS_TABLE_USER_PREVALENCE_CELL_TEST_ID).length
|
||||||
|
).toBeGreaterThan(1);
|
||||||
|
expect(getByTestId(`${PREVALENCE_DETAILS_TABLE_TEST_ID}UpSell`)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render loading', () => {
|
it('should render loading', () => {
|
||||||
|
|
|
@ -5,19 +5,25 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState } from 'react';
|
import dateMath from '@elastic/datemath';
|
||||||
|
import React, { useMemo, useState } from 'react';
|
||||||
import type { EuiBasicTableColumn, OnTimeChangeProps } from '@elastic/eui';
|
import type { EuiBasicTableColumn, OnTimeChangeProps } from '@elastic/eui';
|
||||||
import {
|
import {
|
||||||
|
EuiCallOut,
|
||||||
EuiEmptyPrompt,
|
EuiEmptyPrompt,
|
||||||
EuiFlexGroup,
|
EuiFlexGroup,
|
||||||
EuiFlexItem,
|
EuiFlexItem,
|
||||||
EuiInMemoryTable,
|
EuiInMemoryTable,
|
||||||
|
EuiLink,
|
||||||
EuiLoadingSpinner,
|
EuiLoadingSpinner,
|
||||||
EuiPanel,
|
EuiPanel,
|
||||||
EuiSpacer,
|
EuiSpacer,
|
||||||
EuiSuperDatePicker,
|
EuiSuperDatePicker,
|
||||||
|
EuiText,
|
||||||
EuiToolTip,
|
EuiToolTip,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
|
import { FormattedMessage } from '@kbn/i18n-react';
|
||||||
|
import { useLicense } from '../../../common/hooks/use_license';
|
||||||
import { InvestigateInTimelineButton } from '../../../common/components/event_details/table/investigate_in_timeline_button';
|
import { InvestigateInTimelineButton } from '../../../common/components/event_details/table/investigate_in_timeline_button';
|
||||||
import type { PrevalenceData } from '../../shared/hooks/use_prevalence';
|
import type { PrevalenceData } from '../../shared/hooks/use_prevalence';
|
||||||
import { usePrevalence } from '../../shared/hooks/use_prevalence';
|
import { usePrevalence } from '../../shared/hooks/use_prevalence';
|
||||||
|
@ -63,16 +69,31 @@ export const PREVALENCE_TAB_ID = 'prevalence-details';
|
||||||
const DEFAULT_FROM = 'now-30d';
|
const DEFAULT_FROM = 'now-30d';
|
||||||
const DEFAULT_TO = 'now';
|
const DEFAULT_TO = 'now';
|
||||||
|
|
||||||
const columns: Array<EuiBasicTableColumn<PrevalenceData>> = [
|
interface PrevalenceDetailsRow extends PrevalenceData {
|
||||||
|
/**
|
||||||
|
* From datetime selected in the date picker to pass to timeline
|
||||||
|
*/
|
||||||
|
from: string;
|
||||||
|
/**
|
||||||
|
* To datetime selected in the date picker to pass to timeline
|
||||||
|
*/
|
||||||
|
to: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const columns: Array<EuiBasicTableColumn<PrevalenceDetailsRow>> = [
|
||||||
{
|
{
|
||||||
field: 'field',
|
field: 'field',
|
||||||
name: PREVALENCE_TABLE_FIELD_COLUMN_TITLE,
|
name: PREVALENCE_TABLE_FIELD_COLUMN_TITLE,
|
||||||
'data-test-subj': PREVALENCE_DETAILS_TABLE_FIELD_CELL_TEST_ID,
|
'data-test-subj': PREVALENCE_DETAILS_TABLE_FIELD_CELL_TEST_ID,
|
||||||
|
render: (field: string) => <EuiText size="xs">{field}</EuiText>,
|
||||||
|
width: '20%',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'value',
|
field: 'value',
|
||||||
name: PREVALENCE_TABLE_VALUE_COLUMN_TITLE,
|
name: PREVALENCE_TABLE_VALUE_COLUMN_TITLE,
|
||||||
'data-test-subj': PREVALENCE_DETAILS_TABLE_VALUE_CELL_TEST_ID,
|
'data-test-subj': PREVALENCE_DETAILS_TABLE_VALUE_CELL_TEST_ID,
|
||||||
|
render: (value: string) => <EuiText size="xs">{value}</EuiText>,
|
||||||
|
width: '20%',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: (
|
name: (
|
||||||
|
@ -84,7 +105,7 @@ const columns: Array<EuiBasicTableColumn<PrevalenceData>> = [
|
||||||
</EuiToolTip>
|
</EuiToolTip>
|
||||||
),
|
),
|
||||||
'data-test-subj': PREVALENCE_DETAILS_TABLE_ALERT_COUNT_CELL_TEST_ID,
|
'data-test-subj': PREVALENCE_DETAILS_TABLE_ALERT_COUNT_CELL_TEST_ID,
|
||||||
render: (data: PrevalenceData) => {
|
render: (data: PrevalenceDetailsRow) => {
|
||||||
const dataProviders = [
|
const dataProviders = [
|
||||||
getDataProvider(data.field, `timeline-indicator-${data.field}-${data.value}`, data.value),
|
getDataProvider(data.field, `timeline-indicator-${data.field}-${data.value}`, data.value),
|
||||||
];
|
];
|
||||||
|
@ -93,6 +114,7 @@ const columns: Array<EuiBasicTableColumn<PrevalenceData>> = [
|
||||||
asEmptyButton={true}
|
asEmptyButton={true}
|
||||||
dataProviders={dataProviders}
|
dataProviders={dataProviders}
|
||||||
filters={[]}
|
filters={[]}
|
||||||
|
timeRange={{ kind: 'absolute', from: data.from, to: data.to }}
|
||||||
>
|
>
|
||||||
<>{data.alertCount}</>
|
<>{data.alertCount}</>
|
||||||
</InvestigateInTimelineButton>
|
</InvestigateInTimelineButton>
|
||||||
|
@ -112,7 +134,7 @@ const columns: Array<EuiBasicTableColumn<PrevalenceData>> = [
|
||||||
</EuiToolTip>
|
</EuiToolTip>
|
||||||
),
|
),
|
||||||
'data-test-subj': PREVALENCE_DETAILS_TABLE_DOC_COUNT_CELL_TEST_ID,
|
'data-test-subj': PREVALENCE_DETAILS_TABLE_DOC_COUNT_CELL_TEST_ID,
|
||||||
render: (data: PrevalenceData) => {
|
render: (data: PrevalenceDetailsRow) => {
|
||||||
const dataProviders = [
|
const dataProviders = [
|
||||||
{
|
{
|
||||||
...getDataProvider(
|
...getDataProvider(
|
||||||
|
@ -136,6 +158,7 @@ const columns: Array<EuiBasicTableColumn<PrevalenceData>> = [
|
||||||
asEmptyButton={true}
|
asEmptyButton={true}
|
||||||
dataProviders={dataProviders}
|
dataProviders={dataProviders}
|
||||||
filters={[]}
|
filters={[]}
|
||||||
|
timeRange={{ kind: 'absolute', from: data.from, to: data.to }}
|
||||||
keepDataView // changing dataview from only detections to include non-alerts docs
|
keepDataView // changing dataview from only detections to include non-alerts docs
|
||||||
>
|
>
|
||||||
<>{data.docCount}</>
|
<>{data.docCount}</>
|
||||||
|
@ -158,10 +181,7 @@ const columns: Array<EuiBasicTableColumn<PrevalenceData>> = [
|
||||||
),
|
),
|
||||||
'data-test-subj': PREVALENCE_DETAILS_TABLE_HOST_PREVALENCE_CELL_TEST_ID,
|
'data-test-subj': PREVALENCE_DETAILS_TABLE_HOST_PREVALENCE_CELL_TEST_ID,
|
||||||
render: (hostPrevalence: number) => (
|
render: (hostPrevalence: number) => (
|
||||||
<>
|
<EuiText size="xs">{`${Math.round(hostPrevalence * 100)}%`}</EuiText>
|
||||||
{Math.round(hostPrevalence * 100)}
|
|
||||||
{'%'}
|
|
||||||
</>
|
|
||||||
),
|
),
|
||||||
width: '10%',
|
width: '10%',
|
||||||
},
|
},
|
||||||
|
@ -177,10 +197,7 @@ const columns: Array<EuiBasicTableColumn<PrevalenceData>> = [
|
||||||
),
|
),
|
||||||
'data-test-subj': PREVALENCE_DETAILS_TABLE_USER_PREVALENCE_CELL_TEST_ID,
|
'data-test-subj': PREVALENCE_DETAILS_TABLE_USER_PREVALENCE_CELL_TEST_ID,
|
||||||
render: (userPrevalence: number) => (
|
render: (userPrevalence: number) => (
|
||||||
<>
|
<EuiText size="xs">{`${Math.round(userPrevalence * 100)}%`}</EuiText>
|
||||||
{Math.round(userPrevalence * 100)}
|
|
||||||
{'%'}
|
|
||||||
</>
|
|
||||||
),
|
),
|
||||||
width: '10%',
|
width: '10%',
|
||||||
},
|
},
|
||||||
|
@ -193,12 +210,38 @@ export const PrevalenceDetails: React.FC = () => {
|
||||||
const { browserFields, dataFormattedForFieldBrowser, eventId, investigationFields } =
|
const { browserFields, dataFormattedForFieldBrowser, eventId, investigationFields } =
|
||||||
useLeftPanelContext();
|
useLeftPanelContext();
|
||||||
|
|
||||||
|
const isPlatinumPlus = useLicense().isPlatinumPlus();
|
||||||
|
|
||||||
|
// these two are used by the usePrevalence hook to fetch the data
|
||||||
const [start, setStart] = useState(DEFAULT_FROM);
|
const [start, setStart] = useState(DEFAULT_FROM);
|
||||||
const [end, setEnd] = useState(DEFAULT_TO);
|
const [end, setEnd] = useState(DEFAULT_TO);
|
||||||
|
|
||||||
const onTimeChange = ({ start: s, end: e }: OnTimeChangeProps) => {
|
// these two are used to pass to timeline
|
||||||
|
const [absoluteStart, setAbsoluteStart] = useState(
|
||||||
|
(dateMath.parse(DEFAULT_FROM) || new Date()).toISOString()
|
||||||
|
);
|
||||||
|
const [absoluteEnd, setAbsoluteEnd] = useState(
|
||||||
|
(dateMath.parse(DEFAULT_TO) || new Date()).toISOString()
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO update the logic to use a single set of start/end dates
|
||||||
|
// currently as we're using this InvestigateInTimelineButton component we need to pass the timeRange
|
||||||
|
// as an AbsoluteTimeRange, which requires from/to values
|
||||||
|
const onTimeChange = ({ start: s, end: e, isInvalid }: OnTimeChangeProps) => {
|
||||||
|
if (isInvalid) return;
|
||||||
|
|
||||||
setStart(s);
|
setStart(s);
|
||||||
setEnd(e);
|
setEnd(e);
|
||||||
|
|
||||||
|
const from = dateMath.parse(s);
|
||||||
|
if (from && from.isValid()) {
|
||||||
|
setAbsoluteStart(from.toISOString());
|
||||||
|
}
|
||||||
|
|
||||||
|
const to = dateMath.parse(e);
|
||||||
|
if (to && to.isValid()) {
|
||||||
|
setAbsoluteEnd(to.toISOString());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const { loading, error, data } = usePrevalence({
|
const { loading, error, data } = usePrevalence({
|
||||||
|
@ -210,6 +253,12 @@ export const PrevalenceDetails: React.FC = () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// add timeRange to pass it down to timeline
|
||||||
|
const items = useMemo(
|
||||||
|
() => data.map((item) => ({ ...item, from: absoluteStart, to: absoluteEnd })),
|
||||||
|
[data, absoluteStart, absoluteEnd]
|
||||||
|
);
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<EuiFlexGroup
|
<EuiFlexGroup
|
||||||
|
@ -235,8 +284,31 @@ export const PrevalenceDetails: React.FC = () => {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const upsell = (
|
||||||
|
<>
|
||||||
|
<EuiCallOut data-test-subj={`${PREVALENCE_DETAILS_TABLE_TEST_ID}UpSell`}>
|
||||||
|
<FormattedMessage
|
||||||
|
id="xpack.securitySolution.flyout.documentDetails.prevalenceTableAlertUpsell"
|
||||||
|
defaultMessage="Preview of a {subscription} feature showing host and user prevalence."
|
||||||
|
values={{
|
||||||
|
subscription: (
|
||||||
|
<EuiLink href="https://www.elastic.co/pricing/" target="_blank">
|
||||||
|
<FormattedMessage
|
||||||
|
id="xpack.securitySolution.flyout.documentDetails.prevalenceTableAlertUpsellLink"
|
||||||
|
defaultMessage="Platinum"
|
||||||
|
/>
|
||||||
|
</EuiLink>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</EuiCallOut>
|
||||||
|
<EuiSpacer size="s" />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{!isPlatinumPlus && upsell}
|
||||||
<EuiPanel>
|
<EuiPanel>
|
||||||
<EuiSuperDatePicker
|
<EuiSuperDatePicker
|
||||||
start={start}
|
start={start}
|
||||||
|
@ -247,7 +319,7 @@ export const PrevalenceDetails: React.FC = () => {
|
||||||
<EuiSpacer size="m" />
|
<EuiSpacer size="m" />
|
||||||
{data.length > 0 ? (
|
{data.length > 0 ? (
|
||||||
<EuiInMemoryTable
|
<EuiInMemoryTable
|
||||||
items={data}
|
items={items}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data-test-subj={PREVALENCE_DETAILS_TABLE_TEST_ID}
|
data-test-subj={PREVALENCE_DETAILS_TABLE_TEST_ID}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -69,7 +69,7 @@ export const ResponseDetails: React.FC = () => {
|
||||||
values={{
|
values={{
|
||||||
editRuleLink: (
|
editRuleLink: (
|
||||||
<EuiLink
|
<EuiLink
|
||||||
href="https://www.elastic.co/guide/en/security/master/rules-ui-management.html#edit-rules-settings"
|
href="https://www.elastic.co/guide/en/security/current/rules-ui-management.html#edit-rules-settings"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
|
|
|
@ -54,11 +54,13 @@ const columns: Array<EuiBasicTableColumn<HighlightedFieldsTableRow>> = [
|
||||||
field: 'field',
|
field: 'field',
|
||||||
name: HIGHLIGHTED_FIELDS_FIELD_COLUMN,
|
name: HIGHLIGHTED_FIELDS_FIELD_COLUMN,
|
||||||
'data-test-subj': 'fieldCell',
|
'data-test-subj': 'fieldCell',
|
||||||
|
width: '50%',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'description',
|
field: 'description',
|
||||||
name: HIGHLIGHTED_FIELDS_VALUE_COLUMN,
|
name: HIGHLIGHTED_FIELDS_VALUE_COLUMN,
|
||||||
'data-test-subj': 'valueCell',
|
'data-test-subj': 'valueCell',
|
||||||
|
width: '50%',
|
||||||
render: (description: {
|
render: (description: {
|
||||||
field: string;
|
field: string;
|
||||||
values: string[] | null | undefined;
|
values: string[] | null | undefined;
|
||||||
|
|
|
@ -11,6 +11,9 @@ import { useQuery } from '@tanstack/react-query';
|
||||||
import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types';
|
import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types';
|
||||||
import { createFetchData } from '../utils/fetch_data';
|
import { createFetchData } from '../utils/fetch_data';
|
||||||
import { useKibana } from '../../../common/lib/kibana';
|
import { useKibana } from '../../../common/lib/kibana';
|
||||||
|
import { useTimelineDataFilters } from '../../../timelines/containers/use_timeline_data_filters';
|
||||||
|
import { isActiveTimeline } from '../../../helpers';
|
||||||
|
import { SourcererScopeName } from '../../../common/store/sourcerer/model';
|
||||||
|
|
||||||
const QUERY_KEY = 'useFetchFieldValuePairWithAggregation';
|
const QUERY_KEY = 'useFetchFieldValuePairWithAggregation';
|
||||||
|
|
||||||
|
@ -99,7 +102,10 @@ export const useFetchPrevalence = ({
|
||||||
},
|
},
|
||||||
} = useKibana();
|
} = useKibana();
|
||||||
|
|
||||||
const searchRequest = buildSearchRequest(highlightedFieldsFilters, from, to);
|
// retrieves detections and non-detections indices (for example, the alert security index from the current space and 'logs-*' indices)
|
||||||
|
const { selectedPatterns } = useTimelineDataFilters(isActiveTimeline(SourcererScopeName.default));
|
||||||
|
|
||||||
|
const searchRequest = buildSearchRequest(highlightedFieldsFilters, from, to, selectedPatterns);
|
||||||
|
|
||||||
const { data, isLoading, isError } = useQuery(
|
const { data, isLoading, isError } = useQuery(
|
||||||
[QUERY_KEY, highlightedFieldsFilters, from, to],
|
[QUERY_KEY, highlightedFieldsFilters, from, to],
|
||||||
|
@ -120,7 +126,8 @@ export const useFetchPrevalence = ({
|
||||||
const buildSearchRequest = (
|
const buildSearchRequest = (
|
||||||
highlightedFieldsFilters: Record<string, QueryDslQueryContainer>,
|
highlightedFieldsFilters: Record<string, QueryDslQueryContainer>,
|
||||||
from: string,
|
from: string,
|
||||||
to: string
|
to: string,
|
||||||
|
selectedPatterns: string[]
|
||||||
): IEsSearchRequest => {
|
): IEsSearchRequest => {
|
||||||
const query = buildEsQuery(
|
const query = buildEsQuery(
|
||||||
undefined,
|
undefined,
|
||||||
|
@ -146,14 +153,16 @@ const buildSearchRequest = (
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
return buildAggregationSearchRequest(query, highlightedFieldsFilters);
|
return buildAggregationSearchRequest(query, highlightedFieldsFilters, selectedPatterns);
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildAggregationSearchRequest = (
|
const buildAggregationSearchRequest = (
|
||||||
query: QueryDslQueryContainer,
|
query: QueryDslQueryContainer,
|
||||||
highlightedFieldsFilters: Record<string, QueryDslQueryContainer>
|
highlightedFieldsFilters: Record<string, QueryDslQueryContainer>,
|
||||||
|
selectedPatterns: string[]
|
||||||
): IEsSearchRequest => ({
|
): IEsSearchRequest => ({
|
||||||
params: {
|
params: {
|
||||||
|
index: selectedPatterns,
|
||||||
body: {
|
body: {
|
||||||
query,
|
query,
|
||||||
aggs: {
|
aggs: {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue