From d5a28b15f3ef64b1e22d36fc5eedb8f91c6bb8b9 Mon Sep 17 00:00:00 2001 From: Jacek Kolezynski Date: Wed, 18 Dec 2024 10:47:05 +0100 Subject: [PATCH] [Security Solution] Remove warning for rule filter (#201776) **Resolves: #178908** ## Summary This PR fixes a warning displayed for the rule when certain filter is present. I followed the suggestion from @nikitaindik in the original ticket and pulled his fix and tested that it works, but it also needed some modification borrowed from QueryBar component, namely to update the filters before displaying the FilterItems component. Note: This PR only covers the Rule Creation / Rules Details page. Two new tickets have been created to cover issues found in other places: #203600 and #203615 # BEFORE image # AFTER image ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed --------- Co-authored-by: Nikita Indik (cherry picked from commit 2e3a74829d953e3a968c75e0edaed21dce332c03) # Conflicts: # x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_definition_section.tsx # x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/hooks/use_data_view.ts --- .../rule_details/rule_definition_section.tsx | 41 +++++++++---- .../final_edit/fields/hooks/use_data_view.ts | 60 +++++++++++++++++++ 2 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/hooks/use_data_view.ts diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_definition_section.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_definition_section.tsx index 9c4b71c6ffedc..a3337c74582cc 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_definition_section.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_definition_section.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; import { isEmpty } from 'lodash/fp'; import { EuiDescriptionList, @@ -23,8 +23,8 @@ import type { import type { Filter } from '@kbn/es-query'; import type { SavedQuery } from '@kbn/data-plugin/public'; import { mapAndFlattenFilters } from '@kbn/data-plugin/public'; -import type { DataView } from '@kbn/data-views-plugin/public'; import { FilterItems } from '@kbn/unified-search-plugin/public'; +import { isDataView } from '../../../../common/components/query_bar'; import type { AlertSuppressionMissingFieldsStrategy, RequiredFieldArray, @@ -39,8 +39,6 @@ import { AlertSuppressionLabel } from '../../../rule_creation_ui/components/desc import { useGetSavedQuery } from '../../../../detections/pages/detection_engine/rules/use_get_saved_query'; import * as threatMatchI18n from '../../../../common/components/threat_match/translations'; import * as timelinesI18n from '../../../../timelines/components/timeline/translations'; -import { useRuleIndexPattern } from '../../../rule_creation_ui/pages/form'; -import { DataSourceType } from '../../../../detections/pages/detection_engine/rules/types'; import type { Duration } from '../../../../detections/pages/detection_engine/rules/types'; import { convertHistoryStartToSize } from '../../../../detections/pages/detection_engine/rules/helpers'; import { MlJobsDescription } from '../../../rule_creation/components/ml_jobs_description/ml_jobs_description'; @@ -59,6 +57,7 @@ import { } from './rule_definition_section.styles'; import { getQueryLanguageLabel } from './helpers'; import { useDefaultIndexPattern } from './use_default_index_pattern'; +import { useDataView } from './three_way_diff/final_edit/fields/hooks/use_data_view'; interface SavedQueryNameProps { savedQueryName: string; @@ -83,16 +82,34 @@ export const Filters = ({ index, 'data-test-subj': dataTestSubj, }: FiltersProps) => { - const flattenedFilters = mapAndFlattenFilters(filters); - const defaultIndexPattern = useDefaultIndexPattern(); + const useDataViewParams = dataViewId + ? { dataViewId } + : { indexPatterns: index ?? defaultIndexPattern }; + const { dataView } = useDataView(useDataViewParams); + const isEsql = filters.some((filter) => filter?.query?.language === 'esql'); + const searchBarFilters = useMemo(() => { + if (!index || isDataView(index) || isEsql) { + return filters; + } + const filtersWithUpdatedMetaIndex = filters.map((filter) => { + return { + ...filter, + meta: { + ...filter.meta, + index: index.join(','), + }, + }; + }); - const { indexPattern } = useRuleIndexPattern({ - dataSourceType: dataViewId ? DataSourceType.DataView : DataSourceType.IndexPatterns, - index: index ?? defaultIndexPattern, - dataViewId, - }); + return filtersWithUpdatedMetaIndex; + }, [filters, index, isEsql]); + + if (!dataView) { + return null; + } + const flattenedFilters = mapAndFlattenFilters(searchBarFilters); const styles = filtersStyles; return ( @@ -103,7 +120,7 @@ export const Filters = ({ responsive={false} gutterSize="xs" > - + ); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/hooks/use_data_view.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/hooks/use_data_view.ts new file mode 100644 index 0000000000000..123a7b3cffb58 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/hooks/use_data_view.ts @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useEffect, useState } from 'react'; +import type { DataView } from '@kbn/data-views-plugin/common'; +import { useKibana } from '../../../../../../../../common/lib/kibana'; + +export type UseDataViewParams = + | { indexPatterns: string[]; dataViewId?: never } + | { indexPatterns?: never; dataViewId: string }; + +interface UseDataViewResult { + dataView: DataView | undefined; + isLoading: boolean; +} + +export function useDataView(indexPatternsOrDataViewId: UseDataViewParams): UseDataViewResult { + const { + data: { dataViews: dataViewsService }, + } = useKibana().services; + const [dataView, setDataView] = useState(); + const [isLoading, setIsLoading] = useState(false); + + useEffect(() => { + setIsLoading(true); + + (async () => { + try { + if (indexPatternsOrDataViewId.indexPatterns) { + const indexPatternsDataView = await dataViewsService.create({ + title: indexPatternsOrDataViewId.indexPatterns.join(','), + id: indexPatternsOrDataViewId.indexPatterns.join(','), + allowNoIndex: true, + }); + + setDataView(indexPatternsDataView); + return; + } + + if (indexPatternsOrDataViewId.dataViewId) { + const ruleDataView = await dataViewsService.get(indexPatternsOrDataViewId.dataViewId); + + setDataView(ruleDataView); + } + } finally { + setIsLoading(false); + } + })(); + }, [ + dataViewsService, + indexPatternsOrDataViewId.indexPatterns, + indexPatternsOrDataViewId.dataViewId, + ]); + + return { dataView, isLoading }; +}