diff --git a/x-pack/plugins/security_solution/public/common/mock/mock_timelines_plugin.tsx b/x-pack/plugins/security_solution/public/common/mock/mock_timelines_plugin.tsx index 9a7577630434925..e2b92b0eeae4108 100644 --- a/x-pack/plugins/security_solution/public/common/mock/mock_timelines_plugin.tsx +++ b/x-pack/plugins/security_solution/public/common/mock/mock_timelines_plugin.tsx @@ -15,18 +15,4 @@ export const mockTimelines = { onBlur: jest.fn(), onKeyDown: jest.fn(), }), - getAddToCasePopover: jest - .fn() - .mockReturnValue(
{'Add to case'}
), - getAddToCaseAction: jest.fn(), - getAddToExistingCaseButton: jest.fn().mockReturnValue( -
- {'Add to existing case'} -
- ), - getAddToNewCaseButton: jest.fn().mockReturnValue( -
- {'Add to new case'} -
- ), }; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.test.tsx index 890175ac8daf9ab..ac4a09c01cc0623 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.test.tsx @@ -52,17 +52,6 @@ jest.mock('../../../../../common/lib/kibana', () => ({ useGetUserCasesPermissions: jest.fn(), })); -jest.mock( - '../../../../../../../timelines/public/components/actions/timeline/cases/add_to_case_action', - () => { - return { - AddToCasePopover: () => { - return
{'Add to case'}
; - }, - }; - } -); - describe('EventColumnView', () => { useIsExperimentalFeatureEnabledMock.mockReturnValue(false); (useShallowEqualSelector as jest.Mock).mockReturnValue(TimelineType.default); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx index 5a9f981988d5919..bcb4c01fa409f3d 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx @@ -61,10 +61,6 @@ jest.mock('../../../../common/lib/kibana', () => { onBlur: jest.fn(), onKeyDown: jest.fn(), }), - getAddToCasePopover: jest - .fn() - .mockReturnValue(
{'Add to case'}
), - getAddToCaseAction: jest.fn(), }, }, }), diff --git a/x-pack/plugins/timelines/public/components/actions/index.ts b/x-pack/plugins/timelines/public/components/actions/index.ts deleted file mode 100644 index 9464a33082a4951..000000000000000 --- a/x-pack/plugins/timelines/public/components/actions/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * 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. - */ - -export * from './timeline'; diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action.test.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action.test.tsx deleted file mode 100644 index 80ae1cfa4446566..000000000000000 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action.test.tsx +++ /dev/null @@ -1,195 +0,0 @@ -/* - * 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 { mount } from 'enzyme'; -import { - TestProviders, - mockGetAllCasesSelectorModal, - mockGetCreateCaseFlyout, -} from '../../../../mock'; -import { AddToCaseAction } from './add_to_case_action'; -import { SECURITY_SOLUTION_OWNER } from '../../../../../../cases/common'; -import { AddToCaseActionButton } from './add_to_case_action_button'; -import { ALERT_RULE_UUID } from '@kbn/rule-data-utils'; - -jest.mock('react-router-dom', () => ({ - useLocation: () => ({ - search: '', - }), -})); -jest.mock('./helpers'); - -describe('AddToCaseAction', () => { - const props = { - event: { - _id: 'test-id', - data: [], - ecs: { - _id: 'test-id', - _index: 'test-index', - signal: { rule: { id: ['rule-id'], name: ['rule-name'], false_positives: [] } }, - }, - }, - casePermissions: { - crud: true, - read: true, - }, - appId: 'securitySolutionUI', - owner: 'securitySolution', - onClose: () => null, - }; - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('it renders', () => { - const wrapper = mount( - - - - - ); - - expect(wrapper.find(`[data-test-subj="attach-alert-to-case-button"]`).exists()).toBeTruthy(); - }); - - it('it opens the context menu', () => { - const wrapper = mount( - - - - - ); - - wrapper.find(`[data-test-subj="attach-alert-to-case-button"]`).first().simulate('click'); - expect(wrapper.find(`[data-test-subj="add-new-case-item"]`).exists()).toBeTruthy(); - expect(wrapper.find(`[data-test-subj="add-existing-case-menu-item"]`).exists()).toBeTruthy(); - }); - - it('it opens the create case flyout', () => { - const wrapper = mount( - - - - - ); - - wrapper.find(`[data-test-subj="attach-alert-to-case-button"]`).first().simulate('click'); - wrapper.find(`[data-test-subj="add-new-case-item"]`).first().simulate('click'); - expect(mockGetCreateCaseFlyout).toHaveBeenCalled(); - }); - - it('it opens the all cases modal', () => { - const wrapper = mount( - - - - - ); - - wrapper.find(`[data-test-subj="attach-alert-to-case-button"]`).first().simulate('click'); - wrapper.find(`[data-test-subj="add-existing-case-menu-item"]`).first().simulate('click'); - - expect(mockGetAllCasesSelectorModal).toHaveBeenCalled(); - }); - - it('it set rule information as null when missing', () => { - const wrapper = mount( - - - - - ); - - wrapper.find(`[data-test-subj="attach-alert-to-case-button"]`).first().simulate('click'); - wrapper.find(`[data-test-subj="add-existing-case-menu-item"]`).first().simulate('click'); - expect(mockGetAllCasesSelectorModal.mock.calls[0][0].alertData).toEqual({ - alertId: 'test-id', - index: 'test-index', - rule: { - id: 'rule-id', - name: null, - }, - owner: SECURITY_SOLUTION_OWNER, - }); - }); - - it('disabled when event type is not supported', () => { - const wrapper = mount( - - - - - ); - - expect( - wrapper.find(`[data-test-subj="attach-alert-to-case-button"]`).first().prop('isDisabled') - ).toBeTruthy(); - }); - - it('hides the icon when user does not have crud permissions', () => { - const newProps = { - ...props, - casePermissions: { - crud: false, - read: true, - }, - }; - const wrapper = mount( - - - - - ); - - expect(wrapper.find(`[data-test-subj="attach-alert-to-case-button"]`).exists()).toBeFalsy(); - }); -}); diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action.tsx deleted file mode 100644 index 193d63e2e849c7f..000000000000000 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action.tsx +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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 } from 'react'; -import { useDispatch } from 'react-redux'; -import { - GetAllCasesSelectorModalProps, - GetCreateCaseFlyoutProps, -} from '../../../../../../cases/public'; -import { - CaseStatuses, - StatusAll, - CasesFeatures, - CommentType, -} from '../../../../../../cases/common'; -import { TimelineItem } from '../../../../../common/search_strategy'; -import { useAddToCase, normalizedEventFields } from '../../../../hooks/use_add_to_case'; -import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public'; -import { TimelinesStartServices } from '../../../../types'; -import { setOpenAddToExistingCase, setOpenAddToNewCase } from '../../../../store/t_grid/actions'; - -export interface AddToCaseActionProps { - event?: TimelineItem; - useInsertTimeline?: Function; - casePermissions: { - crud: boolean; - read: boolean; - } | null; - appId: string; - owner: string; - onClose?: Function; - casesFeatures?: CasesFeatures; -} - -const AddToCaseActionComponent: React.FC = ({ - event, - useInsertTimeline, - casePermissions, - appId, - owner, - onClose, - casesFeatures, -}) => { - const eventId = event?.ecs._id ?? ''; - const eventIndex = event?.ecs._index ?? ''; - const dispatch = useDispatch(); - const { cases } = useKibana().services; - const { - onCaseClicked, - onCaseSuccess, - onCaseCreated, - isAllCaseModalOpen, - isCreateCaseFlyoutOpen, - } = useAddToCase({ event, casePermissions, appId, owner, onClose }); - - const allCasesSelectorModalProps: GetAllCasesSelectorModalProps = useMemo(() => { - const { ruleId, ruleName } = normalizedEventFields(event); - return { - alertData: { - alertId: eventId, - index: eventIndex ?? '', - rule: { - id: ruleId, - name: ruleName, - }, - owner, - }, - hooks: { - useInsertTimeline, - }, - hiddenStatuses: [CaseStatuses.closed, StatusAll], - onRowClick: onCaseClicked, - updateCase: onCaseSuccess, - userCanCrud: casePermissions?.crud ?? false, - owner: [owner], - onClose: () => dispatch(setOpenAddToExistingCase({ id: eventId, isOpen: false })), - }; - }, [ - casePermissions?.crud, - onCaseSuccess, - onCaseClicked, - eventId, - eventIndex, - dispatch, - owner, - useInsertTimeline, - event, - ]); - - const closeCaseFlyoutOpen = useCallback(() => { - dispatch(setOpenAddToNewCase({ id: eventId, isOpen: false })); - }, [dispatch, eventId]); - - const createCaseFlyoutProps: GetCreateCaseFlyoutProps = useMemo(() => { - const { ruleId, ruleName } = normalizedEventFields(event); - const attachments = [ - { - alertId: eventId, - index: eventIndex ?? '', - rule: { - id: ruleId, - name: ruleName, - }, - owner, - type: CommentType.alert as const, - }, - ]; - return { - afterCaseCreated: onCaseCreated, - onClose: closeCaseFlyoutOpen, - onSuccess: onCaseSuccess, - useInsertTimeline, - owner: [owner], - userCanCrud: casePermissions?.crud ?? false, - features: casesFeatures, - attachments, - }; - }, [ - event, - eventId, - eventIndex, - owner, - onCaseCreated, - closeCaseFlyoutOpen, - onCaseSuccess, - useInsertTimeline, - casePermissions?.crud, - casesFeatures, - ]); - - return ( - <> - {isCreateCaseFlyoutOpen && cases.getCreateCaseFlyout(createCaseFlyoutProps)} - {isAllCaseModalOpen && cases.getAllCasesSelectorModal(allCasesSelectorModalProps)} - - ); -}; -AddToCaseActionComponent.displayName = 'AddToCaseAction'; - -export const AddToCaseAction = memo(AddToCaseActionComponent); - -// eslint-disable-next-line import/no-default-export -export default AddToCaseAction; diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action_button.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action_button.tsx deleted file mode 100644 index 9757bd94b174680..000000000000000 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_case_action_button.tsx +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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 } from 'react'; -import { - EuiPopover, - EuiButtonIcon, - EuiContextMenuPanel, - EuiText, - EuiContextMenuItem, - EuiToolTip, -} from '@elastic/eui'; -import { AddToCaseActionProps } from './add_to_case_action'; -import { useAddToCase } from '../../../../hooks/use_add_to_case'; -import { ActionIconItem } from '../../action_icon_item'; -import * as i18n from './translations'; - -const AddToCaseActionButtonComponent: React.FC = ({ - event, - useInsertTimeline, - casePermissions, - appId, - owner, - onClose, -}) => { - const { - addNewCaseClick, - addExistingCaseClick, - isDisabled, - userCanCrud, - isEventSupported, - openPopover, - closePopover, - isPopoverOpen, - } = useAddToCase({ event, useInsertTimeline, casePermissions, appId, owner, onClose }); - const tooltipContext = userCanCrud - ? isEventSupported - ? i18n.ACTION_ADD_TO_CASE_TOOLTIP - : i18n.UNSUPPORTED_EVENTS_MSG - : i18n.PERMISSIONS_MSG; - const items = useMemo( - () => [ - - {i18n.ACTION_ADD_NEW_CASE} - , - - {i18n.ACTION_ADD_EXISTING_CASE} - , - ], - [addExistingCaseClick, addNewCaseClick, isDisabled] - ); - - const button = useMemo( - () => ( - - - - ), - [isDisabled, openPopover, tooltipContext] - ); - - return ( - <> - {userCanCrud && ( - - - - - - )} - - ); -}; - -export const AddToCaseActionButton = memo(AddToCaseActionButtonComponent); - -// eslint-disable-next-line import/no-default-export -export default AddToCaseActionButton; diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_existing_case_button.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_existing_case_button.tsx deleted file mode 100644 index 4d19a890968820f..000000000000000 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_existing_case_button.tsx +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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 } from 'react'; -import { EuiContextMenuItem } from '@elastic/eui'; - -import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public'; -import { TimelinesStartServices } from '../../../../types'; -import { useAddToCase } from '../../../../hooks/use_add_to_case'; -import { AddToCaseActionProps } from './add_to_case_action'; -import * as i18n from './translations'; - -interface AddToCaseActionButtonProps extends AddToCaseActionProps { - ariaLabel?: string; -} - -const AddToCaseActionButtonComponent: React.FC = ({ - ariaLabel = i18n.ACTION_ADD_TO_CASE_ARIA_LABEL, - event, - useInsertTimeline, - casePermissions, - appId, - owner, - onClose, -}) => { - const { onCaseSuccess, onCaseClicked, isDisabled, userCanCrud, caseAttachments } = useAddToCase({ - event, - useInsertTimeline, - casePermissions, - appId, - owner, - onClose, - }); - const { cases } = useKibana().services; - const addToCaseModal = cases.hooks.getUseCasesAddToExistingCaseModal({ - attachments: caseAttachments, - updateCase: onCaseSuccess, - onRowClick: onCaseClicked, - }); - - // TODO To be further refactored and moved to cases plugins - // https://github.com/elastic/kibana/issues/123183 - const handleClick = () => { - // close the popover - if (onClose) { - onClose(); - } - addToCaseModal.open(); - }; - - return ( - <> - {userCanCrud && ( - - {i18n.ACTION_ADD_EXISTING_CASE} - - )} - - ); -}; - -export const AddToExistingCaseButton = memo(AddToCaseActionButtonComponent); - -// eslint-disable-next-line import/no-default-export -export default AddToExistingCaseButton; diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_new_case_button.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_new_case_button.tsx deleted file mode 100644 index eb83cb21aea6eac..000000000000000 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_new_case_button.tsx +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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 } from 'react'; -import { EuiContextMenuItem } from '@elastic/eui'; - -import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public'; -import { TimelinesStartServices } from '../../../../types'; -import { useAddToCase } from '../../../../hooks/use_add_to_case'; -import { AddToCaseActionProps } from './add_to_case_action'; -import * as i18n from './translations'; - -export interface AddToNewCaseButtonProps extends AddToCaseActionProps { - ariaLabel?: string; -} - -const AddToNewCaseButtonComponent: React.FC = ({ - ariaLabel = i18n.ACTION_ADD_TO_CASE_ARIA_LABEL, - event, - useInsertTimeline, - casePermissions, - appId, - owner, - onClose, -}) => { - const { isDisabled, userCanCrud, caseAttachments, onCaseSuccess, onCaseCreated } = useAddToCase({ - event, - useInsertTimeline, - casePermissions, - appId, - owner, - onClose, - }); - const { cases } = useKibana().services; - const createCaseFlyout = cases.hooks.getUseCasesAddToNewCaseFlyout({ - attachments: caseAttachments, - afterCaseCreated: onCaseCreated, - onSuccess: onCaseSuccess, - }); - - // TODO To be further refactored and moved to cases plugins - // https://github.com/elastic/kibana/issues/123183 - const handleClick = () => { - // close the popover - if (onClose) { - onClose(); - } - createCaseFlyout.open(); - }; - - return ( - <> - {userCanCrud && ( - - {i18n.ACTION_ADD_NEW_CASE} - - )} - - ); -}; -AddToNewCaseButtonComponent.displayName = 'AddToNewCaseButton'; - -export const AddToNewCaseButton = memo(AddToNewCaseButtonComponent); - -// eslint-disable-next-line import/no-default-export -export default AddToNewCaseButton; diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/helpers.test.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/helpers.test.tsx deleted file mode 100644 index efb11393a42448b..000000000000000 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/helpers.test.tsx +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 'jest-styled-components'; -import type { MockedKeys } from '@kbn/utility-types/jest'; -import { CoreStart } from 'kibana/public'; -import { coreMock } from 'src/core/public/mocks'; -import type { IToasts } from '../../../../../../../../src/core/public'; - -import { createUpdateSuccessToaster } from './helpers'; -import { Case } from '../../../../../../cases/common'; - -let mockCoreStart: MockedKeys; -let toasts: IToasts; -let toastsSpy: jest.SpyInstance; - -const theCase = { - id: 'case-id', - title: 'My case', - settings: { - syncAlerts: true, - }, -} as Case; - -describe('helpers', () => { - beforeEach(() => { - mockCoreStart = coreMock.createStart(); - }); - - describe('createUpdateSuccessToaster', () => { - it('creates the correct toast when the sync alerts is on', () => { - const onViewCaseClick = jest.fn(); - - toasts = mockCoreStart.notifications.toasts; - toastsSpy = jest.spyOn(mockCoreStart.notifications.toasts, 'addSuccess'); - createUpdateSuccessToaster(toasts, theCase, onViewCaseClick); - - expect(toastsSpy).toHaveBeenCalled(); - }); - }); -}); diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/helpers.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/helpers.tsx deleted file mode 100644 index 71e2f41a5288a8f..000000000000000 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/helpers.tsx +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 styled from 'styled-components'; -import { ToasterContent } from './toaster_content'; -import * as i18n from './translations'; -import type { Case } from '../../../../../../cases/common'; -import type { ToastsStart, Toast } from '../../../../../../../../src/core/public'; -import { toMountPoint } from '../../../../../../../../src/plugins/kibana_react/public'; - -const LINE_CLAMP = 3; - -const Title = styled.span` - text-overflow: ellipsis; - display: -webkit-box; - -webkit-line-clamp: ${LINE_CLAMP}; - -webkit-box-orient: vertical; - overflow: hidden; -`; - -export const createUpdateSuccessToaster = ( - toasts: ToastsStart, - theCase: Case, - onViewCaseClick: (id: string) => void -): Toast => { - return toasts.addSuccess({ - color: 'success', - iconType: 'check', - title: toMountPoint({i18n.CASE_CREATED_SUCCESS_TOAST(theCase.title)}), - text: toMountPoint( - - ), - }); -}; diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/index.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/index.tsx deleted file mode 100644 index bb3bd63e316ed55..000000000000000 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/index.tsx +++ /dev/null @@ -1,11 +0,0 @@ -/* - * 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. - */ - -export * from './add_to_case_action'; -export * from './toaster_content'; -export * from './add_to_existing_case_button'; -export * from './add_to_new_case_button'; diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/toaster_content.test.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/toaster_content.test.tsx deleted file mode 100644 index fd20366e7891f54..000000000000000 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/toaster_content.test.tsx +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 { mount } from 'enzyme'; - -import { ToasterContent } from './toaster_content'; - -describe('ToasterContent', () => { - const onViewCaseClick = jest.fn(); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('renders with syncAlerts=true', () => { - const wrapper = mount( - - ); - - expect(wrapper.find('[data-test-subj="toaster-content-case-view-link"]').exists()).toBeTruthy(); - expect(wrapper.find('[data-test-subj="toaster-content-sync-text"]').exists()).toBeTruthy(); - }); - - it('renders with syncAlerts=false', () => { - const wrapper = mount( - - ); - - expect(wrapper.find('[data-test-subj="toaster-content-case-view-link"]').exists()).toBeTruthy(); - expect(wrapper.find('[data-test-subj="toaster-content-sync-text"]').exists()).toBeFalsy(); - }); - - it('calls onViewCaseClick', () => { - const wrapper = mount( - - ); - - wrapper.find('[data-test-subj="toaster-content-case-view-link"]').first().simulate('click'); - expect(onViewCaseClick).toHaveBeenCalled(); - }); -}); diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/toaster_content.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/toaster_content.tsx deleted file mode 100644 index 147dd3f5e8399b3..000000000000000 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/toaster_content.tsx +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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, useCallback } from 'react'; -import { EuiButtonEmpty, EuiText } from '@elastic/eui'; -import styled from 'styled-components'; - -import * as i18n from './translations'; - -const EuiTextStyled = styled(EuiText)` - ${({ theme }) => ` - margin-bottom: ${theme.eui?.paddingSizes?.s ?? 8}px; - `} -`; - -interface Props { - caseId: string; - syncAlerts: boolean; - onViewCaseClick: (id: string) => void; -} - -const ToasterContentComponent: React.FC = ({ caseId, syncAlerts, onViewCaseClick }) => { - const onClick = useCallback(() => onViewCaseClick(caseId), [caseId, onViewCaseClick]); - return ( - <> - {syncAlerts && ( - - {i18n.CASE_CREATED_SUCCESS_TOAST_TEXT} - - )} - - {i18n.VIEW_CASE} - - - ); -}; - -export const ToasterContent = memo(ToasterContentComponent); diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/translations.ts b/x-pack/plugins/timelines/public/components/actions/timeline/cases/translations.ts deleted file mode 100644 index df0dfb9048ace23..000000000000000 --- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/translations.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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 { i18n } from '@kbn/i18n'; - -export const ACTION_ADD_CASE = i18n.translate('xpack.timelines.cases.timeline.actions.addCase', { - defaultMessage: 'Add to case', -}); - -export const ACTION_ADD_NEW_CASE = i18n.translate( - 'xpack.timelines.cases.timeline.actions.addNewCase', - { - defaultMessage: 'Add to new case', - } -); - -export const ACTION_ADD_EXISTING_CASE = i18n.translate( - 'xpack.timelines.cases.timeline.actions.addExistingCase', - { - defaultMessage: 'Add to existing case', - } -); - -export const ACTION_ADD_TO_CASE_ARIA_LABEL = i18n.translate( - 'xpack.timelines.cases.timeline.actions.addToCaseAriaLabel', - { - defaultMessage: 'Attach alert to case', - } -); - -export const ACTION_ADD_TO_CASE_TOOLTIP = i18n.translate( - 'xpack.timelines.cases.timeline.actions.addToCaseTooltip', - { - defaultMessage: 'Add to case', - } -); - -export const CASE_CREATED_SUCCESS_TOAST = (title: string) => - i18n.translate('xpack.timelines.cases.timeline.actions.caseCreatedSuccessToast', { - values: { title }, - defaultMessage: 'An alert has been added to "{title}"', - }); - -export const CASE_CREATED_SUCCESS_TOAST_TEXT = i18n.translate( - 'xpack.timelines.cases.timeline.actions.caseCreatedSuccessToastText', - { - defaultMessage: 'Alerts in this case have their status synched with the case status', - } -); - -export const VIEW_CASE = i18n.translate( - 'xpack.timelines.cases.timeline.actions.caseCreatedSuccessToastViewCaseLink', - { - defaultMessage: 'View Case', - } -); - -export const PERMISSIONS_MSG = i18n.translate( - 'xpack.timelines.cases.timeline.actions.permissionsMessage', - { - defaultMessage: - 'You are currently missing the required permissions to attach alerts to cases. Please contact your administrator for further assistance.', - } -); - -export const UNSUPPORTED_EVENTS_MSG = i18n.translate( - 'xpack.timelines.cases.timeline.actions.unsupportedEventsMessage', - { - defaultMessage: 'This event cannot be attached to a case', - } -); diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/index.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/index.tsx deleted file mode 100644 index c5a69fd5e57451b..000000000000000 --- a/x-pack/plugins/timelines/public/components/actions/timeline/index.tsx +++ /dev/null @@ -1,8 +0,0 @@ -/* - * 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. - */ - -export * from './cases'; diff --git a/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx index f0488d26f5f16e3..be71d159eafca3d 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx @@ -8,7 +8,7 @@ import { EuiFlexItem, EuiFlexGroup } from '@elastic/eui'; import { isEmpty } from 'lodash/fp'; import React, { useEffect, useMemo, useState, useRef } from 'react'; import styled from 'styled-components'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { Filter, Query } from '@kbn/es-query'; import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; @@ -39,7 +39,6 @@ import { LastUpdatedAt } from '../..'; import { SELECTOR_TIMELINE_GLOBAL_CONTAINER, UpdatedFlexItem, UpdatedFlexGroup } from '../styles'; import { InspectButton, InspectButtonContainer } from '../../inspect'; import { useFetchIndex } from '../../../container/source'; -import { AddToCaseAction } from '../../actions/timeline/cases/add_to_case_action'; import { TGridLoading, TGridEmpty, TimelineContext } from '../shared'; const FullWidthFlexGroup = styled(EuiFlexGroup)<{ $visible: boolean }>` @@ -76,16 +75,7 @@ const ScrollableFlexItem = styled(EuiFlexItem)` overflow: auto; `; -const casesFeatures = { alerts: { sync: false } }; - export interface TGridStandaloneProps { - appId: string; - casesOwner: string; - casePermissions: { - crud: boolean; - read: boolean; - } | null; - afterCaseSelection?: Function; columns: ColumnHeaderOptions[]; dataViewId?: string | null; defaultCellActions?: TGridCellAction[]; @@ -127,10 +117,6 @@ export interface TGridStandaloneProps { } const TGridStandaloneComponent: React.FC = ({ - afterCaseSelection, - appId, - casesOwner, - casePermissions, columns, dataViewId = null, defaultCellActions, @@ -272,26 +258,6 @@ const TGridStandaloneComponent: React.FC = ({ ); const hasAlerts = totalCountMinusDeleted > 0; - const activeCaseFlowId = useSelector((state: State) => tGridSelectors.activeCaseFlowId(state)); - const selectedEvent = useMemo(() => { - const matchedEvent = events.find((event) => event.ecs._id === activeCaseFlowId); - if (matchedEvent) { - return matchedEvent; - } else { - return undefined; - } - }, [events, activeCaseFlowId]); - - const addToCaseActionProps = useMemo(() => { - return { - event: selectedEvent, - casePermissions: casePermissions ?? null, - appId, - owner: casesOwner, - onClose: afterCaseSelection, - }; - }, [appId, casePermissions, afterCaseSelection, selectedEvent, casesOwner]); - const nonDeletedEvents = useMemo( () => events.filter((e) => !deletedEventIds.includes(e._id)), [deletedEventIds, events] @@ -425,7 +391,6 @@ const TGridStandaloneComponent: React.FC = ({ ) : null} - ); diff --git a/x-pack/plugins/timelines/public/hooks/use_add_to_case.test.ts b/x-pack/plugins/timelines/public/hooks/use_add_to_case.test.ts deleted file mode 100644 index 5b654f40deea66b..000000000000000 --- a/x-pack/plugins/timelines/public/hooks/use_add_to_case.test.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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 { normalizedEventFields } from './use_add_to_case'; -import { ALERT_RULE_NAME, ALERT_RULE_UUID } from '@kbn/rule-data-utils'; -import { merge } from 'lodash'; - -const defaultArgs = { - _id: 'test-id', - data: [ - { field: '@timestamp', value: ['2018-11-05T19:03:25.937Z'] }, - { field: ALERT_RULE_UUID, value: ['data-rule-id'] }, - { field: ALERT_RULE_NAME, value: ['data-rule-name'] }, - ], - ecs: { - _id: 'test-id', - _index: 'test-index', - signal: { rule: { id: ['rule-id'], name: ['rule-name'], false_positives: [] } }, - }, -}; -describe('normalizedEventFields', () => { - it('uses rule data when provided', () => { - const result = normalizedEventFields(defaultArgs); - expect(result).toEqual({ - ruleId: 'data-rule-id', - ruleName: 'data-rule-name', - }); - }); - const makeObj = (s: string, v: string[]) => { - const keys = s.split('.'); - return keys - .reverse() - .reduce((prev, current, i) => (i === 0 ? { [current]: v } : { [current]: { ...prev } }), {}); - }; - it('uses rule/ecs combo Xavier thinks is a thing but Steph has yet to see', () => { - const args = { - ...defaultArgs, - data: [], - ecs: { - _id: 'string', - ...merge( - makeObj(ALERT_RULE_UUID, ['xavier-rule-id']), - makeObj(ALERT_RULE_NAME, ['xavier-rule-name']) - ), - }, - }; - const result = normalizedEventFields(args); - expect(result).toEqual({ - ruleId: 'xavier-rule-id', - ruleName: 'xavier-rule-name', - }); - }); - it('falls back to use ecs data', () => { - const result = normalizedEventFields({ ...defaultArgs, data: [] }); - expect(result).toEqual({ - ruleId: 'rule-id', - ruleName: 'rule-name', - }); - }); - it('returns null when all the data is bad', () => { - const result = normalizedEventFields({ ...defaultArgs, data: [], ecs: { _id: 'bad' } }); - expect(result).toEqual({ - ruleId: null, - ruleName: null, - }); - }); -}); diff --git a/x-pack/plugins/timelines/public/hooks/use_add_to_case.ts b/x-pack/plugins/timelines/public/hooks/use_add_to_case.ts deleted file mode 100644 index 63a7d07831c4b7a..000000000000000 --- a/x-pack/plugins/timelines/public/hooks/use_add_to_case.ts +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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 { get, isEmpty } from 'lodash/fp'; -import { useState, useCallback, useMemo, SyntheticEvent } from 'react'; -import { useDispatch } from 'react-redux'; -import { ALERT_RULE_NAME, ALERT_RULE_UUID } from '@kbn/rule-data-utils'; -import { useKibana } from '../../../../../src/plugins/kibana_react/public'; -import { Case, CommentType } from '../../../cases/common'; -import { TimelinesStartServices } from '../types'; -import { TimelineItem } from '../../common/search_strategy'; -import { tGridActions } from '../store/t_grid'; -import { useDeepEqualSelector } from './use_selector'; -import { createUpdateSuccessToaster } from '../components/actions/timeline/cases/helpers'; -import { AddToCaseActionProps } from '../components/actions'; -import { CaseAttachments, CasesDeepLinkId, generateCaseViewPath } from '../../../cases/public'; - -interface UseAddToCase { - addNewCaseClick: () => void; - addExistingCaseClick: () => void; - onCaseClicked: (theCase?: Case) => void; - onCaseSuccess: (theCase: Case) => Promise; - onCaseCreated: () => Promise; - isAllCaseModalOpen: boolean; - isDisabled: boolean; - userCanCrud: boolean; - isEventSupported: boolean; - openPopover: (event: SyntheticEvent) => void; - closePopover: () => void; - isPopoverOpen: boolean; - isCreateCaseFlyoutOpen: boolean; - caseAttachments?: CaseAttachments; -} - -export const useAddToCase = ({ - event, - casePermissions, - appId, - onClose, - owner, -}: AddToCaseActionProps): UseAddToCase => { - const eventId = event?.ecs._id ?? ''; - const dispatch = useDispatch(); - // TODO: use correct value in standalone or integrated. - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const timelineById = useDeepEqualSelector((state: any) => { - if (state.timeline) { - return state.timeline.timelineById[eventId]; - } else { - return state.timelineById[eventId]; - } - }); - const isAllCaseModalOpen = useMemo(() => { - if (timelineById) { - return timelineById.isAddToExistingCaseOpen; - } else { - return false; - } - }, [timelineById]); - const isCreateCaseFlyoutOpen = useMemo(() => { - if (timelineById) { - return timelineById.isCreateNewCaseOpen; - } else { - return false; - } - }, [timelineById]); - const { - application: { navigateToApp }, - notifications: { toasts }, - } = useKibana().services; - - const [isPopoverOpen, setIsPopoverOpen] = useState(false); - const openPopover = useCallback(() => setIsPopoverOpen(true), []); - const closePopover = useCallback(() => setIsPopoverOpen(false), []); - - const isEventSupported = useMemo(() => { - if (event !== undefined) { - if (event.data.some(({ field }) => field === 'kibana.alert.rule.uuid')) { - return true; - } - return !isEmpty(event.ecs.signal?.rule?.id ?? event.ecs.kibana?.alert?.rule?.uuid); - } else { - return false; - } - }, [event]); - - const userCanCrud = casePermissions?.crud ?? false; - const isDisabled = !userCanCrud || !isEventSupported; - - const onViewCaseClick = useCallback( - (id) => { - navigateToApp(appId, { - deepLinkId: CasesDeepLinkId.cases, - path: generateCaseViewPath({ detailName: id }), - }); - }, - [navigateToApp, appId] - ); - - const onCaseCreated = useCallback(async () => { - dispatch(tGridActions.setOpenAddToNewCase({ id: eventId, isOpen: false })); - }, [eventId, dispatch]); - - const onCaseSuccess = useCallback( - async (theCase: Case) => { - dispatch(tGridActions.setOpenAddToExistingCase({ id: eventId, isOpen: false })); - createUpdateSuccessToaster(toasts, theCase, onViewCaseClick); - }, - [onViewCaseClick, toasts, dispatch, eventId] - ); - const caseAttachments: CaseAttachments = useMemo(() => { - const eventIndex = event?.ecs._index ?? ''; - const { ruleId, ruleName } = normalizedEventFields(event); - const attachments = [ - { - alertId: eventId, - index: eventIndex ?? '', - rule: { - id: ruleId, - name: ruleName, - }, - owner, - type: CommentType.alert as const, - }, - ]; - return attachments; - }, [event, eventId, owner]); - - const onCaseClicked = useCallback( - (theCase?: Case) => { - /** - * No cases listed on the table. - * The user pressed the add new case table's button. - * We gonna open the create case modal. - */ - if (theCase == null) { - dispatch(tGridActions.setOpenAddToNewCase({ id: eventId, isOpen: true })); - } - dispatch(tGridActions.setOpenAddToExistingCase({ id: eventId, isOpen: false })); - }, - [dispatch, eventId] - ); - const addNewCaseClick = useCallback(() => { - closePopover(); - dispatch(tGridActions.setOpenAddToNewCase({ id: eventId, isOpen: true })); - if (onClose) { - onClose(); - } - }, [onClose, closePopover, dispatch, eventId]); - - const addExistingCaseClick = useCallback(() => { - closePopover(); - dispatch(tGridActions.setOpenAddToExistingCase({ id: eventId, isOpen: true })); - if (onClose) { - onClose(); - } - }, [onClose, closePopover, dispatch, eventId]); - return { - caseAttachments, - addNewCaseClick, - addExistingCaseClick, - onCaseClicked, - onCaseSuccess, - onCaseCreated, - isAllCaseModalOpen, - isDisabled, - userCanCrud, - isEventSupported, - openPopover, - closePopover, - isPopoverOpen, - isCreateCaseFlyoutOpen, - }; -}; - -export function normalizedEventFields(event?: TimelineItem) { - const ruleUuidData = event && event.data.find(({ field }) => field === ALERT_RULE_UUID); - const ruleNameData = event && event.data.find(({ field }) => field === ALERT_RULE_NAME); - const ruleUuidValueData = ruleUuidData && ruleUuidData.value && ruleUuidData.value[0]; - const ruleNameValueData = ruleNameData && ruleNameData.value && ruleNameData.value[0]; - - const ruleUuid = - ruleUuidValueData ?? - get(`ecs.${ALERT_RULE_UUID}[0]`, event) ?? - get(`ecs.signal.rule.id[0]`, event) ?? - null; - const ruleName = - ruleNameValueData ?? - get(`ecs.${ALERT_RULE_NAME}[0]`, event) ?? - get(`ecs.signal.rule.name[0]`, event) ?? - null; - - return { - ruleId: ruleUuid, - ruleName, - }; -} diff --git a/x-pack/plugins/timelines/public/methods/index.tsx b/x-pack/plugins/timelines/public/methods/index.tsx index c8b5e28c2d21efe..7d9ec4bcaab2750 100644 --- a/x-pack/plugins/timelines/public/methods/index.tsx +++ b/x-pack/plugins/timelines/public/methods/index.tsx @@ -7,14 +7,11 @@ import React, { lazy, Suspense } from 'react'; import { EuiLoadingSpinner } from '@elastic/eui'; -import { I18nProvider } from '@kbn/i18n-react'; import type { Store } from 'redux'; -import { Provider } from 'react-redux'; import type { Storage } from '../../../../../src/plugins/kibana_utils/public'; import type { DataPublicPluginStart } from '../../../../../src/plugins/data/public'; import type { TGridProps } from '../types'; import type { LastUpdatedAtProps, LoadingPanelProps, FieldBrowserProps } from '../components'; -import type { AddToCaseActionProps } from '../components/actions/timeline/cases/add_to_case_action'; import { initialTGridState } from '../store/t_grid/reducer'; import { createStore } from '../store/t_grid'; import { TGridLoading } from '../components/t_grid/shared'; @@ -84,76 +81,3 @@ export const getFieldsBrowserLazy = (props: FieldBrowserProps, { store }: { stor ); }; - -const AddToCaseLazy = lazy(() => import('../components/actions/timeline/cases/add_to_case_action')); -export const getAddToCaseLazy = ( - props: AddToCaseActionProps, - { store, storage, setStore }: { store: Store; storage: Storage; setStore: (store: Store) => void } -) => { - return ( - }> - - - - - - - ); -}; - -const AddToCasePopover = lazy( - () => import('../components/actions/timeline/cases/add_to_case_action_button') -); -export const getAddToCasePopoverLazy = ( - props: AddToCaseActionProps, - { store, storage, setStore }: { store: Store; storage: Storage; setStore: (store: Store) => void } -) => { - initializeStore({ store, storage, setStore }); - return ( - }> - - - - - - - ); -}; - -const AddToExistingButton = lazy( - () => import('../components/actions/timeline/cases/add_to_existing_case_button') -); -export const getAddToExistingCaseButtonLazy = ( - props: AddToCaseActionProps, - { store, storage, setStore }: { store: Store; storage: Storage; setStore: (store: Store) => void } -) => { - initializeStore({ store, storage, setStore }); - return ( - }> - - - - - - - ); -}; - -const AddToNewCaseButton = lazy( - () => import('../components/actions/timeline/cases/add_to_new_case_button') -); -export const getAddToNewCaseButtonLazy = ( - props: AddToCaseActionProps, - { store, storage, setStore }: { store: Store; storage: Storage; setStore: (store: Store) => void } -) => { - initializeStore({ store, storage, setStore }); - return ( - }> - - - - - - - ); -}; diff --git a/x-pack/plugins/timelines/public/mock/global_state.ts b/x-pack/plugins/timelines/public/mock/global_state.ts index fea8aa57b88dd36..955a612f89c1d4a 100644 --- a/x-pack/plugins/timelines/public/mock/global_state.ts +++ b/x-pack/plugins/timelines/public/mock/global_state.ts @@ -34,8 +34,6 @@ export const mockGlobalState: TimelineState = { 'packetbeat-*', 'winlogbeat-*', ], - isAddToExistingCaseOpen: false, - isCreateNewCaseOpen: false, isLoading: false, isSelectAllChecked: false, itemsPerPage: 5, diff --git a/x-pack/plugins/timelines/public/mock/mock_timeline_data.ts b/x-pack/plugins/timelines/public/mock/mock_timeline_data.ts index 363a67a30b978e5..55ec6862309aa0c 100644 --- a/x-pack/plugins/timelines/public/mock/mock_timeline_data.ts +++ b/x-pack/plugins/timelines/public/mock/mock_timeline_data.ts @@ -1566,8 +1566,6 @@ export const mockTgridModel: TGridModel = { selectAll: false, id: 'ef579e40-jibber-jabber', indexNames: [], - isAddToExistingCaseOpen: false, - isCreateNewCaseOpen: false, isLoading: false, isSelectAllChecked: false, kqlQuery: { diff --git a/x-pack/plugins/timelines/public/mock/plugin_mock.tsx b/x-pack/plugins/timelines/public/mock/plugin_mock.tsx index 066485319f9116c..be2adfe84a10185 100644 --- a/x-pack/plugins/timelines/public/mock/plugin_mock.tsx +++ b/x-pack/plugins/timelines/public/mock/plugin_mock.tsx @@ -24,6 +24,4 @@ export const createTGridMocks = () => ({ getUseAddToTimeline: () => useAddToTimeline, getUseAddToTimelineSensor: () => useAddToTimelineSensor, getUseDraggableKeyboardWrapper: () => useDraggableKeyboardWrapper, - getAddToExistingCaseButton: () =>
, - getAddToNewCaseButton: () =>
, }); diff --git a/x-pack/plugins/timelines/public/plugin.ts b/x-pack/plugins/timelines/public/plugin.ts index 0ecb063445a46fa..8b4bdae43dfe340 100644 --- a/x-pack/plugins/timelines/public/plugin.ts +++ b/x-pack/plugins/timelines/public/plugin.ts @@ -16,10 +16,6 @@ import { getLoadingPanelLazy, getTGridLazy, getFieldsBrowserLazy, - getAddToCaseLazy, - getAddToExistingCaseButtonLazy, - getAddToNewCaseButtonLazy, - getAddToCasePopoverLazy, } from './methods'; import type { TimelinesUIStart, TGridProps, TimelinesStartPlugins } from './types'; import { tGridReducer } from './store/t_grid/reducer'; @@ -88,38 +84,6 @@ export class TimelinesPlugin implements Plugin { setTGridEmbeddedStore: (store: Store) => { this.setStore(store); }, - getAddToCaseAction: (props) => { - return getAddToCaseLazy(props, { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - store: this._store!, - storage: this._storage, - setStore: this.setStore.bind(this), - }); - }, - getAddToCasePopover: (props) => { - return getAddToCasePopoverLazy(props, { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - store: this._store!, - storage: this._storage, - setStore: this.setStore.bind(this), - }); - }, - getAddToExistingCaseButton: (props) => { - return getAddToExistingCaseButtonLazy(props, { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - store: this._store!, - storage: this._storage, - setStore: this.setStore.bind(this), - }); - }, - getAddToNewCaseButton: (props) => { - return getAddToNewCaseButtonLazy(props, { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - store: this._store!, - storage: this._storage, - setStore: this.setStore.bind(this), - }); - }, }; } diff --git a/x-pack/plugins/timelines/public/store/t_grid/actions.ts b/x-pack/plugins/timelines/public/store/t_grid/actions.ts index feab12b616c783f..00e207180b13470 100644 --- a/x-pack/plugins/timelines/public/store/t_grid/actions.ts +++ b/x-pack/plugins/timelines/public/store/t_grid/actions.ts @@ -117,11 +117,3 @@ export const setTimelineUpdatedAt = export const addProviderToTimeline = actionCreator<{ id: string; dataProvider: DataProvider }>( 'ADD_PROVIDER_TO_TIMELINE' ); - -export const setOpenAddToExistingCase = actionCreator<{ id: string; isOpen: boolean }>( - 'SET_OPEN_ADD_TO_EXISTING_CASE' -); - -export const setOpenAddToNewCase = actionCreator<{ id: string; isOpen: boolean }>( - 'SET_OPEN_ADD_TO_NEW_CASE' -); diff --git a/x-pack/plugins/timelines/public/store/t_grid/model.ts b/x-pack/plugins/timelines/public/store/t_grid/model.ts index 0640cfb845d9c94..82a4c3e68fd0219 100644 --- a/x-pack/plugins/timelines/public/store/t_grid/model.ts +++ b/x-pack/plugins/timelines/public/store/t_grid/model.ts @@ -66,8 +66,6 @@ export interface TGridModel extends TGridModelSettings { /** Uniquely identifies the timeline */ id: string; indexNames: string[]; - isAddToExistingCaseOpen: boolean; - isCreateNewCaseOpen: boolean; isLoading: boolean; /** If selectAll checkbox in header is checked **/ isSelectAllChecked: boolean; diff --git a/x-pack/plugins/timelines/public/store/t_grid/reducer.ts b/x-pack/plugins/timelines/public/store/t_grid/reducer.ts index d3af1dc4e9b3020..ae3f9dc5c20b302 100644 --- a/x-pack/plugins/timelines/public/store/t_grid/reducer.ts +++ b/x-pack/plugins/timelines/public/store/t_grid/reducer.ts @@ -18,8 +18,6 @@ import { setEventsDeleted, setEventsLoading, setTGridSelectAll, - setOpenAddToExistingCase, - setOpenAddToNewCase, setSelected, setTimelineUpdatedAt, toggleDetailPanel, @@ -239,26 +237,6 @@ export const tGridReducer = reducerWithInitialState(initialTGridState) ...state, timelineById: addProviderToTimelineHelper(id, dataProvider, state.timelineById), })) - .case(setOpenAddToExistingCase, (state, { id, isOpen }) => ({ - ...state, - timelineById: { - ...state.timelineById, - [id]: { - ...state.timelineById[id], - isAddToExistingCaseOpen: isOpen, - }, - }, - })) - .case(setOpenAddToNewCase, (state, { id, isOpen }) => ({ - ...state, - timelineById: { - ...state.timelineById, - [id]: { - ...state.timelineById[id], - isCreateNewCaseOpen: isOpen, - }, - }, - })) .case(setTimelineUpdatedAt, (state, { id, updated }) => ({ ...state, timelineById: { diff --git a/x-pack/plugins/timelines/public/store/t_grid/selectors.ts b/x-pack/plugins/timelines/public/store/t_grid/selectors.ts index 9077cac2b5dd017..2db463e47cc8833 100644 --- a/x-pack/plugins/timelines/public/store/t_grid/selectors.ts +++ b/x-pack/plugins/timelines/public/store/t_grid/selectors.ts @@ -6,26 +6,11 @@ */ import { getOr } from 'lodash/fp'; import { createSelector } from 'reselect'; -import { TGridModel, State } from '.'; +import { TGridModel } from '.'; import { tGridDefaults, getTGridManageDefaults } from './defaults'; -interface TGridById { - [id: string]: TGridModel; -} - const getDefaultTgrid = (id: string) => ({ ...tGridDefaults, ...getTGridManageDefaults(id) }); -const standaloneTGridById = (state: State): TGridById => state.timelineById; - -export const activeCaseFlowId = createSelector(standaloneTGridById, (tGrid) => { - return ( - tGrid && - Object.entries(tGrid) - .map(([id, data]) => (data.isAddToExistingCaseOpen || data.isCreateNewCaseOpen ? id : null)) - .find((id) => id) - ); -}); - export const selectTGridById = (state: unknown, timelineId: string): TGridModel => { return getOr( getOr(getDefaultTgrid(timelineId), ['timelineById', timelineId], state), diff --git a/x-pack/plugins/timelines/public/types.ts b/x-pack/plugins/timelines/public/types.ts index ddecac02be705d8..0c9e6aa3e325f81 100644 --- a/x-pack/plugins/timelines/public/types.ts +++ b/x-pack/plugins/timelines/public/types.ts @@ -23,7 +23,6 @@ import type { TGridIntegratedProps } from './components/t_grid/integrated'; import type { TGridStandaloneProps } from './components/t_grid/standalone'; import type { UseAddToTimelineProps, UseAddToTimeline } from './hooks/use_add_to_timeline'; import { HoverActionsConfig } from './components/hover_actions/index'; -import type { AddToCaseActionProps } from './components/actions/timeline/cases/add_to_case_action'; import { TimelineTabs } from '../common/types'; export * from './store/t_grid'; export interface TimelinesUIStart { @@ -42,10 +41,6 @@ export interface TimelinesUIStart { props: UseDraggableKeyboardWrapperProps ) => UseDraggableKeyboardWrapper; setTGridEmbeddedStore: (store: Store) => void; - getAddToCaseAction: (props: AddToCaseActionProps) => ReactElement; - getAddToCasePopover: (props: AddToCaseActionProps) => ReactElement; - getAddToExistingCaseButton: (props: AddToCaseActionProps) => ReactElement; - getAddToNewCaseButton: (props: AddToCaseActionProps) => ReactElement; } export interface TimelinesStartPlugins { diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 8a39c36c870d4c2..a80c43bd832d879 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -27003,16 +27003,6 @@ "xpack.timelines.alerts.summaryView.options.summaryView.description": "各アラートのイベントフローのレンダリングを表示", "xpack.timelines.beatFields.errorSearchDescription": "Beatフィールドの取得でエラーが発生しました", "xpack.timelines.beatFields.failSearchDescription": "Beat フィールドで検索を実行できませんでした", - "xpack.timelines.cases.timeline.actions.addCase": "ケースに追加", - "xpack.timelines.cases.timeline.actions.addExistingCase": "既存のケースに追加", - "xpack.timelines.cases.timeline.actions.addNewCase": "新しいケースに追加", - "xpack.timelines.cases.timeline.actions.addToCaseAriaLabel": "アラートをケースに関連付ける", - "xpack.timelines.cases.timeline.actions.addToCaseTooltip": "ケースに追加", - "xpack.timelines.cases.timeline.actions.caseCreatedSuccessToast": "アラートが「{title}」に追加されました", - "xpack.timelines.cases.timeline.actions.caseCreatedSuccessToastText": "このケースのアラートはステータスがケースステータスと同期されました", - "xpack.timelines.cases.timeline.actions.caseCreatedSuccessToastViewCaseLink": "ケースの表示", - "xpack.timelines.cases.timeline.actions.permissionsMessage": "現在、アラートをケースに関連付けるための必要な権限がありません。サポートについては、管理者にお問い合わせください。", - "xpack.timelines.cases.timeline.actions.unsupportedEventsMessage": "このイベントはケースに関連付けられません", "xpack.timelines.clipboard.copied": "コピー完了", "xpack.timelines.clipboard.copy": "コピー", "xpack.timelines.clipboard.copy.successToastTitle": "フィールド{field}をクリップボードにコピーしました", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index bdba6f9225cc004..15a194346a9e115 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -27035,16 +27035,6 @@ "xpack.timelines.alerts.summaryView.options.summaryView.description": "查看每个告警的事件渲染", "xpack.timelines.beatFields.errorSearchDescription": "获取 Beat 字段时发生错误", "xpack.timelines.beatFields.failSearchDescription": "无法对 Beat 字段执行搜索", - "xpack.timelines.cases.timeline.actions.addCase": "添加到案例", - "xpack.timelines.cases.timeline.actions.addExistingCase": "添加到现有案例", - "xpack.timelines.cases.timeline.actions.addNewCase": "添加到新案例", - "xpack.timelines.cases.timeline.actions.addToCaseAriaLabel": "将告警附加到案例", - "xpack.timelines.cases.timeline.actions.addToCaseTooltip": "添加到案例", - "xpack.timelines.cases.timeline.actions.caseCreatedSuccessToast": "告警已添加到“{title}”", - "xpack.timelines.cases.timeline.actions.caseCreatedSuccessToastText": "此案例中的告警的状态已经与案例状态同步", - "xpack.timelines.cases.timeline.actions.caseCreatedSuccessToastViewCaseLink": "查看案例", - "xpack.timelines.cases.timeline.actions.permissionsMessage": "您当前缺少所需的权限,无法向案例附加告警。有关进一步帮助,请联系您的管理员。", - "xpack.timelines.cases.timeline.actions.unsupportedEventsMessage": "此事件无法附加到案例", "xpack.timelines.clipboard.copied": "已复制", "xpack.timelines.clipboard.copy": "复制", "xpack.timelines.clipboard.copy.successToastTitle": "已将字段 {field} 复制到剪贴板", diff --git a/x-pack/test/plugin_functional/plugins/timelines_test/public/applications/timelines_test/index.tsx b/x-pack/test/plugin_functional/plugins/timelines_test/public/applications/timelines_test/index.tsx index c034ba1612a2c56..2542e82c5e28d63 100644 --- a/x-pack/test/plugin_functional/plugins/timelines_test/public/applications/timelines_test/index.tsx +++ b/x-pack/test/plugin_functional/plugins/timelines_test/public/applications/timelines_test/index.tsx @@ -65,13 +65,7 @@ const AppRoot = React.memo( {(timelinesPluginSetup && timelinesPluginSetup.getTGrid && timelinesPluginSetup.getTGrid<'standalone'>({ - appId: 'securitySolution', - casesOwner: 'securitySolutionUI', type: 'standalone', - casePermissions: { - read: true, - crud: true, - }, columns: [], indexNames: [], deletedEventIds: [],