From e7242593f9b26d63a49f2f389f74958f380c725b Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 7 Mar 2023 11:00:09 -0500 Subject: [PATCH] [8.7] [Security Solution][Investigations] - 8.7 minor fixes (#152284) (#152758) # Backport This will backport the following commits from `main` to `8.7`: - [[Security Solution][Investigations] - 8.7 minor fixes (#152284)](https://github.com/elastic/kibana/pull/152284) ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) Co-authored-by: Michael Olorunnisola --- .../cypress/e2e/timelines/creation.cy.ts | 65 +++++++++++++++++++ .../cypress/screens/create_new_rule.ts | 2 + .../alerts_histogram_panel/index.tsx | 3 +- .../timeline/eql_tab_content/index.tsx | 3 +- .../timeline/query_bar/eql/index.tsx | 5 +- 5 files changed, 74 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/security_solution/cypress/e2e/timelines/creation.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/timelines/creation.cy.ts index 62d8fdb8f1b4..81e74661d183 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/timelines/creation.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/timelines/creation.cy.ts @@ -22,6 +22,7 @@ import { TIMELINE_TAB_CONTENT_GRAPHS_NOTES, EDIT_TIMELINE_BTN, EDIT_TIMELINE_TOOLTIP, + TIMELINE_CORRELATION_INPUT, } from '../../screens/timeline'; import { createTimelineTemplate } from '../../tasks/api_calls/timelines'; @@ -41,9 +42,11 @@ import { goToQueryTab, pinFirstEvent, populateTimeline, + waitForTimelineChanges, } from '../../tasks/timeline'; import { OVERVIEW_URL, TIMELINE_TEMPLATES_URL } from '../../urls/navigation'; +import { EQL_QUERY_VALIDATION_ERROR } from '../../screens/create_new_rule'; describe('Create a timeline from a template', () => { before(() => { @@ -154,5 +157,67 @@ describe('Timelines', (): void => { .then(parseInt) .should('be.gt', 0); }); + + // Skipped in this PR until the underlying re-renders are fixed: https://github.com/elastic/kibana/pull/152284 + describe.skip('correlation tab', () => { + it('should update timeline after adding eql', () => { + cy.intercept('PATCH', '/api/timeline').as('updateTimeline'); + const eql = 'any where process.name == "zsh"'; + addEqlToTimeline(eql); + + cy.wait('@updateTimeline', { timeout: 10000 }).its('response.statusCode').should('eq', 200); + + cy.get(`${TIMELINE_TAB_CONTENT_EQL} ${SERVER_SIDE_EVENT_COUNT}`) + .invoke('text') + .then(parseInt) + .should('be.gt', 0); + }); + + describe.skip('updates', () => { + const eql = 'any where process.name == "zsh"'; + beforeEach(() => { + cy.intercept('PATCH', '/api/timeline').as('updateTimeline'); + addEqlToTimeline(eql); + // TODO: It may need a further refactor to handle the frequency with which react calls this api + // Since it's based on real time text changes...and real time query validation + // there's almost no guarantee on the number of calls, so a cypress.wait may actually be more appropriate + cy.wait('@updateTimeline'); + cy.wait('@updateTimeline'); + cy.reload(); + cy.get(TIMELINE_CORRELATION_INPUT).should('be.visible'); + cy.get(TIMELINE_CORRELATION_INPUT).should('have.text', eql); + }); + + it('should update timeline after removing eql', () => { + cy.intercept('PATCH', '/api/timeline').as('updateTimeline'); + cy.get(TIMELINE_CORRELATION_INPUT).should('be.visible'); + waitForTimelineChanges(); + cy.get(TIMELINE_CORRELATION_INPUT).type('{selectAll} {del}').clear(); + // TODO: It may need a further refactor to handle the frequency with which react calls this api + // Since it's based on real time text changes...and real time query validation + // there's almost no guarantee on the number of calls, so a cypress.wait may actually be more appropriate + cy.wait('@updateTimeline'); + cy.wait('@updateTimeline'); + cy.wait('@updateTimeline'); + cy.wait('@updateTimeline'); + waitForTimelineChanges(); + cy.reload(); + cy.get(TIMELINE_CORRELATION_INPUT).should('be.visible'); + + cy.get(TIMELINE_CORRELATION_INPUT).should('have.text', ''); + }); + + it('should NOT update timeline after adding wrong eql', () => { + cy.intercept('PATCH', '/api/timeline').as('updateTimeline'); + const nonFunctionalEql = 'this is not valid eql'; + addEqlToTimeline(nonFunctionalEql); + cy.get(EQL_QUERY_VALIDATION_ERROR).should('be.visible'); + cy.reload(); + cy.get(TIMELINE_CORRELATION_INPUT).should('be.visible'); + + cy.get(TIMELINE_CORRELATION_INPUT).should('have.text', eql); + }); + }); + }); }); }); diff --git a/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts b/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts index 80b53926ed72..61677bbd73b7 100644 --- a/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts +++ b/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts @@ -89,6 +89,8 @@ export const EQL_QUERY_INPUT = '[data-test-subj="eqlQueryBarTextInput"]'; export const EQL_QUERY_VALIDATION_SPINNER = '[data-test-subj="eql-validation-loading"]'; +export const EQL_QUERY_VALIDATION_ERROR = '[data-test-subj="eql-validation-errors-popover-button"]'; + export const IMPORT_QUERY_FROM_SAVED_TIMELINE_LINK = '[data-test-subj="importQueryFromSavedTimeline"]'; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx index 814f5120da78..3e89ae0bacf6 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx @@ -385,7 +385,7 @@ export const AlertsHistogramPanel = memo( alignHeader={alignHeader} id={uniqueQueryId} inspectTitle={inspectTitle} - outerDirection="row" + outerDirection="column" title={titleText} titleSize={titleSize} toggleStatus={showHistogram} @@ -393,7 +393,6 @@ export const AlertsHistogramPanel = memo( showInspectButton={isChartEmbeddablesEnabled ? false : chartOptionsContextMenu == null} subtitle={!isInitialLoading && showTotalAlertsCount && totalAlerts} isInspectDisabled={isInspectDisabled} - hideSubtitle > diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.tsx index 87bd628ca48c..8bcf48b869f3 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.tsx @@ -69,11 +69,12 @@ const StyledEuiFlyoutHeader = styled(EuiFlyoutHeader)` box-shadow: none; display: flex; flex-direction: column; + margin-top: ${({ theme }) => theme.eui.euiSizeM} padding: 0; &.euiFlyoutHeader { ${({ theme }) => - `padding: 0 ${theme.eui.euiSizeS} ${theme.eui.euiSizeS} ${theme.eui.euiSizeS};`} + `padding: 0 ${theme.eui.euiSizeM} ${theme.eui.euiSizeS} ${theme.eui.euiSizeS};`} } `; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/eql/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/eql/index.tsx index 56969a288102..f4b21265a790 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/eql/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/eql/index.tsx @@ -107,6 +107,8 @@ export const EqlQueryBarTimeline = memo(({ timelineId }: { timelineId: string }) watch: ['eqlQueryBar'], }); + const prevEqlQuery = useRef(''); + const optionsData = useMemo( () => isEmpty(indexPattern.fields) @@ -156,10 +158,11 @@ export const EqlQueryBarTimeline = memo(({ timelineId }: { timelineId: string }) useEffect(() => { if ( formEqlQueryBar != null && - !isEmpty(formEqlQueryBar.query.query) && + prevEqlQuery.current !== formEqlQueryBar.query.query && isQueryBarValid && !isQueryBarValidating ) { + prevEqlQuery.current = formEqlQueryBar.query.query; dispatch( timelineActions.updateEqlOptions({ id: timelineId,