mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Security Solution] Fix TopN filters in timeline (#183501)
## Summary Fixes: https://github.com/elastic/kibana/issues/183497 Sets the `applyGlobalQueriesAndFilters` prop correctly to _VisualizationEmbeddable_. This property was ignored when used from the _TopN_ component, causing it to always apply the global filters and query. Extra: I cleaned all props that are not used in those component ### Screenshots Pre-condition: Setting `user.name:"0q3c5et718"` query to the global query in the background. Before:  After:  --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
ece10c6139
commit
5acea44cc9
5 changed files with 36 additions and 33 deletions
|
@ -276,6 +276,12 @@ describe('StatefulTopN', () => {
|
|||
|
||||
expect(props.to).toEqual('2020-07-08T08:20:18.966Z');
|
||||
});
|
||||
|
||||
test(`provides 'applyGlobalQueriesAndFilters' = true`, () => {
|
||||
const props = wrapper.find('[data-test-subj="top-n"]').first().props() as Props;
|
||||
|
||||
expect(props.applyGlobalQueriesAndFilters).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('rendering in a timeline context', () => {
|
||||
|
@ -343,26 +349,38 @@ describe('StatefulTopN', () => {
|
|||
|
||||
expect(props.to).toEqual('2020-04-15T03:46:09.047Z');
|
||||
});
|
||||
|
||||
test(`provides 'applyGlobalQueriesAndFilters' = false`, () => {
|
||||
const props = wrapper.find('[data-test-subj="top-n"]').first().props() as Props;
|
||||
|
||||
expect(props.applyGlobalQueriesAndFilters).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('rendering in alerts context', () => {
|
||||
detectionAlertsTables.forEach((tableId) => {
|
||||
test(`defaults to the 'Alert events' option when rendering in Alerts`, async () => {
|
||||
const wrapper = mount(
|
||||
describe.each(detectionAlertsTables)('tableId: %s', (tableId) => {
|
||||
let wrapper: ReactWrapper;
|
||||
beforeEach(() => {
|
||||
wrapper = mount(
|
||||
<TestProviders store={store}>
|
||||
<StatefulTopN
|
||||
{...{
|
||||
...testProps,
|
||||
scopeId: tableId,
|
||||
}}
|
||||
/>
|
||||
<StatefulTopN {...{ ...testProps, scopeId: tableId }} />
|
||||
</TestProviders>
|
||||
);
|
||||
});
|
||||
afterEach(() => {
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
test(`defaults to the 'Alert events' option when rendering in Alerts`, async () => {
|
||||
await waitFor(() => {
|
||||
const props = wrapper.find('[data-test-subj="top-n"]').first().props() as Props;
|
||||
expect(props.defaultView).toEqual('alert');
|
||||
});
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
test(`provides 'applyGlobalQueriesAndFilters' = true`, () => {
|
||||
const props = wrapper.find('[data-test-subj="top-n"]').first().props() as Props;
|
||||
expect(props.applyGlobalQueriesAndFilters).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -111,6 +111,7 @@ const StatefulTopNComponent: React.FC<Props> = ({
|
|||
const { from, deleteQuery, setQuery, to } = useGlobalTime();
|
||||
|
||||
const options = getOptions(isActiveTimeline(scopeId ?? '') ? activeTimelineEventType : undefined);
|
||||
const applyGlobalQueriesAndFilters = !isActiveTimeline(scopeId ?? '');
|
||||
|
||||
const combinedQueries = useMemo(
|
||||
() =>
|
||||
|
@ -158,7 +159,6 @@ const StatefulTopNComponent: React.FC<Props> = ({
|
|||
options={options}
|
||||
paddingSize={paddingSize}
|
||||
query={isActiveTimeline(scopeId ?? '') ? EMPTY_QUERY : globalQuery}
|
||||
showLegend={showLegend}
|
||||
setAbsoluteRangeDatePickerTarget={
|
||||
isActiveTimeline(scopeId ?? '') ? InputsModelId.timeline : InputsModelId.global
|
||||
}
|
||||
|
@ -167,6 +167,7 @@ const StatefulTopNComponent: React.FC<Props> = ({
|
|||
to={isActiveTimeline(scopeId ?? '') ? activeTimelineTo : to}
|
||||
toggleTopN={toggleTopN}
|
||||
onFilterAdded={onFilterAdded}
|
||||
applyGlobalQueriesAndFilters={applyGlobalQueriesAndFilters}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -15,7 +15,6 @@ import { EventsByDataset } from '../../../overview/components/events_by_dataset'
|
|||
import { SignalsByCategory } from '../../../overview/components/signals_by_category';
|
||||
import type { InputsModelId } from '../../store/inputs/constants';
|
||||
import type { TimelineEventsType } from '../../../../common/types/timeline';
|
||||
import { useSourcererDataView } from '../../containers/sourcerer';
|
||||
import type { TopNOption } from './helpers';
|
||||
import { getSourcererScopeName, removeIgnoredAlertFilters } from './helpers';
|
||||
import * as i18n from './translations';
|
||||
|
@ -54,10 +53,10 @@ export interface Props extends Pick<GlobalTimeArgs, 'from' | 'to' | 'deleteQuery
|
|||
paddingSize?: 's' | 'm' | 'l' | 'none';
|
||||
query: Query;
|
||||
setAbsoluteRangeDatePickerTarget: InputsModelId;
|
||||
showLegend?: boolean;
|
||||
scopeId?: string;
|
||||
toggleTopN: () => void;
|
||||
onFilterAdded?: () => void; // eslint-disable-line react/no-unused-prop-types
|
||||
applyGlobalQueriesAndFilters?: boolean;
|
||||
}
|
||||
|
||||
const TopNComponent: React.FC<Props> = ({
|
||||
|
@ -71,12 +70,12 @@ const TopNComponent: React.FC<Props> = ({
|
|||
options,
|
||||
paddingSize,
|
||||
query,
|
||||
showLegend,
|
||||
setAbsoluteRangeDatePickerTarget,
|
||||
setQuery,
|
||||
scopeId,
|
||||
to,
|
||||
toggleTopN,
|
||||
applyGlobalQueriesAndFilters,
|
||||
}) => {
|
||||
const [view, setView] = useState<TimelineEventsType>(defaultView);
|
||||
const onViewSelected = useCallback(
|
||||
|
@ -84,7 +83,6 @@ const TopNComponent: React.FC<Props> = ({
|
|||
[setView]
|
||||
);
|
||||
const sourcererScopeId = getSourcererScopeName({ scopeId, view });
|
||||
const { selectedPatterns, runtimeMappings } = useSourcererDataView(sourcererScopeId);
|
||||
|
||||
useEffect(() => {
|
||||
setView(defaultView);
|
||||
|
@ -121,21 +119,17 @@ const TopNComponent: React.FC<Props> = ({
|
|||
from={from}
|
||||
headerChildren={headerChildren}
|
||||
indexPattern={indexPattern}
|
||||
indexNames={selectedPatterns}
|
||||
runtimeMappings={runtimeMappings}
|
||||
onlyField={field}
|
||||
paddingSize={paddingSize}
|
||||
query={query}
|
||||
queryType="topN"
|
||||
showLegend={showLegend}
|
||||
setAbsoluteRangeDatePickerTarget={setAbsoluteRangeDatePickerTarget}
|
||||
setQuery={setQuery}
|
||||
showSpacer={false}
|
||||
toggleTopN={toggleTopN}
|
||||
scopeId={scopeId}
|
||||
sourcererScopeId={sourcererScopeId}
|
||||
to={to}
|
||||
hideQueryToggle
|
||||
applyGlobalQueriesAndFilters={applyGlobalQueriesAndFilters}
|
||||
/>
|
||||
) : (
|
||||
<SignalsByCategory
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
import { Position } from '@elastic/charts';
|
||||
import numeral from '@elastic/numeral';
|
||||
import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import React, { useEffect, useMemo, useCallback } from 'react';
|
||||
|
||||
import type { DataViewBase, Filter, Query } from '@kbn/es-query';
|
||||
|
@ -29,7 +28,6 @@ import {
|
|||
eventsHistogramConfig,
|
||||
} from '../../../common/components/events_tab/histogram_configurations';
|
||||
import { HostsTableType } from '../../../explore/hosts/store/model';
|
||||
import type { InputsModelId } from '../../../common/store/inputs/constants';
|
||||
import type { GlobalTimeArgs } from '../../../common/containers/use_global_time';
|
||||
|
||||
import * as i18n from '../../pages/translations';
|
||||
|
@ -48,20 +46,16 @@ interface Props extends Pick<GlobalTimeArgs, 'from' | 'to' | 'deleteQuery' | 'se
|
|||
filters: Filter[];
|
||||
headerChildren?: React.ReactNode;
|
||||
indexPattern: DataViewBase;
|
||||
indexNames: string[];
|
||||
runtimeMappings?: MappingRuntimeFields;
|
||||
onlyField?: string;
|
||||
paddingSize?: 's' | 'm' | 'l' | 'none';
|
||||
query: Query;
|
||||
// Make a unique query type everywhere this query is used
|
||||
queryType: 'topN' | 'overview';
|
||||
setAbsoluteRangeDatePickerTarget?: InputsModelId;
|
||||
showLegend?: boolean;
|
||||
showSpacer?: boolean;
|
||||
scopeId?: string;
|
||||
toggleTopN?: () => void;
|
||||
hideQueryToggle?: boolean;
|
||||
sourcererScopeId?: SourcererScopeName;
|
||||
applyGlobalQueriesAndFilters?: boolean;
|
||||
}
|
||||
|
||||
const getHistogramOption = (fieldName: string): MatrixHistogramOption => ({
|
||||
|
@ -83,21 +77,17 @@ const EventsByDatasetComponent: React.FC<Props> = ({
|
|||
from,
|
||||
headerChildren,
|
||||
indexPattern,
|
||||
indexNames,
|
||||
runtimeMappings,
|
||||
onlyField,
|
||||
paddingSize,
|
||||
query,
|
||||
queryType,
|
||||
setAbsoluteRangeDatePickerTarget,
|
||||
setQuery,
|
||||
showLegend,
|
||||
showSpacer = true,
|
||||
scopeId,
|
||||
sourcererScopeId,
|
||||
to,
|
||||
toggleTopN,
|
||||
hideQueryToggle = false,
|
||||
applyGlobalQueriesAndFilters,
|
||||
}) => {
|
||||
const uniqueQueryId = useMemo(() => `${ID}-${queryType}`, [queryType]);
|
||||
|
||||
|
@ -204,6 +194,7 @@ const EventsByDatasetComponent: React.FC<Props> = ({
|
|||
title={onlyField != null ? i18n.TOP(onlyField) : eventsByDatasetHistogramConfigs.title}
|
||||
chartHeight={CHART_HEIGHT}
|
||||
hideQueryToggle={hideQueryToggle}
|
||||
applyGlobalQueriesAndFilters={applyGlobalQueriesAndFilters}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -115,7 +115,6 @@ const OverviewComponent = () => {
|
|||
filters={filters}
|
||||
from={from}
|
||||
indexPattern={indexPattern}
|
||||
indexNames={selectedPatterns}
|
||||
query={query}
|
||||
queryType="overview"
|
||||
setQuery={setQuery}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue