Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security Solution][Exceptions] - Fixes up some bugs in the all exception items view #141682

Merged
merged 7 commits into from
Sep 29, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@
*/

import React, { useCallback, useMemo, useEffect, useReducer } from 'react';
import { EuiPanel, EuiSpacer } from '@elastic/eui';
import { EuiPanel, EuiSpacer, EuiText } from '@elastic/eui';

import type {
ExceptionListItemSchema,
UseExceptionListItemsSuccess,
Pagination,
ExceptionListTypeEnum,
} from '@kbn/securitysolution-io-ts-list-types';
import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types';
import { transformInput } from '@kbn/securitysolution-list-hooks';

import {
deleteExceptionListItemById,
fetchExceptionListsItemsByListIds,
} from '@kbn/securitysolution-list-api';
import styled from 'styled-components';
import { DEFAULT_INDEX_PATTERN } from '../../../../../common/constants';
import { useUserData } from '../../../../detections/components/user_info';
import { useKibana, useToasts } from '../../../../common/lib/kibana';
Expand All @@ -37,6 +38,10 @@ import * as i18n from './translations';
import { useFindExceptionListReferences } from '../../logic/use_find_references';
import type { Rule } from '../../../../detections/containers/detection_engine/rules/types';

const StyledText = styled(EuiText)`
font-style: italic;
`;

const STATES_SEARCH_HIDDEN: ViewerState[] = ['error', 'empty'];
const STATES_PAGINATION_UTILITY_HIDDEN: ViewerState[] = [
'loading',
Expand All @@ -51,7 +56,7 @@ const initialState: State = {
pageIndex: 0,
pageSize: 25,
totalItemCount: 0,
pageSizeOptions: [1, 5, 10, 25, 50, 100, 200, 300],
pageSizeOptions: [5, 10, 25, 50, 100, 200, 300],
},
exceptions: [],
exceptionToEdit: null,
Expand Down Expand Up @@ -154,7 +159,18 @@ const ExceptionsViewerComponent = ({
[dispatch]
);

const [_, allReferences] = useFindExceptionListReferences(exceptionListsToQuery);
const [isLoadingReferences, isFetchReferencesError, allReferences] =
useFindExceptionListReferences(exceptionListsToQuery);

useEffect(() => {
if (isFetchReferencesError) {
setViewerState('error');
} else if (viewerState == null && isLoadingReferences) {
setViewerState('loading');
} else if (viewerState === 'loading' && !isLoadingReferences) {
setViewerState(null);
}
}, [isLoadingReferences, isFetchReferencesError, setViewerState, viewerState]);

const handleFetchItems = useCallback(
async (options?: GetExceptionItemProps) => {
Expand Down Expand Up @@ -212,12 +228,8 @@ const ExceptionsViewerComponent = ({
const handleGetExceptionListItems = useCallback(
async (options?: GetExceptionItemProps) => {
try {
setViewerState('loading');

const { pageIndex, itemsPerPage, total, data } = await handleFetchItems(options);

setViewerState(total > 0 ? null : 'empty');

setExceptions({
exceptions: data,
pagination: {
Expand All @@ -226,6 +238,8 @@ const ExceptionsViewerComponent = ({
total,
},
});

setViewerState(total > 0 ? null : 'empty');
} catch (e) {
setViewerState('error');

Expand Down Expand Up @@ -367,6 +381,12 @@ const ExceptionsViewerComponent = ({

<EuiPanel hasBorder={false} hasShadow={false}>
<>
<StyledText size="s">
{listType === ExceptionListTypeEnum.ENDPOINT
? i18n.ENDPOINT_EXCEPTIONS_TAB_ABOUT
: i18n.EXCEPTIONS_TAB_ABOUT}
</StyledText>
<EuiSpacer size="l" />
{!STATES_SEARCH_HIDDEN.includes(viewerState) && (
<ExceptionsViewerSearchBar
canAddException={isReadOnly}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import React, { useCallback, useMemo } from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiButton, EuiSearchBar } from '@elastic/eui';

import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types';
import * as i18n from '../../utils/translations';
import * as sharedI18n from '../../utils/translations';
import * as i18n from './translations';
import type { GetExceptionItemProps } from '.';

const ITEMS_SCHEMA = {
Expand Down Expand Up @@ -75,16 +76,16 @@ const ExceptionsViewerSearchBarComponent = ({

const addExceptionButtonText = useMemo(() => {
return listType === ExceptionListTypeEnum.ENDPOINT
? i18n.ADD_TO_ENDPOINT_LIST
: i18n.ADD_TO_DETECTIONS_LIST;
? sharedI18n.ADD_TO_ENDPOINT_LIST
: sharedI18n.ADD_TO_DETECTIONS_LIST;
}, [listType]);

return (
<EuiFlexGroup alignItems="center">
<EuiFlexItem grow={true}>
<EuiSearchBar
box={{
placeholder: 'Search on the fields below: e.g. name:"my list"',
placeholder: i18n.SEARCH_PLACEHOLDER,
incremental: true,
schema: ITEMS_SCHEMA,
'data-test-subj': 'exceptionsViewerSearchBar',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ export const EXCEPTION_EMPTY_PROMPT_BODY = i18n.translate(
export const EXCEPTION_EMPTY_ENDPOINT_PROMPT_BODY = i18n.translate(
'xpack.securitySolution.exceptions.allItems.endpoint.emptyPromptBody',
{
defaultMessage:
'There are no endpoint exceptions. Endpoint exceptions are applied to the endpoint and the detection rule. Create your first endpoint exception.',
defaultMessage: 'There are no endpoint exceptions. Create your first endpoint exception.',
}
);

Expand Down Expand Up @@ -112,3 +111,25 @@ export const EXCEPTION_ITEM_DELETE_TEXT = (itemName: string) =>
values: { itemName },
defaultMessage: '"{itemName}" deleted successfully.',
});

export const ENDPOINT_EXCEPTIONS_TAB_ABOUT = i18n.translate(
'xpack.securitySolution.exceptions.allExceptionItems.exceptionEndpointDetailsDescription',
{
defaultMessage:
'Endpoint exceptions are added to both the detection rule and the Elastic Endpoint agent on your hosts.',
}
);

export const EXCEPTIONS_TAB_ABOUT = i18n.translate(
'xpack.securitySolution.exceptions.allExceptionItems.exceptionDetectionDetailsDescription',
{
defaultMessage: 'Rule exceptions are added to the detection rule.',
}
);

export const SEARCH_PLACEHOLDER = i18n.translate(
'xpack.securitySolution.exceptions.allExceptionItems.searchPlaceholder',
{
defaultMessage: 'Filter exceptions using simple query syntax, for example, name:"my list"',
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { useToasts } from '../../../common/lib/kibana';
import type { FindRulesReferencedByExceptionsListProp } from '../../../detections/containers/detection_engine/rules/types';
import * as i18n from '../utils/translations';

export type ReturnUseFindExceptionListReferences = [boolean, RuleReferences | null];
export type ReturnUseFindExceptionListReferences = [boolean, boolean, RuleReferences | null];

export interface RuleReferences {
[key: string]: RuleReferenceSchema[];
Expand All @@ -28,6 +28,7 @@ export const useFindExceptionListReferences = (
): ReturnUseFindExceptionListReferences => {
const toasts = useToasts();
const [isLoading, setIsLoading] = useState(false);
const [errorExists, setErrorExists] = useState(false);
const [references, setReferences] = useState<RuleReferences | null>(null);
const listRefs = useMemo((): FindRulesReferencedByExceptionsListProp[] => {
return ruleExceptionLists.map((list) => {
Expand Down Expand Up @@ -61,18 +62,21 @@ export const useFindExceptionListReferences = (
}, {});

if (isSubscribed) {
setErrorExists(false);
setIsLoading(false);
setReferences(results);
}
} catch (error) {
if (isSubscribed) {
setErrorExists(true);
setIsLoading(false);
toasts.addError(error, { title: i18n.ERROR_FETCHING_REFERENCES_TITLE });
}
}
};

if (listRefs.length === 0 && isSubscribed) {
setErrorExists(false);
setIsLoading(false);
setReferences(null);
} else {
Expand All @@ -85,5 +89,5 @@ export const useFindExceptionListReferences = (
};
}, [ruleExceptionLists, listRefs, toasts]);

return [isLoading, references];
return [isLoading, errorExists, references];
};
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,9 @@ export const referenceErrorMessage = (referenceCount: number) =>
});

export const EXCEPTION_LIST_SEARCH_PLACEHOLDER = i18n.translate(
'xpack.securitySolution.exceptions.searchPlaceholder',
'xpack.securitySolution.detectionEngine.rules.all.exceptions.searchPlaceholder',
{
defaultMessage: 'e.g. Example List Name',
yctercero marked this conversation as resolved.
Show resolved Hide resolved
defaultMessage: 'Search by name or list_id',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delayed response. Feel free to revert this to list id or list ID so that it matches the way you're representing the name field in this helper text. That's all - everything else looks good. :) Thank you!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All good! I'll update and post follow up PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed here - #142258

}
);

Expand Down
1 change: 0 additions & 1 deletion x-pack/plugins/translations/translations/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -28304,7 +28304,6 @@
"xpack.securitySolution.exceptions.referenceModalCancelButton": "Annuler",
"xpack.securitySolution.exceptions.referenceModalDeleteButton": "Retirer la liste d'exceptions",
"xpack.securitySolution.exceptions.referenceModalTitle": "Retirer la liste d'exceptions",
"xpack.securitySolution.exceptions.searchPlaceholder": "par ex. Exemple de liste de noms",
"xpack.securitySolution.exceptions.viewer.addCommentPlaceholder": "Ajouter un nouveau commentaire...",
"xpack.securitySolution.exceptions.viewer.addToClipboard": "Commentaire",
"xpack.securitySolution.exceptions.viewer.addToDetectionsListLabel": "Ajouter une exception à une règle",
Expand Down
1 change: 0 additions & 1 deletion x-pack/plugins/translations/translations/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -28279,7 +28279,6 @@
"xpack.securitySolution.exceptions.referenceModalCancelButton": "キャンセル",
"xpack.securitySolution.exceptions.referenceModalDeleteButton": "例外リストを削除",
"xpack.securitySolution.exceptions.referenceModalTitle": "例外リストを削除",
"xpack.securitySolution.exceptions.searchPlaceholder": "例:例外リスト名",
"xpack.securitySolution.exceptions.viewer.addCommentPlaceholder": "新しいコメントを追加...",
"xpack.securitySolution.exceptions.viewer.addToClipboard": "コメント",
"xpack.securitySolution.exceptions.viewer.addToDetectionsListLabel": "ルール例外の追加",
Expand Down
1 change: 0 additions & 1 deletion x-pack/plugins/translations/translations/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -28313,7 +28313,6 @@
"xpack.securitySolution.exceptions.referenceModalCancelButton": "取消",
"xpack.securitySolution.exceptions.referenceModalDeleteButton": "移除例外列表",
"xpack.securitySolution.exceptions.referenceModalTitle": "移除例外列表",
"xpack.securitySolution.exceptions.searchPlaceholder": "例如,示例列表名称",
"xpack.securitySolution.exceptions.viewer.addCommentPlaceholder": "添加新注释......",
"xpack.securitySolution.exceptions.viewer.addToClipboard": "注释",
"xpack.securitySolution.exceptions.viewer.addToDetectionsListLabel": "添加规则例外",
Expand Down