[8.12] [Security Solution] Fix rule filters on the Rule Details page (#177081) (#177260)

# Backport

This will backport the following commits from `main` to `8.12`:
- [[Security Solution] Fix rule filters on the Rule Details page
(#177081)](https://github.com/elastic/kibana/pull/177081)

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)
This commit is contained in:
Georgii Gorbachev 2024-02-20 12:18:18 +01:00 committed by GitHub
parent 1200cf30d6
commit 1b457956ed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 101 additions and 69 deletions

View file

@ -0,0 +1,45 @@
/*
* 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 { useEuiTheme } from '@elastic/eui';
import { css } from '@emotion/css';
import { useMemo } from 'react';
export const useFiltersStyles = () => {
return useMemo(
() => ({
flexGroup: css`
max-width: 600px;
`,
}),
[]
);
};
export const useQueryStyles = () => {
return useMemo(
() => ({
content: css`
white-space: pre-wrap;
`,
}),
[]
);
};
export const useRequiredFieldsStyles = () => {
const { euiTheme } = useEuiTheme();
return useMemo(
() => ({
fieldTypeText: css({
fontFamily: euiTheme.font.familyCode,
display: 'inline',
}),
}),
[euiTheme.font.familyCode]
);
};

View file

@ -7,7 +7,6 @@
import React from 'react';
import { isEmpty } from 'lodash/fp';
import styled from 'styled-components';
import {
EuiDescriptionList,
EuiText,
@ -15,7 +14,6 @@ import {
EuiFlexItem,
EuiFlexGroup,
EuiLoadingSpinner,
EuiBadge,
} from '@elastic/eui';
import type { EuiDescriptionListProps } from '@elastic/eui';
import type {
@ -25,9 +23,10 @@ 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 { FieldIcon } from '@kbn/react-field';
import { castEsToKbnFieldTypeName } from '@kbn/field-types';
import { FilterBadgeGroup } from '@kbn/unified-search-plugin/public';
import { FilterItems } from '@kbn/unified-search-plugin/public';
import type {
AlertSuppressionMissingFieldsStrategy,
RequiredFieldArray,
@ -55,6 +54,11 @@ import { BadgeList } from './badge_list';
import { DEFAULT_DESCRIPTION_LIST_COLUMN_WIDTHS } from './constants';
import * as i18n from './translations';
import type { ExperimentalFeatures } from '../../../../../common/experimental_features';
import {
useFiltersStyles,
useQueryStyles,
useRequiredFieldsStyles,
} from './rule_definition_section.styles';
interface SavedQueryNameProps {
savedQueryName: string;
@ -66,12 +70,6 @@ const SavedQueryName = ({ savedQueryName }: SavedQueryNameProps) => (
</EuiText>
);
const EuiBadgeWrap = styled(EuiBadge)`
.euiBadge__text {
white-space: pre-wrap !important;
}
`;
interface FiltersProps {
filters: Filter[];
dataViewId?: string;
@ -80,51 +78,42 @@ interface FiltersProps {
}
const Filters = ({ filters, dataViewId, index, 'data-test-subj': dataTestSubj }: FiltersProps) => {
const flattenedFilters = mapAndFlattenFilters(filters);
const { indexPattern } = useRuleIndexPattern({
dataSourceType: dataViewId ? DataSourceType.DataView : DataSourceType.IndexPatterns,
index: index ?? [],
dataViewId,
});
const flattenedFilters = mapAndFlattenFilters(filters);
const styles = useFiltersStyles();
return (
<EuiFlexGroup wrap responsive={false} gutterSize="xs" data-test-subj={dataTestSubj}>
{flattenedFilters.map((filter, idx) => {
const displayContent = filter.meta.alias ? (
filter.meta.alias
) : (
<FilterBadgeGroup filters={[filter]} dataViews={[indexPattern]} />
);
return (
<EuiFlexItem
grow={false}
key={`filter-${idx}`}
css={{ width: '100%' }}
data-test-subj={`filterItem-${filter.meta.key}`}
>
<EuiBadgeWrap color="hollow">
{indexPattern != null ? displayContent : <EuiLoadingSpinner size="m" />}
</EuiBadgeWrap>
</EuiFlexItem>
);
})}
<EuiFlexGroup
data-test-subj={dataTestSubj}
className={styles.flexGroup}
wrap
responsive={false}
gutterSize="xs"
>
<FilterItems filters={flattenedFilters} indexPatterns={[indexPattern as DataView]} readOnly />
</EuiFlexGroup>
);
};
const QueryContent = styled.div`
white-space: pre-wrap;
`;
interface QueryProps {
query: string;
'data-test-subj'?: string;
}
const Query = ({ query, 'data-test-subj': dataTestSubj = 'query' }: QueryProps) => (
<QueryContent data-test-subj={dataTestSubj}>{query}</QueryContent>
);
const Query = ({ query, 'data-test-subj': dataTestSubj = 'query' }: QueryProps) => {
const styles = useQueryStyles();
return (
<div data-test-subj={dataTestSubj} className={styles.content}>
{query}
</div>
);
};
interface IndexProps {
index: string[];
@ -260,42 +249,40 @@ const RuleType = ({ type }: RuleTypeProps) => (
<EuiText size="s">{getRuleTypeDescription(type)}</EuiText>
);
const StyledFieldTypeText = styled(EuiText)`
font-size: ${({ theme }) => theme.eui.euiFontSizeXS};
font-family: ${({ theme }) => theme.eui.euiCodeFontFamily};
display: inline;
`;
interface RequiredFieldsProps {
requiredFields: RequiredFieldArray;
}
const RequiredFields = ({ requiredFields }: RequiredFieldsProps) => (
<EuiFlexGrid gutterSize={'s'} data-test-subj="requiredFieldsPropertyValue">
{requiredFields.map((rF, index) => (
<EuiFlexItem grow={false} key={rF.name}>
<EuiFlexGroup alignItems="center" gutterSize={'xs'}>
<EuiFlexItem grow={false}>
<FieldIcon
data-test-subj="field-type-icon"
type={castEsToKbnFieldTypeName(rF.type)}
label={rF.type}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<StyledFieldTypeText
grow={false}
size={'s'}
data-test-subj="requiredFieldsPropertyValueItem"
>
{` ${rF.name}${index + 1 !== requiredFields.length ? ', ' : ''}`}
</StyledFieldTypeText>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
))}
</EuiFlexGrid>
);
const RequiredFields = ({ requiredFields }: RequiredFieldsProps) => {
const styles = useRequiredFieldsStyles();
return (
<EuiFlexGrid data-test-subj="requiredFieldsPropertyValue" gutterSize={'s'}>
{requiredFields.map((rF, index) => (
<EuiFlexItem grow={false} key={rF.name}>
<EuiFlexGroup alignItems="center" gutterSize={'xs'}>
<EuiFlexItem grow={false}>
<FieldIcon
data-test-subj="field-type-icon"
type={castEsToKbnFieldTypeName(rF.type)}
label={rF.type}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiText
data-test-subj="requiredFieldsPropertyValueItem"
className={styles.fieldTypeText}
grow={false}
size="xs"
>
{` ${rF.name}${index + 1 !== requiredFields.length ? ', ' : ''}`}
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
))}
</EuiFlexGrid>
);
};
interface TimelineTitleProps {
timelineTitle: string;