diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_table.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_table.tsx index 2504392d5ef1..4e7e443972ab 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_table.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_table.tsx @@ -7,19 +7,19 @@ import React, { memo, useCallback, useEffect, useMemo, useState } from 'react'; import { - EuiI18nNumber, + type CriteriaWithPagination, EuiAvatar, EuiBasicTable, EuiButtonIcon, EuiFacetButton, EuiHorizontalRule, - RIGHT_ALIGNMENT, + EuiI18nNumber, EuiScreenReaderOnly, + EuiSkeletonText, EuiText, EuiToolTip, type HorizontalAlignment, - type CriteriaWithPagination, - EuiSkeletonText, + RIGHT_ALIGNMENT, } from '@elastic/eui'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -30,14 +30,13 @@ import { SecuritySolutionLinkAnchor } from '../../../../common/components/links' import type { ActionListApiResponse } from '../../../../../common/endpoint/types'; import type { EndpointActionListRequestQuery } from '../../../../../common/api/endpoint'; import { FormattedDate } from '../../../../common/components/formatted_date'; -import { TABLE_COLUMN_NAMES, UX_MESSAGES, ARIA_LABELS } from '../translations'; +import { ARIA_LABELS, TABLE_COLUMN_NAMES, UX_MESSAGES } from '../translations'; import { getActionStatus, getUiCommand } from './hooks'; import { getEmptyValue } from '../../../../common/components/empty_value'; import { StatusBadge } from './status_badge'; import { ActionsLogExpandedTray } from './action_log_expanded_tray'; import { useTestIdGenerator } from '../../../hooks/use_test_id_generator'; import { MANAGEMENT_PAGE_SIZE_OPTIONS } from '../../../common/constants'; -import { useActionHistoryUrlParams } from './use_action_history_url_params'; import { useUrlPagination } from '../../../hooks/use_url_pagination'; const emptyValue = getEmptyValue(); @@ -292,22 +291,19 @@ export const ActionsLogTable = memo( }) => { const getTestId = useTestIdGenerator(dataTestSubj); const { pagination: paginationFromUrlParams } = useUrlPagination(); - const { withOutputs: withOutputsFromUrl } = useActionHistoryUrlParams(); const [expandedRowMap, setExpandedRowMap] = useState({}); - const actionIdsWithOpenTrays = useMemo((): string[] => { - // get the list of action ids from URL params on the history page - if (!isFlyout) { - return withOutputsFromUrl ?? []; - } - // get the list of action ids form the query params for flyout view - return queryParams.withOutputs - ? typeof queryParams.withOutputs === 'string' - ? [queryParams.withOutputs] - : queryParams.withOutputs - : []; - }, [isFlyout, queryParams.withOutputs, withOutputsFromUrl]); + const actionIdsWithOpenTrays = useMemo( + (): string[] => + // get the list of action ids from the query params for flyout view + queryParams.withOutputs + ? typeof queryParams.withOutputs === 'string' + ? [queryParams.withOutputs] + : queryParams.withOutputs + : [], + [queryParams.withOutputs] + ); const redoOpenTrays = useCallback(() => { if (actionIdsWithOpenTrays.length && items.length) { diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/integration_tests/response_actions_log.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/integration_tests/response_actions_log.test.tsx index 476a86a6561d..1e835e34ac7e 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/integration_tests/response_actions_log.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/integration_tests/response_actions_log.test.tsx @@ -7,12 +7,13 @@ import React from 'react'; import * as reactTestingLibrary from '@testing-library/react'; +import { waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { waitForEuiPopoverOpen } from '@elastic/eui/lib/test/rtl'; import type { IHttpFetchError } from '@kbn/core-http-browser'; import { - createAppRootMockRenderer, type AppContextTestRender, + createAppRootMockRenderer, } from '../../../../common/mock/endpoint'; import { ResponseActionsLog } from '../response_actions_log'; import type { @@ -29,7 +30,6 @@ import { v4 as uuidv4 } from 'uuid'; import { RESPONSE_ACTION_API_COMMANDS_NAMES } from '../../../../../common/endpoint/service/response_actions/constants'; import { useUserPrivileges as _useUserPrivileges } from '../../../../common/components/user_privileges'; import { responseActionsHttpMocks } from '../../../mocks/response_actions_http_mocks'; -import { waitFor } from '@testing-library/react'; import { getEndpointAuthzInitialStateMock } from '../../../../../common/endpoint/service/authz/mocks'; import { useGetEndpointActionList as _useGetEndpointActionList } from '../../../hooks/response_actions/use_get_endpoint_action_list'; import { OUTPUT_MESSAGES } from '../translations'; @@ -470,7 +470,7 @@ describe('Response actions history', () => { ); }); - it('should expand each row to show details', async () => { + it('should expand/collapse each row to show/hide details', async () => { render(); const { getAllByTestId, queryAllByTestId } = renderResult; @@ -961,8 +961,7 @@ describe('Response actions history', () => { const expandButtons = getAllByTestId(`${testPrefix}-expand-button`); expandButtons.map((button) => userEvent.click(button)); - const outputs = getAllByTestId(`${testPrefix}-details-tray-output`); - return outputs; + return getAllByTestId(`${testPrefix}-details-tray-output`); }; it.each(RESPONSE_ACTION_API_COMMANDS_NAMES)( diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/reponse_actions_history.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/reponse_actions_history.cy.ts index cb6c7c3a96ee..5c4bb0f3efb8 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/reponse_actions_history.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/reponse_actions_history.cy.ts @@ -50,4 +50,25 @@ describe('Response actions history page', () => { cy.getByTestSubj('pagination-button-0').click(); cy.getByTestSubj('response-actions-list-details-tray').should('exist'); }); + + it('collapses expanded tray with a single click', () => { + loadPage(`/app/security/administration/response_actions_history`); + // 2nd row on 1st page + const row = cy.getByTestSubj('response-actions-list-expand-button').eq(1); + + // expand the row + row.click(); + cy.getByTestSubj('response-actions-list-details-tray').should('exist'); + cy.url().should('include', 'withOutputs'); + + // collapse the row + cy.intercept('GET', '/api/endpoint/action*').as('getResponses'); + row.click(); + // wait for the API response to come back + // and then see if the tray is actually closed + cy.wait('@getResponses', { timeout: 500 }).then(() => { + cy.getByTestSubj('response-actions-list-details-tray').should('not.exist'); + cy.url().should('not.include', 'withOutputs'); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/response_actions/view/response_actions_list_page.test.tsx b/x-pack/plugins/security_solution/public/management/pages/response_actions/view/response_actions_list_page.test.tsx index ebde74b17be7..ea720f79a66c 100644 --- a/x-pack/plugins/security_solution/public/management/pages/response_actions/view/response_actions_list_page.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/response_actions/view/response_actions_list_page.test.tsx @@ -236,7 +236,7 @@ describe('Response actions history page', () => { return { id: `agent-id-${i}`, name: `Host-name-${i}`, - selected: [0, 1, 3, 5].includes(i) ? true : false, + selected: [0, 1, 3, 5].includes(i), }; }), page: 0,