From 0bf0b94ee02a8735a639d27ad61f57948dd0d08c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20S=C3=A1nchez?= Date: Wed, 13 Oct 2021 12:03:13 +0200 Subject: [PATCH] [Security Solution] [Endpoint] Event filters uses the new card design (#114126) * Adds new card design to event filters and also adds comments list * Adds nested comments * Hides comments if there are no commentes * Fixes i18n check error because duplicated key * Fix wrong type and unit test * Fixes ts error * Address pr comments and fix unit tests Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../artifact_entry_card.test.tsx | 22 +++- .../artifact_entry_card.tsx | 35 ++++-- .../artifact_entry_collapsible_card.tsx | 4 +- .../components/card_comments.tsx | 68 ++++++++++ .../components/criteria_conditions.tsx | 57 ++++++++- .../components/translations.ts | 12 ++ .../artifact_entry_card/test_utils.ts | 9 ++ .../components/artifact_entry_card/types.ts | 16 +-- .../utils/get_formatted_comments.tsx | 34 +++++ .../utils/map_to_artifact_info.ts | 1 + .../view/event_filters_list_page.test.tsx | 29 ++--- .../view/event_filters_list_page.tsx | 118 ++++++++++++------ .../components/trusted_apps_grid/index.tsx | 1 + 13 files changed, 329 insertions(+), 77 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/card_comments.tsx create mode 100644 x-pack/plugins/security_solution/public/management/components/artifact_entry_card/utils/get_formatted_comments.tsx diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_card.test.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_card.test.tsx index 52299679ec87b..bde1961dd782d 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_card.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_card.test.tsx @@ -25,7 +25,7 @@ describe.each([ ) => ReturnType; beforeEach(() => { - item = generateItem(); + item = generateItem() as AnyArtifact; appTestContext = createAppRootMockRenderer(); render = (props = {}) => { renderResult = appTestContext.render( @@ -77,13 +77,31 @@ describe.each([ expect(renderResult.getByTestId('testCard-description').textContent).toEqual(item.description); }); + it("shouldn't display description", async () => { + render({ hideDescription: true }); + expect(renderResult.queryByTestId('testCard-description')).toBeNull(); + }); + it('should display default empty value if description does not exist', async () => { item.description = undefined; render(); - expect(renderResult.getByTestId('testCard-description').textContent).toEqual('—'); }); + it('should display comments if one exists', async () => { + render(); + if (isTrustedApp(item)) { + expect(renderResult.queryByTestId('testCard-comments')).toBeNull(); + } else { + expect(renderResult.queryByTestId('testCard-comments')).not.toBeNull(); + } + }); + + it("shouldn't display comments", async () => { + render({ hideComments: true }); + expect(renderResult.queryByTestId('testCard-comments')).toBeNull(); + }); + it('should display OS and criteria conditions', () => { render(); diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_card.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_card.tsx index d9709c64e092d..bee9a63c9cf69 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_card.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_card.tsx @@ -16,10 +16,11 @@ import { useNormalizedArtifact } from './hooks/use_normalized_artifact'; import { useTestIdGenerator } from '../hooks/use_test_id_generator'; import { CardContainerPanel } from './components/card_container_panel'; import { CardSectionPanel } from './components/card_section_panel'; +import { CardComments } from './components/card_comments'; import { usePolicyNavLinks } from './hooks/use_policy_nav_links'; import { MaybeImmutable } from '../../../../common/endpoint/types'; -export interface ArtifactEntryCardProps extends CommonProps { +export interface CommonArtifactEntryCardProps extends CommonProps { item: MaybeImmutable; /** * The list of actions for the card. Will display an icon with the actions in a menu if defined. @@ -34,12 +35,27 @@ export interface ArtifactEntryCardProps extends CommonProps { policies?: MenuItemPropsByPolicyId; } +export interface ArtifactEntryCardProps extends CommonArtifactEntryCardProps { + // A flag to hide description section, false by default + hideDescription?: boolean; + // A flag to hide comments section, false by default + hideComments?: boolean; +} + /** * Display Artifact Items (ex. Trusted App, Event Filter, etc) as a card. * This component is a TS Generic that allows you to set what the Item type is */ export const ArtifactEntryCard = memo( - ({ item, policies, actions, 'data-test-subj': dataTestSubj, ...commonProps }) => { + ({ + item, + policies, + actions, + hideDescription = false, + hideComments = false, + 'data-test-subj': dataTestSubj, + ...commonProps + }) => { const artifact = useNormalizedArtifact(item as AnyArtifact); const getTestId = useTestIdGenerator(dataTestSubj); const policyNavLinks = usePolicyNavLinks(artifact, policies); @@ -63,11 +79,16 @@ export const ArtifactEntryCard = memo( - -

- {artifact.description || getEmptyValue()} -

-
+ {!hideDescription ? ( + +

+ {artifact.description || getEmptyValue()} +

+
+ ) : null} + {!hideComments ? ( + + ) : null} diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_collapsible_card.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_collapsible_card.tsx index 43572ea234d31..673504c18a9df 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_collapsible_card.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/artifact_entry_collapsible_card.tsx @@ -7,7 +7,7 @@ import React, { memo } from 'react'; import { EuiHorizontalRule } from '@elastic/eui'; -import { ArtifactEntryCardProps } from './artifact_entry_card'; +import { CommonArtifactEntryCardProps } from './artifact_entry_card'; import { CardContainerPanel } from './components/card_container_panel'; import { useNormalizedArtifact } from './hooks/use_normalized_artifact'; import { useTestIdGenerator } from '../hooks/use_test_id_generator'; @@ -15,7 +15,7 @@ import { CardSectionPanel } from './components/card_section_panel'; import { CriteriaConditions, CriteriaConditionsProps } from './components/criteria_conditions'; import { CardCompressedHeader } from './components/card_compressed_header'; -export interface ArtifactEntryCollapsibleCardProps extends ArtifactEntryCardProps { +export interface ArtifactEntryCollapsibleCardProps extends CommonArtifactEntryCardProps { onExpandCollapse: () => void; expanded?: boolean; } diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/card_comments.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/card_comments.tsx new file mode 100644 index 0000000000000..ce539554a722e --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/card_comments.tsx @@ -0,0 +1,68 @@ +/* + * 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 React, { memo, useMemo, useCallback, useState } from 'react'; +import { + CommonProps, + EuiAccordion, + EuiCommentList, + EuiCommentProps, + EuiButtonEmpty, + EuiSpacer, +} from '@elastic/eui'; +import { isEmpty } from 'lodash/fp'; +import { useTestIdGenerator } from '../../hooks/use_test_id_generator'; +import { CardActionsFlexItemProps } from './card_actions_flex_item'; +import { ArtifactInfo } from '../types'; +import { getFormattedComments } from '../utils/get_formatted_comments'; +import { SHOW_COMMENTS_LABEL, HIDE_COMMENTS_LABEL } from './translations'; + +export interface CardCommentsProps + extends CardActionsFlexItemProps, + Pick { + comments: ArtifactInfo['comments']; +} + +export const CardComments = memo( + ({ comments, 'data-test-subj': dataTestSubj }) => { + const getTestId = useTestIdGenerator(dataTestSubj); + + const [showComments, setShowComments] = useState(false); + const onCommentsClick = useCallback((): void => { + setShowComments(!showComments); + }, [setShowComments, showComments]); + const formattedComments = useMemo((): EuiCommentProps[] => { + return getFormattedComments(comments); + }, [comments]); + + const buttonText = useMemo( + () => + showComments ? HIDE_COMMENTS_LABEL(comments.length) : SHOW_COMMENTS_LABEL(comments.length), + [comments.length, showComments] + ); + + return !isEmpty(comments) ? ( +
+ + + {buttonText} + + + + + +
+ ) : null; + } +); + +CardComments.displayName = 'CardComments'; diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/criteria_conditions.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/criteria_conditions.tsx index 292c06c4f5b8c..260db313ced36 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/criteria_conditions.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/criteria_conditions.tsx @@ -5,8 +5,9 @@ * 2.0. */ -import React, { memo } from 'react'; -import { CommonProps, EuiExpression } from '@elastic/eui'; +import React, { memo, useCallback } from 'react'; +import { CommonProps, EuiExpression, EuiToken, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import styled from 'styled-components'; import { ListOperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { CONDITION_OS, @@ -21,7 +22,7 @@ import { CONDITION_OPERATOR_TYPE_EXISTS, CONDITION_OPERATOR_TYPE_LIST, } from './translations'; -import { ArtifactInfo } from '../types'; +import { ArtifactInfo, ArtifactInfoEntry } from '../types'; import { useTestIdGenerator } from '../../hooks/use_test_id_generator'; const OS_LABELS = Object.freeze({ @@ -39,6 +40,15 @@ const OPERATOR_TYPE_LABELS = Object.freeze({ [ListOperatorTypeEnum.LIST]: CONDITION_OPERATOR_TYPE_LIST, }); +const EuiFlexGroupNested = styled(EuiFlexGroup)` + margin-left: ${({ theme }) => theme.eui.spacerSizes.l}; +`; + +const EuiFlexItemNested = styled(EuiFlexItem)` + margin-bottom: 6px !important; + margin-top: 6px !important; +`; + export type CriteriaConditionsProps = Pick & Pick; @@ -46,6 +56,44 @@ export const CriteriaConditions = memo( ({ os, entries, 'data-test-subj': dataTestSubj }) => { const getTestId = useTestIdGenerator(dataTestSubj); + const getNestedEntriesContent = useCallback( + (type: string, nestedEntries: ArtifactInfoEntry[]) => { + if (type === 'nested' && nestedEntries.length) { + return nestedEntries.map( + ({ field: nestedField, type: nestedType, value: nestedValue }) => { + return ( + + + + + + + + + + + + ); + } + ); + } + }, + [getTestId] + ); + return (
@@ -57,7 +105,7 @@ export const CriteriaConditions = memo( />
- {entries.map(({ field, type, value }) => { + {entries.map(({ field, type, value, entries: nestedEntries = [] }) => { return (
@@ -67,6 +115,7 @@ export const CriteriaConditions = memo( } value={value} /> + {getNestedEntriesContent(type, nestedEntries)}
); })} diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/translations.ts b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/translations.ts index d98f4589027d4..512724b66d50e 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/translations.ts +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/translations.ts @@ -114,3 +114,15 @@ export const COLLAPSE_ACTION = i18n.translate( defaultMessage: 'Collapse', } ); + +export const SHOW_COMMENTS_LABEL = (count: number = 0) => + i18n.translate('xpack.securitySolution.artifactCard.comments.label.show', { + defaultMessage: 'Show comments ({count})', + values: { count }, + }); + +export const HIDE_COMMENTS_LABEL = (count: number = 0) => + i18n.translate('xpack.securitySolution.artifactCard.comments.label.hide', { + defaultMessage: 'Hide comments ({count})', + values: { count }, + }); diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/test_utils.ts b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/test_utils.ts index d9ff23b3a2c6a..d7d8899b005ed 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/test_utils.ts +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/test_utils.ts @@ -6,6 +6,7 @@ */ import { cloneDeep } from 'lodash'; +import uuid from 'uuid'; import { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; import { TrustedAppGenerator } from '../../../../common/endpoint/data_generators/trusted_app_generator'; import { getExceptionListItemSchemaMock } from '../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; @@ -54,6 +55,14 @@ export const getExceptionProviderMock = (): ExceptionListItemSchema => { }, ], tags: ['policy:all'], + comments: [ + { + id: uuid.v4(), + comment: 'test', + created_at: new Date().toISOString(), + created_by: 'Justa', + }, + ], }) ); }; diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/types.ts b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/types.ts index c506c62ac4351..fe50a15190f11 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/types.ts +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/types.ts @@ -10,6 +10,13 @@ import { EffectScope, TrustedApp } from '../../../../common/endpoint/types'; import { ContextMenuItemNavByRouterProps } from '../context_menu_with_router_support/context_menu_item_nav_by_router'; export type AnyArtifact = ExceptionListItemSchema | TrustedApp; +export interface ArtifactInfoEntry { + field: string; + type: string; + operator: string; + value: string; +} +type ArtifactInfoEntries = ArtifactInfoEntry & { entries?: ArtifactInfoEntry[] }; /** * A normalized structured that is used internally through out the card's components. @@ -17,16 +24,11 @@ export type AnyArtifact = ExceptionListItemSchema | TrustedApp; export interface ArtifactInfo extends Pick< ExceptionListItemSchema, - 'name' | 'created_at' | 'updated_at' | 'created_by' | 'updated_by' | 'description' + 'name' | 'created_at' | 'updated_at' | 'created_by' | 'updated_by' | 'description' | 'comments' > { effectScope: EffectScope; os: string; - entries: Array<{ - field: string; - type: string; - operator: string; - value: string; - }>; + entries: ArtifactInfoEntries[]; } export interface MenuItemPropsByPolicyId { diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/utils/get_formatted_comments.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/utils/get_formatted_comments.tsx new file mode 100644 index 0000000000000..c9e96c5ce9ec1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/utils/get_formatted_comments.tsx @@ -0,0 +1,34 @@ +/* + * 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 React from 'react'; +import { EuiAvatar, EuiText, EuiCommentProps } from '@elastic/eui'; +import styled from 'styled-components'; +import { CommentsArray } from '@kbn/securitysolution-io-ts-list-types'; +import { COMMENT_EVENT } from '../../../../common/components/exceptions/translations'; +import { FormattedRelativePreferenceDate } from '../../../../common/components/formatted_date'; + +const CustomEuiAvatar = styled(EuiAvatar)` + background-color: ${({ theme }) => theme.eui.euiColorLightShade} !important; +`; + +/** + * Formats ExceptionItem.comments into EuiCommentList format + * + * @param comments ExceptionItem.comments + */ +export const getFormattedComments = (comments: CommentsArray): EuiCommentProps[] => { + return comments.map((commentItem) => ({ + username: commentItem.created_by, + timestamp: ( + + ), + event: COMMENT_EVENT, + timelineIcon: , + children: {commentItem.comment}, + })); +}; diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/utils/map_to_artifact_info.ts b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/utils/map_to_artifact_info.ts index dd9e90db327ee..5969cf9d043b4 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/utils/map_to_artifact_info.ts +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/utils/map_to_artifact_info.ts @@ -24,6 +24,7 @@ export const mapToArtifactInfo = (_item: MaybeImmutable): ArtifactI updated_at, updated_by, description, + comments: isTrustedApp(item) ? [] : item.comments, entries: entries as unknown as ArtifactInfo['entries'], os: isTrustedApp(item) ? item.os : getOsFromExceptionItem(item), effectScope: isTrustedApp(item) ? item.effectScope : getEffectScopeFromExceptionItem(item), diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.test.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.test.tsx index 37269108aa10f..0729f95bb44a9 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.test.tsx @@ -109,19 +109,15 @@ describe('When on the Event Filters List Page', () => { it('should render expected fields on card', async () => { render(); await dataReceived(); - const eventMeta = ([] as HTMLElement[]).map.call( - renderResult.getByTestId('exceptionsViewerItemDetails').querySelectorAll('dd'), - (ele) => ele.textContent - ); - expect(eventMeta).toEqual([ - 'some name', - 'April 20th 2020 @ 11:25:31', - 'some user', - 'April 20th 2020 @ 11:25:31', - 'some user', - 'some description', - ]); + [ + ['subHeader-touchedBy-createdBy-value', 'some user'], + ['subHeader-touchedBy-updatedBy-value', 'some user'], + ['header-created-value', '4/20/2020'], + ['header-updated-value', '4/20/2020'], + ].forEach(([suffix, value]) => + expect(renderResult.getByTestId(`eventFilterCard-${suffix}`).textContent).toEqual(value) + ); }); it('should show API error if one is encountered', async () => { @@ -143,8 +139,13 @@ describe('When on the Event Filters List Page', () => { it('should show modal when delete is clicked on a card', async () => { render(); await dataReceived(); - act(() => { - fireEvent.click(renderResult.getByTestId('exceptionsViewerDeleteBtn')); + + await act(async () => { + (await renderResult.findAllByTestId('eventFilterCard-header-actions-button'))[0].click(); + }); + + await act(async () => { + (await renderResult.findByTestId('deleteEventFilterAction')).click(); }); expect( diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.tsx index e206f85df6548..db4e5dbb531b2 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/event_filters_list_page.tsx @@ -36,16 +36,20 @@ import { } from '../store/selector'; import { PaginatedContent, PaginatedContentProps } from '../../../components/paginated_content'; import { Immutable, ListPageRouteState } from '../../../../../common/endpoint/types'; +import { ExceptionItem } from '../../../../common/components/exceptions/viewer/exception_item'; import { - ExceptionItem, - ExceptionItemProps, -} from '../../../../common/components/exceptions/viewer/exception_item'; + AnyArtifact, + ArtifactEntryCard, + ArtifactEntryCardProps, +} from '../../../components/artifact_entry_card'; import { EventFilterDeleteModal } from './components/event_filter_delete_modal'; import { SearchExceptions } from '../../../components/search_exceptions'; import { BackToExternalAppButton } from '../../../components/back_to_external_app_button'; import { ABOUT_EVENT_FILTERS } from './translations'; +type ArtifactEntryCardType = typeof ArtifactEntryCard; + type EventListPaginatedContent = PaginatedContentProps< Immutable, typeof ExceptionItem @@ -61,6 +65,20 @@ const AdministrationListPage = styled(_AdministrationListPage)` } `; +const EDIT_EVENT_FILTER_ACTION_LABEL = i18n.translate( + 'xpack.securitySolution.eventFilters.list.cardAction.edit', + { + defaultMessage: 'Edit event filter', + } +); + +const DELETE_EVENT_FILTER_ACTION_LABEL = i18n.translate( + 'xpack.securitySolution.eventFilters.list.cardAction.delete', + { + defaultMessage: 'Delete event filter', + } +); + export const EventFiltersListPage = memo(() => { const { state: routeState } = useLocation(); const history = useHistory(); @@ -133,41 +151,6 @@ export const EventFiltersListPage = memo(() => { [navigateCallback] ); - const handleItemEdit: ExceptionItemProps['onEditException'] = useCallback( - (item: ExceptionListItemSchema) => { - navigateCallback({ - show: 'edit', - id: item.id, - }); - }, - [navigateCallback] - ); - - const handleItemDelete: ExceptionItemProps['onDeleteException'] = useCallback( - ({ id }) => { - dispatch({ - type: 'eventFilterForDeletion', - // Casting below needed due to error around the comments array needing to be mutable - payload: listItems.find((item) => item.id === id)! as ExceptionListItemSchema, - }); - }, - [dispatch, listItems] - ); - - const handleItemComponentProps: EventListPaginatedContent['itemComponentProps'] = useCallback( - (exceptionItem) => ({ - exceptionItem: exceptionItem as ExceptionListItemSchema, - loadingItemIds: [], - commentsAccordionId: '', - onEditException: handleItemEdit, - onDeleteException: handleItemDelete, - showModified: true, - showName: true, - 'data-test-subj': `eventFilterCard`, - }), - [handleItemDelete, handleItemEdit] - ); - const handlePaginatedContentChange: EventListPaginatedContent['onChange'] = useCallback( ({ pageIndex, pageSize }) => { navigateCallback({ @@ -186,6 +169,59 @@ export const EventFiltersListPage = memo(() => { [navigateCallback, dispatch] ); + const artifactCardPropsPerItem = useMemo(() => { + const cachedCardProps: Record = {}; + + // Casting `listItems` below to remove the `Immutable<>` from it in order to prevent errors + // with common component's props + for (const eventFilter of listItems as ExceptionListItemSchema[]) { + let policies: ArtifactEntryCardProps['policies']; + + cachedCardProps[eventFilter.id] = { + item: eventFilter as AnyArtifact, + policies, + hideDescription: true, + 'data-test-subj': 'eventFilterCard', + actions: [ + { + icon: 'controlsHorizontal', + onClick: () => { + history.push( + getEventFiltersListPath({ + ...location, + show: 'edit', + id: eventFilter.id, + }) + ); + }, + 'data-test-subj': 'editEventFilterAction', + children: EDIT_EVENT_FILTER_ACTION_LABEL, + }, + { + icon: 'trash', + onClick: () => { + dispatch({ + type: 'eventFilterForDeletion', + payload: eventFilter, + }); + }, + 'data-test-subj': 'deleteEventFilterAction', + children: DELETE_EVENT_FILTER_ACTION_LABEL, + }, + ], + }; + } + + return cachedCardProps; + }, [dispatch, history, listItems, location]); + + const handleArtifactCardProps = useCallback( + (eventFilter: ExceptionListItemSchema) => { + return artifactCardPropsPerItem[eventFilter.id]; + }, + [artifactCardPropsPerItem] + ); + return ( { )} - , typeof ExceptionItem> + items={listItems} - ItemComponent={ExceptionItem} - itemComponentProps={handleItemComponentProps} + ItemComponent={ArtifactEntryCard} + itemComponentProps={handleArtifactCardProps} onChange={handlePaginatedContentChange} error={fetchError?.message} loading={isLoading} diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.tsx index ba09d0c7ee0cc..948b454f9cc00 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.tsx @@ -138,6 +138,7 @@ export const TrustedAppsGrid = memo(() => { cachedCardProps[trustedApp.id] = { item: trustedApp, policies, + hideComments: true, 'data-test-subj': 'trustedAppCard', actions: [ {