From 92553b16c20490a100ad85de0f44e464a8aaf78c Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Thu, 17 Sep 2020 15:45:56 -0400 Subject: [PATCH 1/9] [Security Solution][Resolver] Show all event counts --- .../public/resolver/view/submenu.tsx | 180 ++---------------- 1 file changed, 21 insertions(+), 159 deletions(-) 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 dda90df0fff936..e0fee9ee7bf5a5 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx @@ -4,11 +4,9 @@ * 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, ButtonColor } from '@elastic/eui'; import styled from 'styled-components'; import { ResolverNodeStats } from '../../../common/endpoint/types'; import { useRelatedEventByCategoryNavigation } from './use_related_event_by_category_navigation'; @@ -45,53 +43,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. @@ -120,32 +71,7 @@ const NodeSubMenuComponents = React.memo( 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 +90,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 { colorMap: { pillStroke: pillBorderStroke, resolverBackground: pillFill }, } = useResolverTheme(); @@ -191,64 +99,31 @@ 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 ( +
  • + +
  • + ); + })} +
); } ); @@ -301,17 +176,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}; - } - } `; From 3ee4e2447b0c6da7e15670d0a7c092c160dcd3ae Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Thu, 17 Sep 2020 15:58:22 -0400 Subject: [PATCH 2/9] Remove more --- .../public/resolver/view/process_event_dot.tsx | 11 ----------- .../public/resolver/view/submenu.tsx | 9 --------- 2 files changed, 20 deletions(-) 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 3edfe36087e688..716620c18e6d73 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 @@ -252,13 +252,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) { @@ -434,11 +427,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 e0fee9ee7bf5a5..e497bf2d3ccb54 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx @@ -10,7 +10,6 @@ import { EuiI18nNumber, ButtonColor } 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 { useResolverTheme } from './assets'; /** @@ -50,24 +49,16 @@ export type ResolverSubmenuOptionList = ResolverSubmenuOption[] | string; */ 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; }) => { From 392ec76c3855c1b58287af32caaa524aecf69153 Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Thu, 17 Sep 2020 16:13:06 -0400 Subject: [PATCH 3/9] adjust position of pills --- .../security_solution/public/resolver/view/submenu.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 e497bf2d3ccb54..dc57f8e84ff928 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx @@ -6,7 +6,7 @@ import { i18n } from '@kbn/i18n'; import React, { useMemo } from 'react'; -import { EuiI18nNumber, ButtonColor } from '@elastic/eui'; +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'; @@ -132,7 +132,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; From 7ad7395825d30a5e3c1cfe1faaf5ed7d3f54b831 Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Thu, 17 Sep 2020 16:49:44 -0400 Subject: [PATCH 4/9] remove irrelevant tests --- .../resolver/view/clickthrough.test.tsx | 46 ++----------------- 1 file changed, 5 insertions(+), 41 deletions(-) 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']); }); }); }); From 918e13617e22c6eb46c379cb78a639cd145faa0b Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Thu, 17 Sep 2020 22:41:53 -0400 Subject: [PATCH 5/9] fix functional test --- .../test/security_solution_endpoint/apps/endpoint/resolver.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 725edb6d981985..6c3b621bdbca37 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/resolver.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/resolver.ts @@ -46,7 +46,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const Table = await testSubjects.findAll('resolver:node-list:item'); for (const value of Table) { - const text = await value._webElement.getText(); + const text = await ( + await value.findByCssSelector('[class*="StyledLabelTitle"]') + )._webElement.getText(); TableData.push(text.split('\n')[0]); } await (await testSubjects.find('resolver:graph-controls:zoom-out')).click(); From 11a04844e5f2a206a96668961c31f641155ea530 Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Fri, 18 Sep 2020 11:01:28 -0400 Subject: [PATCH 6/9] Revert "fix functional test" This reverts commit 918e13617e22c6eb46c379cb78a639cd145faa0b. --- .../test/security_solution_endpoint/apps/endpoint/resolver.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 e946efbd6f02df..e8fa18aa01b4cd 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/resolver.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/resolver.ts @@ -47,9 +47,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const Table = await testSubjects.findAll('resolver:node-list:item'); for (const value of Table) { - const text = await ( - await value.findByCssSelector('[class*="StyledLabelTitle"]') - )._webElement.getText(); + const text = await value._webElement.getText(); TableData.push(text.split('\n')[0]); } await (await testSubjects.find('resolver:graph-controls:zoom-out')).click(); From 9e1b0ea3f93677cc8bc7f4008b3ac606e677aa19 Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Fri, 18 Sep 2020 11:46:04 -0400 Subject: [PATCH 7/9] Remove errant comment --- x-pack/test/security_solution_endpoint/apps/endpoint/resolver.ts | 1 - 1 file changed, 1 deletion(-) 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 }); From 69169a13840b55ed8c63a4aab71140fab5e8751a Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Fri, 18 Sep 2020 12:40:15 -0400 Subject: [PATCH 8/9] replace key from merge --- .../plugins/security_solution/public/resolver/view/submenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8a1cd00b14e1de..4b1fd4442c20e3 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx @@ -82,7 +82,6 @@ const NodeSubMenuComponents = React.memo( } }, [relatedEventStats, relatedEventCallbacks]); - const { pillStroke: pillBorderStroke, resolverBackground: pillFill } = useColors(); const listStylesFromTheme = useMemo(() => { return { @@ -107,6 +106,7 @@ const NodeSubMenuComponents = React.memo( className="item" data-test-subj="resolver:map:node-submenu-item" style={listStylesFromTheme} + key={opt.optionTitle} >