diff --git a/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx b/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx index 935e565be039e6..dba1136193ee1a 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx @@ -276,48 +276,12 @@ describe('Resolver, when analyzing a tree that has two related events for the or ); expect(edgesThatTerminateUnderneathSecondChild).toHaveLength(1); }); - - it('should render a related events button', async () => { + it('should show exactly one option with the correct count', async () => { await expect( - simulator.map(() => ({ - relatedEventButtons: simulator.processNodeSubmenuButton(entityIDs.origin).length, - })) - ).toYieldEqualTo({ - relatedEventButtons: 1, - }); - }); - describe('when the related events button is clicked', () => { - beforeEach(async () => { - const button = await simulator.resolveWrapper(() => - simulator.processNodeSubmenuButton(entityIDs.origin) - ); - if (button) { - button.simulate('click', { button: 0 }); - } - }); - it('should open the submenu and display exactly one option with the correct count', async () => { - await expect( - simulator.map(() => - simulator.testSubject('resolver:map:node-submenu-item').map((node) => node.text()) - ) - ).toYieldEqualTo(['2 registry']); - }); - }); - describe('and when the related events button is clicked again', () => { - beforeEach(async () => { - const button = await simulator.resolveWrapper(() => - simulator.processNodeSubmenuButton(entityIDs.origin) - ); - if (button) { - button.simulate('click', { button: 0 }); - button.simulate('click', { button: 0 }); // The first click opened the menu, this second click closes it - } - }); - it('should close the submenu', async () => { - await expect( - simulator.map(() => simulator.testSubject('resolver:map:node-submenu-item').length) - ).toYieldEqualTo(0); - }); + simulator.map(() => + simulator.testSubject('resolver:map:node-submenu-item').map((node) => node.text()) + ) + ).toYieldEqualTo(['2 registry']); }); }); }); diff --git a/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx b/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx index 43b337c0603f61..65ec395080f864 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx @@ -257,13 +257,6 @@ const UnstyledProcessEventDot = React.memo( }); }, [dispatch, nodeID]); - const handleRelatedEventRequest = useCallback(() => { - dispatch({ - type: 'userRequestedRelatedEventData', - payload: nodeID, - }); - }, [dispatch, nodeID]); - const handleClick = useCallback( (clickEvent) => { if (animationTarget.current?.beginElement) { @@ -439,11 +432,7 @@ const UnstyledProcessEventDot = React.memo( {grandTotal !== null && grandTotal > 0 && ( diff --git a/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx b/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx index d6cc3e52496188..d40aa0b26a94b3 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx @@ -4,15 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable react/display-name */ - import { i18n } from '@kbn/i18n'; -import React, { useState, useCallback, useRef, useLayoutEffect, useMemo } from 'react'; -import { EuiI18nNumber, EuiButton, EuiPopover, ButtonColor } from '@elastic/eui'; +import React, { useMemo } from 'react'; +import { EuiI18nNumber } from '@elastic/eui'; import styled from 'styled-components'; import { ResolverNodeStats } from '../../../common/endpoint/types'; import { useRelatedEventByCategoryNavigation } from './use_related_event_by_category_navigation'; -import { Matrix3 } from '../types'; import { useColors } from './use_colors'; /** @@ -45,53 +42,6 @@ interface ResolverSubmenuOption { export type ResolverSubmenuOptionList = ResolverSubmenuOption[] | string; -const StyledActionButton = styled(EuiButton)` - &.euiButton--small { - height: fit-content; - line-height: 1; - padding: 0.25em; - font-size: 0.85rem; - } -`; - -/** - * This will be the "host button" that displays the "total number of related events" and opens - * the sumbmenu (with counts by category) when clicked. - */ -const SubButton = React.memo( - ({ - hasMenu, - menuIsOpen, - action, - count, - nodeID, - }: { - hasMenu: boolean; - menuIsOpen?: boolean; - action: (evt: React.MouseEvent) => void; - count?: number; - nodeID: string; - }) => { - const iconType = menuIsOpen === true ? 'arrowUp' : 'arrowDown'; - return ( - - {count ? : ''} {subMenuAssets.relatedEvents.title} - - ); - } -); - /** * A Submenu to be displayed in one of two forms: * 1) Provided a collection of `optionsWithActions`: it will call `menuAction` then - if and when menuData becomes available - display each item with an optional prefix and call the supplied action for the options when that option is clicked. @@ -99,53 +49,20 @@ const SubButton = React.memo( */ const NodeSubMenuComponents = React.memo( ({ - count, - buttonBorderColor, - menuAction, className, - projectionMatrix, nodeID, relatedEventStats, }: { className?: string; - menuAction?: () => unknown; - buttonBorderColor: ButtonColor; // eslint-disable-next-line react/no-unused-prop-types buttonFill: string; - count?: number; /** * Receive the projection matrix, so we can see when the camera position changed, so we can force the submenu to reposition itself. */ - projectionMatrix: Matrix3; nodeID: string; relatedEventStats: ResolverNodeStats | undefined; }) => { - // keep a ref to the popover so we can call its reposition method - const popoverRef = useRef(null); - - const [menuIsOpen, setMenuOpen] = useState(false); - const handleMenuOpenClick = useCallback( - (clickEvent: React.MouseEvent) => { - // stopping propagation/default to prevent other node animations from triggering - clickEvent.preventDefault(); - clickEvent.stopPropagation(); - setMenuOpen(!menuIsOpen); - }, - [menuIsOpen] - ); - const handleMenuActionClick = useCallback( - (clickEvent: React.MouseEvent) => { - // stopping propagation/default to prevent other node animations from triggering - clickEvent.preventDefault(); - clickEvent.stopPropagation(); - if (typeof menuAction === 'function') menuAction(); - setMenuOpen(true); - }, - [menuAction] - ); - // The last projection matrix that was used to position the popover - const projectionMatrixAtLastRender = useRef(); const relatedEventCallbacks = useRelatedEventByCategoryNavigation({ nodeID, categories: relatedEventStats?.events?.byCategory, @@ -164,24 +81,6 @@ const NodeSubMenuComponents = React.memo( } }, [relatedEventStats, relatedEventCallbacks]); - useLayoutEffect(() => { - if ( - /** - * If there is a popover component reference, - * and this isn't the first render, - * and the projectionMatrix has changed since last render, - * then force the popover to reposition itself. - */ - popoverRef.current && - projectionMatrixAtLastRender.current && - projectionMatrixAtLastRender.current !== projectionMatrix - ) { - popoverRef.current.positionPopoverFixed(); - } - - // no matter what, keep track of the last project matrix that was used to size the popover - projectionMatrixAtLastRender.current = projectionMatrix; - }, [projectionMatrixAtLastRender, projectionMatrix]); const { pillStroke: pillBorderStroke, resolverBackground: pillFill } = useColors(); const listStylesFromTheme = useMemo(() => { return { @@ -189,65 +88,32 @@ const NodeSubMenuComponents = React.memo( backgroundColor: pillFill, }; }, [pillBorderStroke, pillFill]); - if (relatedEventStats === undefined) { - /** - * When called with a `menuAction` - * Render without dropdown and call the supplied action when host button is clicked - */ - return ( -
- - {subMenuAssets.relatedEvents.title} - -
- ); - } if (relatedEventOptions === undefined) { return null; } return ( - <> - - {menuIsOpen ? ( -
    - {relatedEventOptions - .sort((opta, optb) => { - return opta.optionTitle.localeCompare(optb.optionTitle); - }) - .map((opt) => { - return ( -
  • - -
  • - ); - })} -
- ) : null} - +
    + {relatedEventOptions + .sort((opta, optb) => { + return opta.optionTitle.localeCompare(optb.optionTitle); + }) + .map((opt) => { + return ( +
  • + +
  • + ); + })} +
); } ); @@ -265,7 +131,7 @@ export const NodeSubMenu = styled(NodeSubMenuComponents)` flex-flow: row wrap; background: transparent; position: absolute; - top: 6.5em; + top: 4.5em; contain: content; width: 12em; z-index: 2; @@ -300,17 +166,4 @@ export const NodeSubMenu = styled(NodeSubMenuComponents)` &.options .item button:active { transform: scale(0.95); } - - & .euiButton { - background-color: ${(props) => props.buttonFill}; - border-color: ${(props) => props.buttonBorderColor}; - border-style: solid; - border-width: 1px; - - &:hover, - &:active, - &:focus { - background-color: ${(props) => props.buttonFill}; - } - } `; diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/resolver.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/resolver.ts index e48d952ce82c35..620eab37f9b46e 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/resolver.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/resolver.ts @@ -13,7 +13,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const queryBar = getService('queryBar'); - // FLAKY: https://github.com/elastic/kibana/issues/77835 describe('Endpoint Event Resolver', function () { before(async () => { await esArchiver.load('endpoint/resolver_tree', { useCreate: true });