From ba91b160ae86609facfc9edf7aa75d4f68439378 Mon Sep 17 00:00:00 2001 From: "konrad.szwarc" Date: Wed, 15 Mar 2023 12:08:49 +0100 Subject: [PATCH 01/22] make sure create-case-flyout-mask-overlay z-index propagates --- .../public/components/create/flyout/create_case_flyout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx b/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx index 3cab988a5ab74..fdd90ce58e0d9 100644 --- a/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx +++ b/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx @@ -48,7 +48,7 @@ const maskOverlayClassName = 'create-case-flyout-mask-overlay'; const GlobalStyle = createGlobalStyle<{ theme: { eui: { euiZLevel5: number } } }>` .${maskOverlayClassName} { ${({ theme }) => ` - z-index: ${theme.eui.euiZLevel5}; + z-index: ${theme.eui.euiZLevel5} !important; `} } `; From e06ecbb019ee2908fa7c9d260572c5c34906a18d Mon Sep 17 00:00:00 2001 From: "konrad.szwarc" Date: Wed, 15 Mar 2023 15:18:37 +0100 Subject: [PATCH 02/22] e2e coverege --- .../osquery/cypress/e2e/all/alerts.cy.ts | 60 ++++++++++++++++++- .../osquery/cypress/tasks/integrations.ts | 10 ++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts b/x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts index e988cd36425d3..386396799847f 100644 --- a/x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts +++ b/x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts @@ -36,7 +36,12 @@ import { viewRecentCaseAndCheckResults, } from '../../tasks/live_query'; import { preparePack } from '../../tasks/packs'; -import { closeModalIfVisible, closeToastIfVisible } from '../../tasks/integrations'; +import { + closeModalIfVisible, + closeToastIfVisible, + generateRandomStringName, + interceptCaseId, +} from '../../tasks/integrations'; import { navigateTo } from '../../tasks/navigation'; import { RESULTS_TABLE, RESULTS_TABLE_BUTTON } from '../../screens/live_query'; import { OSQUERY_POLICY } from '../../screens/fleet'; @@ -359,6 +364,59 @@ describe('Alert Event Details', () => { }); }); + describe('Case creation', () => { + let ruleId: string; + let ruleName: string; + let packId: string; + let packName: string; + let caseId: string; + const packData = packFixture(); + + before(() => { + loadPack(packData).then((data) => { + packId = data.id; + packName = data.attributes.name; + }); + loadRule(true).then((data) => { + ruleId = data.id; + ruleName = data.name; + }); + interceptCaseId((id) => { + caseId = id; + }); + }); + + after(() => { + cleanupPack(packId); + cleanupRule(ruleId); + cleanupCase(caseId); + }); + + it('runs osquery against alert and creates a new case', () => { + const [caseName, caseDescription] = generateRandomStringName(2); + loadRuleAlerts(ruleName); + cy.getBySel('expand-event').first().click({ force: true }); + cy.getBySel('take-action-dropdown-btn').click(); + cy.getBySel('osquery-action-item').click(); + cy.contains('Run a set of queries in a pack').wait(500).click(); + cy.getBySel('select-live-pack').within(() => { + cy.getBySel('comboBoxInput').type(`${packName}{downArrow}{enter}`); + }); + submitQuery(); + cy.get('[aria-label="Add to Case"]').first().click(); + cy.getBySel('cases-table-add-case-filter-bar').click(); + cy.getBySel('create-case-flyout').should('be.visible'); + cy.getBySel('caseTitle').within(() => { + cy.getBySel('input').type(caseName); + }); + cy.getBySel('caseDescription').within(() => { + cy.getBySel('euiMarkdownEditorTextArea').type(caseDescription); + }); + cy.getBySel('create-case-submit').click(); + cy.contains(`An alert was added to "${caseName}"`); + }); + }); + describe('Case', () => { let ruleId: string; let ruleName: string; diff --git a/x-pack/plugins/osquery/cypress/tasks/integrations.ts b/x-pack/plugins/osquery/cypress/tasks/integrations.ts index 9bbb15721ac78..bb576421ccd3f 100644 --- a/x-pack/plugins/osquery/cypress/tasks/integrations.ts +++ b/x-pack/plugins/osquery/cypress/tasks/integrations.ts @@ -60,6 +60,16 @@ export const interceptAgentPolicyId = (cb: (policyId: string) => void) => { }); }; +export const interceptCaseId = (cb: (caseId: string) => void) => { + cy.intercept('POST', '**/api/cases', (req) => { + req.continue((res) => { + cb(res.body.id); + + return res.send(res.body); + }); + }); +}; + export const interceptPackId = (cb: (packId: string) => void) => { cy.intercept('POST', '**/api/osquery/packs', (req) => { req.continue((res) => { From f538460dca6841e8164d1a28527517999f25a207 Mon Sep 17 00:00:00 2001 From: "konrad.szwarc" Date: Wed, 15 Mar 2023 16:06:07 +0100 Subject: [PATCH 03/22] use headerZindexLocation --- .../create/flyout/create_case_flyout.tsx | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx b/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx index fdd90ce58e0d9..f8e7e6874a150 100644 --- a/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx +++ b/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import styled, { createGlobalStyle } from 'styled-components'; +import styled from 'styled-components'; import { EuiFlyout, EuiFlyoutHeader, EuiTitle, EuiFlyoutBody } from '@elastic/eui'; import { QueryClientProvider } from '@tanstack/react-query'; @@ -37,22 +37,6 @@ const StyledFlyout = styled(EuiFlyout)` `} `; -const maskOverlayClassName = 'create-case-flyout-mask-overlay'; - -/** - * We need to target the mask overlay which is a parent element - * of the flyout. - * A global style is needed to target a parent element. - */ - -const GlobalStyle = createGlobalStyle<{ theme: { eui: { euiZLevel5: number } } }>` - .${maskOverlayClassName} { - ${({ theme }) => ` - z-index: ${theme.eui.euiZLevel5} !important; - `} - } -`; - // Adding bottom padding because timeline's // bottom bar gonna hide the submit button. const StyledEuiFlyoutBody = styled(EuiFlyoutBody)` @@ -82,13 +66,12 @@ export const CreateCaseFlyout = React.memo( return ( - From 6f8f8787d18f1f8f671da7ec1fc9e1ef5545ebab Mon Sep 17 00:00:00 2001 From: Tomasz Ciecierski Date: Wed, 22 Mar 2023 14:49:25 +0100 Subject: [PATCH 04/22] fix mask issue --- .../public/components/create/flyout/create_case_flyout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx b/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx index f8e7e6874a150..975cea62ffec1 100644 --- a/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx +++ b/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx @@ -71,7 +71,7 @@ export const CreateCaseFlyout = React.memo( tour-step="create-case-flyout" data-test-subj="create-case-flyout" // maskProps is needed in order to apply the z-index to the parent overlay element, not to the flyout only - maskProps={{ headerZindexLocation: 'above' }} + maskProps={{ headerZindexLocation: 'below' }} > From 64a7f9268960a797bba42e50ac9175ac7eb06aef Mon Sep 17 00:00:00 2001 From: "konrad.szwarc" Date: Thu, 30 Mar 2023 09:37:38 +0200 Subject: [PATCH 05/22] Revert "fix mask issue" This reverts commit 6f8f8787d18f1f8f671da7ec1fc9e1ef5545ebab. --- .../public/components/create/flyout/create_case_flyout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx b/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx index 0fc009a868209..12fcc3bfc4213 100644 --- a/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx +++ b/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx @@ -72,7 +72,7 @@ export const CreateCaseFlyout = React.memo( tour-step="create-case-flyout" data-test-subj="create-case-flyout" // maskProps is needed in order to apply the z-index to the parent overlay element, not to the flyout only - maskProps={{ headerZindexLocation: 'below' }} + maskProps={{ headerZindexLocation: 'above' }} > From 443749fad1a455e7836bf9a063a3e18d62f80625 Mon Sep 17 00:00:00 2001 From: "konrad.szwarc" Date: Thu, 30 Mar 2023 17:48:56 +0200 Subject: [PATCH 06/22] flyout positioning cleanup --- .../create/flyout/create_case_flyout.tsx | 2 -- .../components/add_exception_flyout/index.tsx | 10 +--------- .../all_exception_items_table/index.tsx | 1 - .../components/osquery/osquery_flyout.tsx | 7 +------ .../components/exceptions_list_card/index.tsx | 1 - .../components/list_with_search/index.tsx | 1 - .../exceptions/pages/shared_lists/index.tsx | 1 - .../view/components/event_filters_flyout.tsx | 5 ++--- .../components/flyout/pane/index.tsx | 20 ++----------------- .../event_details/flyout/footer.tsx | 6 +----- .../timelines/components/side_panel/index.tsx | 4 ++++ 11 files changed, 11 insertions(+), 47 deletions(-) diff --git a/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx b/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx index 12fcc3bfc4213..0154fed0e860f 100644 --- a/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx +++ b/x-pack/plugins/cases/public/components/create/flyout/create_case_flyout.tsx @@ -71,8 +71,6 @@ export const CreateCaseFlyout = React.memo( onClose={onClose} tour-step="create-case-flyout" data-test-subj="create-case-flyout" - // maskProps is needed in order to apply the z-index to the parent overlay element, not to the flyout only - maskProps={{ headerZindexLocation: 'above' }} > diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/index.tsx index 52233b7f33aed..e0979730b7d7c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/index.tsx @@ -80,7 +80,6 @@ export interface AddExceptionFlyoutProps { sharedListToAddTo?: ExceptionListSchema[]; onCancel: (didRuleChange: boolean) => void; onConfirm: (didRuleChange: boolean, didCloseAlert: boolean, didBulkCloseAlert: boolean) => void; - isNonTimeline?: boolean; } const FlyoutBodySection = styled(EuiFlyoutBody)` @@ -114,7 +113,6 @@ export const AddExceptionFlyout = memo(function AddExceptionFlyout({ sharedListToAddTo, onCancel, onConfirm, - isNonTimeline = false, }: AddExceptionFlyoutProps) { const { isLoading, indexPatterns } = useFetchIndexPatterns(rules); const [isSubmitting, submitNewExceptionItems] = useAddNewExceptionItems(); @@ -462,13 +460,7 @@ export const AddExceptionFlyout = memo(function AddExceptionFlyout({ }, [listType]); return ( - +

{addExceptionMessage}

diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/index.tsx index c0cbe1ac5caf4..df6a6c2835a1d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/index.tsx @@ -499,7 +499,6 @@ const ExceptionsViewerComponent = ({ onConfirm={handleConfirmExceptionFlyout} data-test-subj="addExceptionItemFlyout" showAlertCloseOptions - isNonTimeline={true} /> )} diff --git a/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout.tsx b/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout.tsx index 9e6bc857a1dd1..3dc2f948536cd 100644 --- a/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/osquery/osquery_flyout.tsx @@ -52,12 +52,7 @@ const OsqueryFlyoutComponent: React.FC = ({ if (osquery?.OsqueryAction) { return ( - +

{ACTION_OSQUERY}

diff --git a/x-pack/plugins/security_solution/public/exceptions/components/exceptions_list_card/index.tsx b/x-pack/plugins/security_solution/public/exceptions/components/exceptions_list_card/index.tsx index eb945e18e7761..00e4862cb9115 100644 --- a/x-pack/plugins/security_solution/public/exceptions/components/exceptions_list_card/index.tsx +++ b/x-pack/plugins/security_solution/public/exceptions/components/exceptions_list_card/index.tsx @@ -232,7 +232,6 @@ export const ExceptionsListCard = memo( onConfirm={handleConfirmExceptionFlyout} data-test-subj="addExceptionItemFlyoutInSharedLists" showAlertCloseOptions={false} - isNonTimeline={true} /> ) : null} {showEditExceptionFlyout && exceptionToEdit ? ( diff --git a/x-pack/plugins/security_solution/public/exceptions/components/list_with_search/index.tsx b/x-pack/plugins/security_solution/public/exceptions/components/list_with_search/index.tsx index c09a5a2327214..341c74ce5f8e7 100644 --- a/x-pack/plugins/security_solution/public/exceptions/components/list_with_search/index.tsx +++ b/x-pack/plugins/security_solution/public/exceptions/components/list_with_search/index.tsx @@ -69,7 +69,6 @@ const ListWithSearchComponent: FC = ({ onConfirm={handleConfirmExceptionFlyout} data-test-subj="addExceptionItemFlyoutInList" showAlertCloseOptions={false} // TODO ask if we need it - isNonTimeline={true} // ask if we need the add to rule/list section and which list should we link the exception here /> ) : viewerStatus === ViewerStatus.EMPTY || viewerStatus === ViewerStatus.LOADING ? ( diff --git a/x-pack/plugins/security_solution/public/exceptions/pages/shared_lists/index.tsx b/x-pack/plugins/security_solution/public/exceptions/pages/shared_lists/index.tsx index 4fe0596941294..d886352e3bd9a 100644 --- a/x-pack/plugins/security_solution/public/exceptions/pages/shared_lists/index.tsx +++ b/x-pack/plugins/security_solution/public/exceptions/pages/shared_lists/index.tsx @@ -500,7 +500,6 @@ export const SharedLists = React.memo(() => { setDisplayAddExceptionItemFlyout(false); if (didRuleChange) handleRefresh(); }} - isNonTimeline={true} /> )} diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/event_filters_flyout.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/event_filters_flyout.tsx index 141d92aae4728..fb8726975ab65 100644 --- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/event_filters_flyout.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/event_filters_flyout.tsx @@ -23,6 +23,7 @@ import { import { lastValueFrom } from 'rxjs'; import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; +import type { EuiOverlayMaskProps } from '@elastic/eui/src/components/overlay_mask'; import { useWithArtifactSubmitData } from '../../../../components/artifact_list_page/hooks/use_with_artifact_submit_data'; import type { ArtifactFormComponentOnChangeCallbackProps, @@ -40,9 +41,7 @@ import { getCreationSuccessMessage, getCreationErrorMessage } from '../translati export interface EventFiltersFlyoutProps { data?: Ecs; onCancel(): void; - maskProps?: { - style?: string; - }; + maskProps?: EuiOverlayMaskProps; } export const EventFiltersFlyout: React.FC = memo( diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx index 0d8dd0f637a5e..2aa96faeddd76 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx @@ -8,13 +8,10 @@ import type { EuiFlyoutProps } from '@elastic/eui'; import { EuiFlyout } from '@elastic/eui'; import React, { useCallback, useEffect } from 'react'; -import styled, { createGlobalStyle } from 'styled-components'; +import styled from 'styled-components'; import { useDispatch } from 'react-redux'; -import { - SELECTOR_TIMELINE_IS_VISIBLE_CSS_CLASS_NAME, - TIMELINE_EUI_THEME_ZINDEX_LEVEL, -} from '../../timeline/styles'; +import { SELECTOR_TIMELINE_IS_VISIBLE_CSS_CLASS_NAME } from '../../timeline/styles'; import { StatefulTimeline } from '../../timeline'; import type { TimelineId } from '../../../../../common/types/timeline'; import * as i18n from './translations'; @@ -31,18 +28,6 @@ interface FlyoutPaneComponentProps { const StyledEuiFlyout = styled(EuiFlyout)` animation: none; min-width: 150px; - z-index: ${({ theme }) => theme.eui[TIMELINE_EUI_THEME_ZINDEX_LEVEL]}; -`; - -// SIDE EFFECT: the following creates a global class selector -const IndexPatternFieldEditorOverlayGlobalStyle = createGlobalStyle<{ - theme: { eui: { euiZLevel5: number } }; -}>` - .euiOverlayMask.indexPatternFieldEditorMaskOverlay { - ${({ theme }) => ` - z-index: ${theme.eui.euiZLevel5}; - `} - } `; const FlyoutPaneComponent: React.FC = ({ @@ -75,7 +60,6 @@ const FlyoutPaneComponent: React.FC = ({ ownFocus={false} style={{ display: visible ? 'block' : 'none' }} > - )} {isAddEventFilterModalOpen && detailsEcsData != null && ( - + )} {isOsqueryFlyoutOpenWithAgentId && detailsEcsData != null && ( {visiblePanel}
From 1bb2782dff7cd4642e18cb00c8ebe103918f6de7 Mon Sep 17 00:00:00 2001 From: "konrad.szwarc" Date: Fri, 31 Mar 2023 16:52:11 +0200 Subject: [PATCH 07/22] clarification --- .../public/timelines/components/side_panel/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.tsx index b54a108de391a..3822f9bad82f1 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.tsx @@ -36,6 +36,7 @@ interface DetailsPanelProps { isReadOnly?: boolean; } +// Both event detail and timeline on detection are rendered in a portal, we need to set the z-index to be below the timeline const flyoutZIndexStyle = { zIndex: euiThemeVars.euiZLevel1 - 1 }; /** From d42b144a3c73835e7bef1a45481c3dc9d38f15ef Mon Sep 17 00:00:00 2001 From: Patryk Kopycinski Date: Thu, 6 Apr 2023 21:55:03 +0200 Subject: [PATCH 08/22] bye zindex --- .../public/common/components/page/index.tsx | 44 +-------- .../update_default_data_view_modal.tsx | 1 - .../public/common/components/top_n/top_n.tsx | 2 - .../item_conditions/index.tsx | 12 +-- .../components/page_overlay/page_overlay.tsx | 48 +--------- .../components/flyout/pane/custom_portal.tsx | 95 +++++++++++++++++++ .../components/flyout/pane/index.tsx | 80 ++++++++-------- .../timelines/components/side_panel/index.tsx | 5 - .../timelines/components/timeline/styles.tsx | 10 -- 9 files changed, 136 insertions(+), 161 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/timelines/components/flyout/pane/custom_portal.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/page/index.tsx b/x-pack/plugins/security_solution/public/common/components/page/index.tsx index 73ea828d0733b..635712a3559ec 100644 --- a/x-pack/plugins/security_solution/public/common/components/page/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/page/index.tsx @@ -35,41 +35,6 @@ export const FULL_SCREEN_CONTENT_OVERRIDES_CSS_STYLESHEET = () => css` } `; -/** The `z-index` for EuiPopover Panels that are displayed from inside of Timeline page */ -export const TIMELINE_EUI_POPOVER_PANEL_ZINDEX = 9900; - -/** - * Stylesheet with Eui class overrides in order to address display issues caused when - * the Timeline overlay is opened. These are normally adjustments to ensure that the - * z-index of other EUI components continues to work with the z-index used by timeline - * overlay. - */ -export const TIMELINE_OVERRIDES_CSS_STYLESHEET = () => css` - .euiPopover__panel[data-popover-open] { - z-index: ${TIMELINE_EUI_POPOVER_PANEL_ZINDEX} !important; - min-width: 24px; - } - .euiPopover__panel[data-popover-open].sourcererPopoverPanel { - // needs to appear under modal - z-index: 5900 !important; - } - .euiToolTip { - z-index: 9950 !important; - } - /* - overrides the default styling of euiComboBoxOptionsList because it's implemented - as a popover, so it's not selectable as a child of the styled component - */ - .euiComboBoxOptionsList { - z-index: 9999; - } - - /* ensure elastic charts tooltips appear above open euiPopovers */ - .echTooltip { - z-index: 9950; - } -`; - /* SIDE EFFECT: the following `createGlobalStyle` overrides default styling in angular code that was not theme-friendly and `EuiPopover`, `EuiToolTip` global styles @@ -77,20 +42,15 @@ export const TIMELINE_OVERRIDES_CSS_STYLESHEET = () => css` export const AppGlobalStyle = createGlobalStyle<{ theme: { eui: { euiColorPrimary: string; euiColorLightShade: string; euiSizeS: string } }; }>` - - ${TIMELINE_OVERRIDES_CSS_STYLESHEET} - /* overrides the default styling of EuiDataGrid expand popover footer to make it a column of actions instead of the default actions row */ .euiDataGridRowCell__popover { - max-width: 815px !important; max-height: none !important; overflow: hidden; - .expandable-top-value-button { &.euiButtonEmpty--primary:enabled:focus, .euiButtonEmpty--primary:focus { @@ -111,8 +71,8 @@ export const AppGlobalStyle = createGlobalStyle<{ } } - .euiText + .euiPopoverFooter { - border-top: 1px solid ${({ theme }) => theme.eui.euiColorLightShade}; + .euiText + .euiPopoverFooter { + border-top: 1px solid ${({ theme }) => theme.eui.euiColorLightShade}; margin-top: ${({ theme }) => theme.eui.euiSizeS}; } } diff --git a/x-pack/plugins/security_solution/public/common/components/sourcerer/update_default_data_view_modal.tsx b/x-pack/plugins/security_solution/public/common/components/sourcerer/update_default_data_view_modal.tsx index 53b9e035a5357..c010a4687c8a3 100644 --- a/x-pack/plugins/security_solution/public/common/components/sourcerer/update_default_data_view_modal.tsx +++ b/x-pack/plugins/security_solution/public/common/components/sourcerer/update_default_data_view_modal.tsx @@ -37,7 +37,6 @@ const MyEuiModal = styled(EuiModal)` height: auto !important; max-width: 718px; } - z-index: 99999999; `; export const UpdateDefaultDataViewModal = React.memo( diff --git a/x-pack/plugins/security_solution/public/common/components/top_n/top_n.tsx b/x-pack/plugins/security_solution/public/common/components/top_n/top_n.tsx index fa82951e4ba12..b0d90b9b8132f 100644 --- a/x-pack/plugins/security_solution/public/common/components/top_n/top_n.tsx +++ b/x-pack/plugins/security_solution/public/common/components/top_n/top_n.tsx @@ -26,14 +26,12 @@ const TopNContainer = styled.div` `; const CloseButton = styled(EuiButtonIcon)` - z-index: 999999; position: absolute; right: 4px; top: 4px; `; const ViewSelect = styled(EuiSuperSelect)` - z-index: 999999; width: 170px; `; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/item_conditions/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/item_conditions/index.tsx index 372839eba9e40..c1f11b17cbbd9 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/item_conditions/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/item_conditions/index.tsx @@ -24,7 +24,7 @@ import type { ExceptionsBuilderReturnExceptionItem, } from '@kbn/securitysolution-list-utils'; import type { DataViewBase } from '@kbn/es-query'; -import styled, { css, createGlobalStyle } from 'styled-components'; +import styled, { css } from 'styled-components'; import { ENDPOINT_LIST_ID } from '@kbn/securitysolution-list-constants'; import { hasEqlSequenceQuery, isEqlRule } from '../../../../../../common/detection_engine/utils'; import type { Rule } from '../../../../rule_management/logic/types'; @@ -56,15 +56,6 @@ const SectionHeader = styled(EuiTitle)` font-weight: ${({ theme }) => theme.eui.euiFontWeightSemiBold}; `} `; -// EuiCombox doesn't support change of z-index, or providing any class to portal -// This fix ovveride z-index for EuiFlyout, which conflict with EuiComboBox on this flyout -// fix x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/index.tsx#L429 -// TODO: should be fixed on Component level -const EuiComboboxZIndexGlobalStyle = createGlobalStyle` - [data-test-subj="comboBoxOptionsList osSelectionDropdown-optionsList"] { - z-index: 6000 !important; - } -`; interface ExceptionsFlyoutConditionsComponentProps { /* Exception list item field value for "name" */ @@ -242,7 +233,6 @@ const ExceptionsConditionsComponent: React.FC - )} diff --git a/x-pack/plugins/security_solution/public/management/components/page_overlay/page_overlay.tsx b/x-pack/plugins/security_solution/public/management/components/page_overlay/page_overlay.tsx index 81ba36e91e353..65780044eb8d3 100644 --- a/x-pack/plugins/security_solution/public/management/components/page_overlay/page_overlay.tsx +++ b/x-pack/plugins/security_solution/public/management/components/page_overlay/page_overlay.tsx @@ -15,15 +15,7 @@ import type { EuiPortalProps } from '@elastic/eui/src/components/portal/portal'; import type { EuiTheme } from '@kbn/kibana-react-plugin/common'; import { useIsMounted } from '@kbn/securitysolution-hook-utils'; import { useHasFullScreenContent } from '../../../common/containers/use_full_screen'; -import { - FULL_SCREEN_CONTENT_OVERRIDES_CSS_STYLESHEET, - TIMELINE_EUI_POPOVER_PANEL_ZINDEX, - TIMELINE_OVERRIDES_CSS_STYLESHEET, -} from '../../../common/components/page'; -import { - SELECTOR_TIMELINE_IS_VISIBLE_CSS_CLASS_NAME, - TIMELINE_EUI_THEME_ZINDEX_LEVEL, -} from '../../../timelines/components/timeline/styles'; +import { FULL_SCREEN_CONTENT_OVERRIDES_CSS_STYLESHEET } from '../../../common/components/page'; const OverlayRootContainer = styled.div` border: none; @@ -88,18 +80,6 @@ const PageOverlayGlobalStyles = createGlobalStyle<{ theme: EuiTheme }>` overflow: hidden; } - //------------------------------------------------------------------------------------------- - // Style overrides for when Page Overlay is shown over SecuritySolutionPageWrapper component - //------------------------------------------------------------------------------------------- - // That page wrapper includes several global EUI styles that can conflict with content shown - // from inside of this Page Overlay component. - //------------------------------------------------------------------------------------------- - // Eui Confirm Dialog mask overlay should be displayed above any other popovers - //------------------------------------------------------------------------------------------- - body.${PAGE_OVERLAY_DOCUMENT_BODY_OVER_PAGE_WRAPPER_CLASSNAME} .euiOverlayMask[data-relative-to-header="above"] { - z-index: ${TIMELINE_EUI_POPOVER_PANEL_ZINDEX}; - } - //------------------------------------------------------------------------------------------- // Style overrides for when Page Overlay is in full screen mode //------------------------------------------------------------------------------------------- @@ -109,32 +89,6 @@ const PageOverlayGlobalStyles = createGlobalStyle<{ theme: EuiTheme }>` body.${PAGE_OVERLAY_DOCUMENT_BODY_FULLSCREEN_CLASSNAME} { ${FULL_SCREEN_CONTENT_OVERRIDES_CSS_STYLESHEET} } - - //------------------------------------------------------------------------------------------- - // TIMELINE SPECIFIC STYLES - //------------------------------------------------------------------------------------------- - // The timeline overlay uses a custom z-index, which causes issues with any other content that - // is normally appended to the 'document.body' directly (like popups, masks, flyouts, etc). - // The styles below will be applied anytime the timeline is opened/visible and attempts to - // mitigate the issues around z-index so that content that is shown after the PageOverlay is - // opened is displayed properly. - //------------------------------------------------------------------------------------------- - body.${SELECTOR_TIMELINE_IS_VISIBLE_CSS_CLASS_NAME}.${PAGE_OVERLAY_DOCUMENT_BODY_IS_VISIBLE_CLASSNAME} { - .${PAGE_OVERLAY_CSS_CLASSNAME}, - .euiOverlayMask, - .euiFlyout { - z-index: ${({ theme: { eui } }) => eui[TIMELINE_EUI_THEME_ZINDEX_LEVEL]}; - } - - // Confirm Dialog mask overlay should be displayed above any other popover - .euiOverlayMask[data-relative-to-header="above"] { - z-index: ${TIMELINE_EUI_POPOVER_PANEL_ZINDEX}; - } - - // Other Timeline overrides from AppGlobalStyle: - // x-pack/plugins/security_solution/public/common/components/page/index.tsx - ${TIMELINE_OVERRIDES_CSS_STYLESHEET} - } `; const setDocumentBodyOverlayIsVisible = () => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/custom_portal.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/custom_portal.tsx new file mode 100644 index 0000000000000..0c16b677b7bc6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/custom_portal.tsx @@ -0,0 +1,95 @@ +/* + * 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. + */ + +/** + * NOTE: We can't test this component because Enzyme doesn't support rendering + * into portals. + */ + +import type { ReactNode } from 'react'; +import { Component } from 'react'; +import { createPortal } from 'react-dom'; + +interface InsertPositionsMap { + after: InsertPosition; + before: InsertPosition; +} + +export const insertPositions: InsertPositionsMap = { + after: 'afterend', + before: 'beforebegin', +}; + +export interface EuiPortalProps { + /** + * ReactNode to render as this component's content + */ + children: ReactNode; + insert?: { sibling: HTMLElement; position: 'before' | 'after' }; + portalRef?: (ref: HTMLDivElement | null) => void; +} + +export class EuiPortal extends Component { + portalNode: HTMLDivElement | null = null; + + constructor(props: EuiPortalProps) { + super(props); + if (typeof window === 'undefined') return; // Prevent SSR errors + + const { insert } = this.props; + + this.portalNode = document.createElement('div'); + this.portalNode.dataset.euiportal = 'true'; + + if (insert == null) { + // no insertion defined, append to body + document.body.appendChild(this.portalNode); + } else { + // inserting before or after an element + const { sibling, position } = insert; + sibling.insertAdjacentElement(insertPositions[position], this.portalNode); + } + } + + componentDidMount() { + this.updatePortalRef(this.portalNode); + } + + componentWillUnmount() { + if (this.portalNode?.parentNode) { + this.portalNode.parentNode.removeChild(this.portalNode); + } + this.updatePortalRef(null); + } + + componentDidUpdate(prevProps: Readonly): void { + if (prevProps.insert !== this.props.insert && this.portalNode?.parentNode) { + this.portalNode.parentNode.removeChild(this.portalNode); + } + + if (this.portalNode) { + if (this.props.insert == null) { + // no insertion defined, append to body + document.body.appendChild(this.portalNode); + } else { + // inserting before or after an element + const { sibling, position } = this.props.insert; + sibling.insertAdjacentElement(insertPositions[position], this.portalNode); + } + } + } + + updatePortalRef(ref: HTMLDivElement | null) { + if (this.props.portalRef) { + this.props.portalRef(ref); + } + } + + render() { + return this.portalNode ? createPortal(this.props.children, this.portalNode) : null; + } +} diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx index 2aa96faeddd76..1c298e5f732df 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx @@ -5,67 +5,61 @@ * 2.0. */ -import type { EuiFlyoutProps } from '@elastic/eui'; -import { EuiFlyout } from '@elastic/eui'; -import React, { useCallback, useEffect } from 'react'; -import styled from 'styled-components'; -import { useDispatch } from 'react-redux'; +import React, { useMemo, useRef } from 'react'; +import { css } from '@emotion/react'; +import { euiThemeVars } from '@kbn/ui-theme'; -import { SELECTOR_TIMELINE_IS_VISIBLE_CSS_CLASS_NAME } from '../../timeline/styles'; import { StatefulTimeline } from '../../timeline'; import type { TimelineId } from '../../../../../common/types/timeline'; import * as i18n from './translations'; -import { timelineActions } from '../../../store/timeline'; import { defaultRowRenderers } from '../../timeline/body/renderers'; import { DefaultCellRenderer } from '../../timeline/cell_rendering/default_cell_renderer'; -import { focusActiveTimelineButton } from '../../timeline/helpers'; - +import { EuiPortal } from './custom_portal'; interface FlyoutPaneComponentProps { timelineId: TimelineId; visible?: boolean; } -const StyledEuiFlyout = styled(EuiFlyout)` - animation: none; - min-width: 150px; -`; - const FlyoutPaneComponent: React.FC = ({ timelineId, visible = true, }) => { - const dispatch = useDispatch(); - const handleClose = useCallback(() => { - dispatch(timelineActions.showTimeline({ id: timelineId, show: false })); - focusActiveTimelineButton(); - }, [dispatch, timelineId]); + const ref = useRef(null); - useEffect(() => { - if (visible) { - document.body.classList.add(SELECTOR_TIMELINE_IS_VISIBLE_CSS_CLASS_NAME); - } else { - document.body.classList.remove(SELECTOR_TIMELINE_IS_VISIBLE_CSS_CLASS_NAME); - } - }, [visible]); + const timeline = useMemo( + () => ( + + ), + [timelineId] + ); return ( -
- - - +
+ {ref?.current && ( + +
+ {timeline} +
+
+ )}
); }; diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.tsx index 3822f9bad82f1..1a91d5b0dc895 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.tsx @@ -12,7 +12,6 @@ import { EuiFlyout } from '@elastic/eui'; import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { EntityType } from '@kbn/timelines-plugin/common'; -import { euiThemeVars } from '@kbn/ui-theme'; import { getScopedActions, isInTableScope, isTimelineScope } from '../../../helpers'; import { timelineSelectors } from '../../store/timeline'; import { timelineDefaults } from '../../store/timeline/defaults'; @@ -36,9 +35,6 @@ interface DetailsPanelProps { isReadOnly?: boolean; } -// Both event detail and timeline on detection are rendered in a portal, we need to set the z-index to be below the timeline -const flyoutZIndexStyle = { zIndex: euiThemeVars.euiZLevel1 - 1 }; - /** * This panel is used in both the main timeline as well as the flyouts on the host, detection, cases, and network pages. * To prevent duplication the `isFlyoutView` prop is passed to determine the layout that should be used @@ -159,7 +155,6 @@ export const DetailsPanel = React.memo( onClose={closePanel} ownFocus={false} key={flyoutUniqueKey} - style={flyoutZIndexStyle} > {visiblePanel} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/styles.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/styles.tsx index 2a3325538b38d..5068a80fb1018 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/styles.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/styles.tsx @@ -15,16 +15,6 @@ import type { TimelineEventsType } from '../../../../common/types/timeline'; import { ACTIONS_COLUMN_ARIA_COL_INDEX } from './helpers'; import { EVENTS_TABLE_ARIA_LABEL } from './translations'; -/** - * The EUI theme's z-index property that is used by the timeline overlay - */ -export const TIMELINE_EUI_THEME_ZINDEX_LEVEL = 'euiZLevel4'; - -/** - * The css classname added to the `document.body` whenever the timeline is visible on the page - */ -export const SELECTOR_TIMELINE_IS_VISIBLE_CSS_CLASS_NAME = 'securitySolutionTimeline-isVisible'; - /** * TIMELINE BODY */ From 0dde9dc32a185c2cd3b92e7d377a398f4facd13e Mon Sep 17 00:00:00 2001 From: Patryk Kopycinski Date: Fri, 7 Apr 2023 00:27:46 +0200 Subject: [PATCH 09/22] cleanup --- .../flyout/__snapshots__/index.test.tsx.snap | 11 +---- .../components/flyout/pane/index.test.tsx | 4 +- .../components/flyout/pane/index.tsx | 44 +++++++++---------- 3 files changed, 25 insertions(+), 34 deletions(-) diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/flyout/__snapshots__/index.test.tsx.snap index 1496c6a65a5e6..c08ffdc81bf70 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/__snapshots__/index.test.tsx.snap @@ -7,16 +7,7 @@ exports[`Flyout rendering it renders correctly against snapshot 1`] = ` >
-
-
-
-
+ />
.c2 { display: block; diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.test.tsx index 0195e4d5c62f6..66eb3497aeddf 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.test.tsx @@ -50,14 +50,14 @@ describe('Pane', () => { }); }); - test('renders with display none when visibility is set to false', async () => { + test.skip('renders with display none when visibility is set to false', async () => { const EmptyComponent = render( ); await waitFor(() => { - expect(EmptyComponent.getByTestId('flyout-pane')).toHaveStyle('display: none'); + expect(EmptyComponent.getByTestId('timeline-flyout')).toHaveStyle('display: none'); }); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx index 1c298e5f732df..fdc5f19647b77 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx @@ -38,28 +38,28 @@ const FlyoutPaneComponent: React.FC = ({ ); return ( -
- {ref?.current && ( - -
- {timeline} -
-
- )} +
+ +
+ {timeline} +
+
); }; From 0e3350989507ab17bc44b5d200b29f8a719a0688 Mon Sep 17 00:00:00 2001 From: Patryk Kopycinski Date: Fri, 7 Apr 2023 17:18:05 +0200 Subject: [PATCH 10/22] fix --- x-pack/plugins/security_solution/cypress/screens/search_bar.ts | 2 ++ x-pack/plugins/security_solution/cypress/tasks/search_bar.ts | 3 +++ x-pack/plugins/security_solution/cypress/tasks/timeline.ts | 1 + 3 files changed, 6 insertions(+) diff --git a/x-pack/plugins/security_solution/cypress/screens/search_bar.ts b/x-pack/plugins/security_solution/cypress/screens/search_bar.ts index 6c57767d7709f..008f50ef1e5fa 100644 --- a/x-pack/plugins/security_solution/cypress/screens/search_bar.ts +++ b/x-pack/plugins/security_solution/cypress/screens/search_bar.ts @@ -35,6 +35,8 @@ export const GLOBAL_SEARCH_BAR_FILTER_ITEM_DELETE = '#popoverFor_filter0 button[ export const GLOBAL_SEARCH_BAR_PINNED_FILTER = '.globalFilterItem-isPinned'; +export const GLOBAL_KQL_WRAPPER = '[data-test-subj="filters-global-container"]'; + export const GLOBAL_KQL_INPUT = '[data-test-subj="filters-global-container"] [data-test-subj="unifiedQueryInput"] textarea'; diff --git a/x-pack/plugins/security_solution/cypress/tasks/search_bar.ts b/x-pack/plugins/security_solution/cypress/tasks/search_bar.ts index 2736b931ba0cf..2e66e1351e4d5 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/search_bar.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/search_bar.ts @@ -17,6 +17,7 @@ import { ADD_FILTER_FORM_OPERATOR_FIELD, ADD_FILTER_FORM_FILTER_VALUE_INPUT, GLOBAL_KQL_INPUT, + GLOBAL_KQL_WRAPPER, } from '../screens/search_bar'; export const openAddFilterPopover = () => { @@ -38,6 +39,8 @@ export const fillKqlQueryBar = (query: string) => { export const clearKqlQueryBar = () => { cy.get(GLOBAL_KQL_INPUT).should('be.visible'); cy.get(GLOBAL_KQL_INPUT).clear(); + // clicks outside of the input to close the autocomplete + cy.get('body').click(0, 0); }; export const removeKqlFilter = () => { diff --git a/x-pack/plugins/security_solution/cypress/tasks/timeline.ts b/x-pack/plugins/security_solution/cypress/tasks/timeline.ts index 779ef19b7335f..18343303aaa12 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/timeline.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/timeline.ts @@ -396,6 +396,7 @@ export const persistNoteToFirstEvent = (notes: string) => { }; export const populateTimeline = () => { + executeTimelineKQL(hostExistsQuery); executeTimelineKQL(hostExistsQuery); cy.get(SERVER_SIDE_EVENT_COUNT).should('not.have.text', '0'); }; From ed923e5ecc152faee2881fb98dd6d3cb65755047 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Fri, 7 Apr 2023 15:23:13 +0000 Subject: [PATCH 11/22] [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' --- x-pack/plugins/security_solution/cypress/tasks/search_bar.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/security_solution/cypress/tasks/search_bar.ts b/x-pack/plugins/security_solution/cypress/tasks/search_bar.ts index 2e66e1351e4d5..55af98f727fed 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/search_bar.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/search_bar.ts @@ -17,7 +17,6 @@ import { ADD_FILTER_FORM_OPERATOR_FIELD, ADD_FILTER_FORM_FILTER_VALUE_INPUT, GLOBAL_KQL_INPUT, - GLOBAL_KQL_WRAPPER, } from '../screens/search_bar'; export const openAddFilterPopover = () => { From 098c7073a31f2019e8911c4e2e200f62ae502bbc Mon Sep 17 00:00:00 2001 From: Patryk Kopycinski Date: Tue, 11 Apr 2023 14:31:22 +0200 Subject: [PATCH 12/22] fix agent version --- x-pack/test/defend_workflows_cypress/runner.ts | 4 ++-- x-pack/test/osquery_cypress/runner.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/test/defend_workflows_cypress/runner.ts b/x-pack/test/defend_workflows_cypress/runner.ts index 3c76a0baf6891..be9b833b42b4c 100644 --- a/x-pack/test/defend_workflows_cypress/runner.ts +++ b/x-pack/test/defend_workflows_cypress/runner.ts @@ -12,7 +12,7 @@ import { startRuntimeServices } from '@kbn/security-solution-plugin/scripts/endp import { FtrProviderContext } from './ftr_provider_context'; import { AgentManager } from './agent'; import { FleetManager } from './fleet_server'; -import { getLatestAvailableAgentVersion } from './utils'; +// import { getLatestAvailableAgentVersion } from './utils'; type RunnerEnv = Record; @@ -35,7 +35,7 @@ async function withFleetAgent( kibanaUrl, username, password, - version: await getLatestAvailableAgentVersion(kbnClient), + version: '8.7.1-SNAPSHOT', }); const fleetManager = new FleetManager(log); diff --git a/x-pack/test/osquery_cypress/runner.ts b/x-pack/test/osquery_cypress/runner.ts index 4075aa9d48086..963ad135723c2 100644 --- a/x-pack/test/osquery_cypress/runner.ts +++ b/x-pack/test/osquery_cypress/runner.ts @@ -15,7 +15,7 @@ import { FtrProviderContext } from './ftr_provider_context'; import { AgentManager } from './agent'; import { FleetManager } from './fleet_server'; -import { getLatestAvailableAgentVersion } from '../defend_workflows_cypress/utils'; +// import { getLatestAvailableAgentVersion } from '../defend_workflows_cypress/utils'; async function withFleetAgent( { getService }: FtrProviderContext, @@ -36,7 +36,7 @@ async function withFleetAgent( kibanaUrl, username, password, - version: await getLatestAvailableAgentVersion(kbnClient), + version: '8.7.1-SNAPSHOT', }); const fleetManager = new FleetManager(kbnClient, log); From 2b5c19e47095c8dbd3a1c33aa019a25148eb756c Mon Sep 17 00:00:00 2001 From: Patryk Kopycinski Date: Tue, 11 Apr 2023 14:43:36 +0200 Subject: [PATCH 13/22] fix selector --- x-pack/plugins/security_solution/cypress/screens/timeline.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/cypress/screens/timeline.ts b/x-pack/plugins/security_solution/cypress/screens/timeline.ts index 2559076b3fd38..411e1b73f61b3 100644 --- a/x-pack/plugins/security_solution/cypress/screens/timeline.ts +++ b/x-pack/plugins/security_solution/cypress/screens/timeline.ts @@ -207,7 +207,7 @@ export const TIMELINE_FILTER_OPERATOR = '[data-test-subj="filterOperatorList"]'; export const TIMELINE_FILTER_VALUE = '[data-test-subj="filterParamsComboBox phraseParamsComboxBox"]'; -export const TIMELINE_FLYOUT = '[data-test-subj="eui-flyout"]'; +export const TIMELINE_FLYOUT = '[data-test-subj="timeline-flyout"]'; export const TIMELINE_FLYOUT_HEADER = '[data-test-subj="query-tab-flyout-header"]'; From 9227bc804aea65d644a9b792ae2ce4dc0f45bb04 Mon Sep 17 00:00:00 2001 From: Patryk Kopycinski Date: Tue, 11 Apr 2023 15:01:04 +0200 Subject: [PATCH 14/22] fix esc key handler --- .../side_nav/src/solution_side_nav_panel.tsx | 1 - .../cypress/tasks/timeline.ts | 2 +- .../timelines/components/flyout/index.tsx | 25 +++++++++++++++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/packages/security-solution/side_nav/src/solution_side_nav_panel.tsx b/packages/security-solution/side_nav/src/solution_side_nav_panel.tsx index f884bfce5fac7..4abcc7fa6ebfd 100644 --- a/packages/security-solution/side_nav/src/solution_side_nav_panel.tsx +++ b/packages/security-solution/side_nav/src/solution_side_nav_panel.tsx @@ -89,7 +89,6 @@ export const SolutionSideNavPanel: React.FC = React.m return ( <> - {/* */} diff --git a/x-pack/plugins/security_solution/cypress/tasks/timeline.ts b/x-pack/plugins/security_solution/cypress/tasks/timeline.ts index 18343303aaa12..d640752565eca 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/timeline.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/timeline.ts @@ -320,7 +320,7 @@ export const createNewTimelineTemplate = () => { }; export const executeTimelineKQL = (query: string) => { - cy.get(`${SEARCH_OR_FILTER_CONTAINER} textarea`).type(`${query} {enter}`); + cy.get(`${SEARCH_OR_FILTER_CONTAINER} textarea`).clear().type(`${query} {enter}`); }; export const executeTimelineSearch = (query: string) => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx index 4c783c1f9d954..fd4e76b89c1c5 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx @@ -5,16 +5,19 @@ * 2.0. */ -import { EuiFocusTrap, EuiOutsideClickDetector } from '@elastic/eui'; +import { EuiFocusTrap, EuiOutsideClickDetector, EuiWindowEvent, keys } from '@elastic/eui'; import React, { useEffect, useMemo, useCallback, useState, useRef } from 'react'; - import type { AppLeaveHandler } from '@kbn/core/public'; +import { useDispatch } from 'react-redux'; + import type { TimelineId } from '../../../../common/types/timeline'; import { useDeepEqualSelector } from '../../../common/hooks/use_selector'; import { FlyoutBottomBar } from './bottom_bar'; import { Pane } from './pane'; import { getTimelineShowStatusByIdSelector } from './selectors'; import { useTimelineSavePrompt } from '../../../common/hooks/timeline/use_timeline_save_prompt'; +import { timelineActions } from '../../store/timeline'; +import { focusActiveTimelineButton } from '../timeline/helpers'; interface OwnProps { timelineId: TimelineId; @@ -26,6 +29,12 @@ type VoidFunc = () => void; const FlyoutComponent: React.FC = ({ timelineId, onAppLeave }) => { const getTimelineShowStatus = useMemo(() => getTimelineShowStatusByIdSelector(), []); const { show } = useDeepEqualSelector((state) => getTimelineShowStatus(state, timelineId)); + const dispatch = useDispatch(); + + const handleClose = useCallback(() => { + dispatch(timelineActions.showTimeline({ id: timelineId, show: false })); + focusActiveTimelineButton(); + }, [dispatch, timelineId]); const [focusOwnership, setFocusOwnership] = useState(true); const [triggerOnBlur, setTriggerOnBlur] = useState(true); @@ -37,6 +46,7 @@ const FlyoutComponent: React.FC = ({ timelineId, onAppLeave }) => { setFocusOwnership(true); } }, [show, focusOwnership]); + const onOutsideClick = useCallback((event) => { setFocusOwnership(false); const classes = event.target.classList; @@ -51,6 +61,16 @@ const FlyoutComponent: React.FC = ({ timelineId, onAppLeave }) => { } }, []); + // ESC key closes Pane + const onKeyDown = useCallback( + (ev: KeyboardEvent) => { + if (ev.key === keys.ESCAPE) { + handleClose(); + } + }, + [handleClose] + ); + useTimelineSavePrompt(timelineId, onAppLeave); useEffect(() => { @@ -75,6 +95,7 @@ const FlyoutComponent: React.FC = ({ timelineId, onAppLeave }) => { + ); From b30ed7a1669ad640f177c61a8e0bc8f95586aea2 Mon Sep 17 00:00:00 2001 From: Patryk Kopycinski Date: Tue, 11 Apr 2023 15:54:21 +0200 Subject: [PATCH 15/22] types --- x-pack/test/defend_workflows_cypress/runner.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/defend_workflows_cypress/runner.ts b/x-pack/test/defend_workflows_cypress/runner.ts index be9b833b42b4c..b7be1bd9d9d8e 100644 --- a/x-pack/test/defend_workflows_cypress/runner.ts +++ b/x-pack/test/defend_workflows_cypress/runner.ts @@ -22,7 +22,7 @@ async function withFleetAgent( ) { const log = getService('log'); const config = getService('config'); - const kbnClient = getService('kibanaServer'); + // const kbnClient = getService('kibanaServer'); const elasticUrl = Url.format(config.get('servers.elasticsearch')); const kibanaUrl = Url.format(config.get('servers.kibana')); From 521585830a9ec7a6d10b004061ac275f2ffd00b8 Mon Sep 17 00:00:00 2001 From: Patryk Kopycinski Date: Tue, 11 Apr 2023 19:29:19 +0200 Subject: [PATCH 16/22] fix --- x-pack/test/defend_workflows_cypress/runner.ts | 6 +++--- x-pack/test/osquery_cypress/runner.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/test/defend_workflows_cypress/runner.ts b/x-pack/test/defend_workflows_cypress/runner.ts index b7be1bd9d9d8e..714e50e66a345 100644 --- a/x-pack/test/defend_workflows_cypress/runner.ts +++ b/x-pack/test/defend_workflows_cypress/runner.ts @@ -12,7 +12,7 @@ import { startRuntimeServices } from '@kbn/security-solution-plugin/scripts/endp import { FtrProviderContext } from './ftr_provider_context'; import { AgentManager } from './agent'; import { FleetManager } from './fleet_server'; -// import { getLatestAvailableAgentVersion } from './utils'; +import { getLatestAvailableAgentVersion } from './utils'; type RunnerEnv = Record; @@ -22,7 +22,7 @@ async function withFleetAgent( ) { const log = getService('log'); const config = getService('config'); - // const kbnClient = getService('kibanaServer'); + const kbnClient = getService('kibanaServer'); const elasticUrl = Url.format(config.get('servers.elasticsearch')); const kibanaUrl = Url.format(config.get('servers.kibana')); @@ -35,7 +35,7 @@ async function withFleetAgent( kibanaUrl, username, password, - version: '8.7.1-SNAPSHOT', + version: getLatestAvailableAgentVersion(kbnClient), }); const fleetManager = new FleetManager(log); diff --git a/x-pack/test/osquery_cypress/runner.ts b/x-pack/test/osquery_cypress/runner.ts index 963ad135723c2..4075aa9d48086 100644 --- a/x-pack/test/osquery_cypress/runner.ts +++ b/x-pack/test/osquery_cypress/runner.ts @@ -15,7 +15,7 @@ import { FtrProviderContext } from './ftr_provider_context'; import { AgentManager } from './agent'; import { FleetManager } from './fleet_server'; -// import { getLatestAvailableAgentVersion } from '../defend_workflows_cypress/utils'; +import { getLatestAvailableAgentVersion } from '../defend_workflows_cypress/utils'; async function withFleetAgent( { getService }: FtrProviderContext, @@ -36,7 +36,7 @@ async function withFleetAgent( kibanaUrl, username, password, - version: '8.7.1-SNAPSHOT', + version: await getLatestAvailableAgentVersion(kbnClient), }); const fleetManager = new FleetManager(kbnClient, log); From b7dfb778b5fc4df2225c91feb1448c6f295d9584 Mon Sep 17 00:00:00 2001 From: Patryk Kopycinski Date: Tue, 11 Apr 2023 19:30:12 +0200 Subject: [PATCH 17/22] await --- x-pack/test/defend_workflows_cypress/runner.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/defend_workflows_cypress/runner.ts b/x-pack/test/defend_workflows_cypress/runner.ts index 714e50e66a345..3c76a0baf6891 100644 --- a/x-pack/test/defend_workflows_cypress/runner.ts +++ b/x-pack/test/defend_workflows_cypress/runner.ts @@ -35,7 +35,7 @@ async function withFleetAgent( kibanaUrl, username, password, - version: getLatestAvailableAgentVersion(kbnClient), + version: await getLatestAvailableAgentVersion(kbnClient), }); const fleetManager = new FleetManager(log); From 362a3510849029e5f5a7a58156c8c1cf424cf8e6 Mon Sep 17 00:00:00 2001 From: Patryk Kopycinski Date: Mon, 1 May 2023 19:08:23 +0200 Subject: [PATCH 18/22] WIP m --- .../public/timelines/components/flyout/pane/index.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx index fdc5f19647b77..e87bec5e3cd3c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx @@ -7,7 +7,7 @@ import React, { useMemo, useRef } from 'react'; import { css } from '@emotion/react'; -import { euiThemeVars } from '@kbn/ui-theme'; +import { useEuiBackgroundColor, useEuiTheme } from '@elastic/eui'; import { StatefulTimeline } from '../../timeline'; import type { TimelineId } from '../../../../../common/types/timeline'; @@ -24,6 +24,7 @@ const FlyoutPaneComponent: React.FC = ({ timelineId, visible = true, }) => { + const { euiTheme } = useEuiTheme(); const ref = useRef(null); const timeline = useMemo( @@ -50,10 +51,10 @@ const FlyoutPaneComponent: React.FC = ({ min-width: 150px; height: calc(100% - 96px); top: 96px; - background: white; + background: ${useEuiBackgroundColor('plain')}; position: fixed; width: 100%; - z-index: ${euiThemeVars.euiZFlyout}; + z-index: ${euiTheme.levels.flyout}; display: ${visible ? 'block' : 'none'}; `} > From f8565f4ead6b32f7530a3e89623b3a67df8f8bbf Mon Sep 17 00:00:00 2001 From: Patryk Kopycinski Date: Tue, 2 May 2023 17:46:16 +0200 Subject: [PATCH 19/22] fix --- .../plugins/security_solution/cypress/tasks/timeline.ts | 1 - .../timelines/components/flyout/pane/custom_portal.tsx | 9 +++++---- .../public/timelines/components/flyout/pane/index.tsx | 4 +--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/security_solution/cypress/tasks/timeline.ts b/x-pack/plugins/security_solution/cypress/tasks/timeline.ts index d640752565eca..4dc8c1119ef72 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/timeline.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/timeline.ts @@ -396,7 +396,6 @@ export const persistNoteToFirstEvent = (notes: string) => { }; export const populateTimeline = () => { - executeTimelineKQL(hostExistsQuery); executeTimelineKQL(hostExistsQuery); cy.get(SERVER_SIDE_EVENT_COUNT).should('not.have.text', '0'); }; diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/custom_portal.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/custom_portal.tsx index 0c16b677b7bc6..861f90851c32c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/custom_portal.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/custom_portal.tsx @@ -10,6 +10,7 @@ * into portals. */ +import deepEqual from 'fast-deep-equal'; import type { ReactNode } from 'react'; import { Component } from 'react'; import { createPortal } from 'react-dom'; @@ -29,7 +30,7 @@ export interface EuiPortalProps { * ReactNode to render as this component's content */ children: ReactNode; - insert?: { sibling: HTMLElement; position: 'before' | 'after' }; + insert?: { sibling: HTMLElement | null; position: 'before' | 'after' }; portalRef?: (ref: HTMLDivElement | null) => void; } @@ -45,7 +46,7 @@ export class EuiPortal extends Component { this.portalNode = document.createElement('div'); this.portalNode.dataset.euiportal = 'true'; - if (insert == null) { + if (insert == null || insert.sibling == null) { // no insertion defined, append to body document.body.appendChild(this.portalNode); } else { @@ -67,12 +68,12 @@ export class EuiPortal extends Component { } componentDidUpdate(prevProps: Readonly): void { - if (prevProps.insert !== this.props.insert && this.portalNode?.parentNode) { + if (!deepEqual(prevProps.insert, this.props.insert) && this.portalNode?.parentNode) { this.portalNode.parentNode.removeChild(this.portalNode); } if (this.portalNode) { - if (this.props.insert == null) { + if (this.props.insert == null || this.props.insert.sibling == null) { // no insertion defined, append to body document.body.appendChild(this.portalNode); } else { diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx index e87bec5e3cd3c..b6e8cf8b7a772 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx @@ -40,9 +40,7 @@ const FlyoutPaneComponent: React.FC = ({ return (
- +
Date: Tue, 2 May 2023 20:01:11 +0200 Subject: [PATCH 20/22] test --- x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts | 2 +- .../test/security_solution_ftr/page_objects/timeline/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts b/x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts index d420192e22b8f..f5ca1f517730f 100644 --- a/x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts +++ b/x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts @@ -607,7 +607,7 @@ describe('Alert Event Details', () => { }); }); cy.contains(timelineRegex); - cy.contains('Untitled timeline').click(); + cy.getBySel('flyoutBottomBar').contains('Untitled timeline').click(); cy.contains(filterRegex); }); }); diff --git a/x-pack/test/security_solution_ftr/page_objects/timeline/index.ts b/x-pack/test/security_solution_ftr/page_objects/timeline/index.ts index f9129158bbcb2..8194454fe4f42 100644 --- a/x-pack/test/security_solution_ftr/page_objects/timeline/index.ts +++ b/x-pack/test/security_solution_ftr/page_objects/timeline/index.ts @@ -9,7 +9,7 @@ import { subj as testSubjSelector } from '@kbn/test-subj-selector'; import { DATE_RANGE_OPTION_TO_TEST_SUBJ_MAP } from '@kbn/security-solution-plugin/common/test'; import { FtrService } from '../../../functional/ftr_provider_context'; -const TIMELINE_BOTTOM_BAR_CONTAINER_TEST_SUBJ = 'timeline-bottom-bar-container'; +const TIMELINE_BOTTOM_BAR_CONTAINER_TEST_SUBJ = 'timeline-flyout-button-bar'; const TIMELINE_CLOSE_BUTTON_TEST_SUBJ = 'close-timeline'; const TIMELINE_MODAL_PAGE_TEST_SUBJ = 'timeline'; const TIMELINE_TAB_QUERY_TEST_SUBJ = 'timeline-tab-content-query'; From 2180a49a5a7fce43690aa27ae1062a865b962140 Mon Sep 17 00:00:00 2001 From: Patryk Kopycinski Date: Tue, 2 May 2023 20:59:39 +0200 Subject: [PATCH 21/22] test --- .../public/timelines/components/flyout/index.tsx | 2 +- .../test/security_solution_ftr/page_objects/timeline/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx index fd4e76b89c1c5..629cf0d5be52d 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx @@ -91,10 +91,10 @@ const FlyoutComponent: React.FC = ({ timelineId, onAppLeave }) => { return ( <> + - diff --git a/x-pack/test/security_solution_ftr/page_objects/timeline/index.ts b/x-pack/test/security_solution_ftr/page_objects/timeline/index.ts index 8194454fe4f42..f9129158bbcb2 100644 --- a/x-pack/test/security_solution_ftr/page_objects/timeline/index.ts +++ b/x-pack/test/security_solution_ftr/page_objects/timeline/index.ts @@ -9,7 +9,7 @@ import { subj as testSubjSelector } from '@kbn/test-subj-selector'; import { DATE_RANGE_OPTION_TO_TEST_SUBJ_MAP } from '@kbn/security-solution-plugin/common/test'; import { FtrService } from '../../../functional/ftr_provider_context'; -const TIMELINE_BOTTOM_BAR_CONTAINER_TEST_SUBJ = 'timeline-flyout-button-bar'; +const TIMELINE_BOTTOM_BAR_CONTAINER_TEST_SUBJ = 'timeline-bottom-bar-container'; const TIMELINE_CLOSE_BUTTON_TEST_SUBJ = 'close-timeline'; const TIMELINE_MODAL_PAGE_TEST_SUBJ = 'timeline'; const TIMELINE_TAB_QUERY_TEST_SUBJ = 'timeline-tab-content-query'; From 75bc5bc04a58b6f5564da7a7eccbae7c9dfb8519 Mon Sep 17 00:00:00 2001 From: Patryk Kopycinski Date: Tue, 2 May 2023 22:09:28 +0200 Subject: [PATCH 22/22] test --- .../public/timelines/components/flyout/index.tsx | 2 +- .../test/security_solution_ftr/page_objects/timeline/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx index 629cf0d5be52d..fd4e76b89c1c5 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx @@ -91,10 +91,10 @@ const FlyoutComponent: React.FC = ({ timelineId, onAppLeave }) => { return ( <> - + diff --git a/x-pack/test/security_solution_ftr/page_objects/timeline/index.ts b/x-pack/test/security_solution_ftr/page_objects/timeline/index.ts index f9129158bbcb2..e7d2bc56aeab2 100644 --- a/x-pack/test/security_solution_ftr/page_objects/timeline/index.ts +++ b/x-pack/test/security_solution_ftr/page_objects/timeline/index.ts @@ -9,7 +9,7 @@ import { subj as testSubjSelector } from '@kbn/test-subj-selector'; import { DATE_RANGE_OPTION_TO_TEST_SUBJ_MAP } from '@kbn/security-solution-plugin/common/test'; import { FtrService } from '../../../functional/ftr_provider_context'; -const TIMELINE_BOTTOM_BAR_CONTAINER_TEST_SUBJ = 'timeline-bottom-bar-container'; +const TIMELINE_BOTTOM_BAR_CONTAINER_TEST_SUBJ = 'flyoutBottomBar'; const TIMELINE_CLOSE_BUTTON_TEST_SUBJ = 'close-timeline'; const TIMELINE_MODAL_PAGE_TEST_SUBJ = 'timeline'; const TIMELINE_TAB_QUERY_TEST_SUBJ = 'timeline-tab-content-query';