From bbb531af3a83c9cbd9d5591a83a9481514d24e38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20S=C3=A1nchez?= Date: Fri, 18 Mar 2022 16:23:01 +0100 Subject: [PATCH] [Security Solution] [Endpoint] Search params are reset when opening flyout in policy details artifact tab (#127718) * Fixes wrong message size * Fixes error with url params when opening flyout * Fixes checks errors * removes unused code * Fix wrong url page when default one * Replace old url pagination params by new ones on use_url_pagination hook * Moves useEffect into a new hook that fixes url pagination params, also adds a unit test for it * Adds note info in jsdoc for new hook Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../public/management/common/routing.ts | 15 ++-- .../use_old_url_search_pagination_replace.ts | 33 ++++++++ .../components/hooks/use_url_pagination.ts | 3 +- .../reducer/initial_policy_details_state.ts | 4 +- .../pages/policy/test_utils/mocks.ts | 83 +------------------ .../public/management/pages/policy/types.ts | 4 +- .../flyout/policy_artifacts_flyout.tsx | 6 +- .../list/policy_artifacts_list.test.tsx | 10 +++ .../artifacts/list/policy_artifacts_list.tsx | 2 + 9 files changed, 66 insertions(+), 94 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/management/components/hooks/use_old_url_search_pagination_replace.ts diff --git a/x-pack/plugins/security_solution/public/management/common/routing.ts b/x-pack/plugins/security_solution/public/management/common/routing.ts index d031e50152a66d..2e84f38989542b 100644 --- a/x-pack/plugins/security_solution/public/management/common/routing.ts +++ b/x-pack/plugins/security_solution/public/management/common/routing.ts @@ -11,6 +11,7 @@ import querystring from 'querystring'; import { generatePath } from 'react-router-dom'; import { appendSearch } from '../../common/components/link_to/helpers'; import { ArtifactListPageUrlParams } from '../components/artifact_list_page'; +import { paginationFromUrlParams } from '../components/hooks/use_url_pagination'; import { EndpointIndexUIQueryParams } from '../pages/endpoint_hosts/types'; import { EventFiltersPageLocation } from '../pages/event_filters/types'; import { HostIsolationExceptionsPageLocation } from '../pages/host_isolation_exceptions/types'; @@ -181,11 +182,11 @@ const normalizePolicyDetailsArtifactsListPageLocation = ( ): Partial => { if (location) { return { - ...(!isDefaultOrMissing(location.page_index, MANAGEMENT_DEFAULT_PAGE) - ? { page_index: location.page_index } + ...(!isDefaultOrMissing(location.page, MANAGEMENT_DEFAULT_PAGE + 1) + ? { page: location.page } : {}), - ...(!isDefaultOrMissing(location.page_size, MANAGEMENT_DEFAULT_PAGE_SIZE) - ? { page_size: location.page_size } + ...(!isDefaultOrMissing(location.pageSize, MANAGEMENT_DEFAULT_PAGE_SIZE) + ? { pageSize: location.pageSize } : {}), ...(!isDefaultOrMissing(location.show, undefined) ? { show: location.show } : {}), ...(!isDefaultOrMissing(location.filter, '') ? { filter: location.filter } : ''), @@ -348,9 +349,11 @@ export const extractPolicyDetailsArtifactsListPageLocation = ( query, 'show' ) as PolicyDetailsArtifactsPageLocation['show']; - + const pagination = paginationFromUrlParams(query); return { - ...extractListPaginationParams(query), + page: pagination.page, + pageSize: pagination.pageSize, + filter: query.filter as string, show: showParamValue && 'list' === showParamValue ? showParamValue : undefined, }; }; diff --git a/x-pack/plugins/security_solution/public/management/components/hooks/use_old_url_search_pagination_replace.ts b/x-pack/plugins/security_solution/public/management/components/hooks/use_old_url_search_pagination_replace.ts new file mode 100644 index 00000000000000..817a2e91e726c7 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/hooks/use_old_url_search_pagination_replace.ts @@ -0,0 +1,33 @@ +/* + * 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. + */ + +import { useEffect } from 'react'; +import { useHistory } from 'react-router-dom'; +import { useUrlParams } from './use_url_params'; + +/** + * Replaces old page_index and page_size url params by the new ones, page and pageSize + * + * NOTE: This hook will also increment the `page_index` by 1 since `page` is now one-based + */ +export const useOldUrlSearchPaginationReplace = (): void => { + const history = useHistory(); + const { urlParams } = useUrlParams(); + + useEffect(() => { + if ((urlParams.page_index && !urlParams.page) || (urlParams.page_size && !urlParams.pageSize)) { + history.replace( + `${history.location.pathname}${history.location.search + .replaceAll('page_size', 'pageSize') + .replaceAll( + `page_index=${urlParams.page_index}`, + `page=${Number(urlParams.page_index) + 1}` + )}` + ); + } + }, [history, urlParams.page, urlParams.pageSize, urlParams.page_index, urlParams.page_size]); +}; diff --git a/x-pack/plugins/security_solution/public/management/components/hooks/use_url_pagination.ts b/x-pack/plugins/security_solution/public/management/components/hooks/use_url_pagination.ts index 84524ec2b7a48b..3a10178c95468b 100644 --- a/x-pack/plugins/security_solution/public/management/components/hooks/use_url_pagination.ts +++ b/x-pack/plugins/security_solution/public/management/components/hooks/use_url_pagination.ts @@ -25,7 +25,7 @@ interface UrlPagination { type UrlPaginationParams = Partial; -const paginationFromUrlParams = (urlParams: UrlPaginationParams): Pagination => { +export const paginationFromUrlParams = (urlParams: UrlPaginationParams): Pagination => { const pagination: Pagination = { pageSize: MANAGEMENT_DEFAULT_PAGE_SIZE, page: 1, @@ -64,6 +64,7 @@ export const useUrlPagination = (): UrlPagination => { const location = useLocation(); const history = useHistory(); const { urlParams, toUrlParams } = useUrlParams(); + const urlPaginationParams = useMemo(() => { return paginationFromUrlParams(urlParams); }, [urlParams]); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer/initial_policy_details_state.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer/initial_policy_details_state.ts index 23bd0f9a56d3e9..a38598bf9d2419 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer/initial_policy_details_state.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer/initial_policy_details_state.ts @@ -28,8 +28,8 @@ export const initialPolicyDetailsState: () => Immutable = () }, artifacts: { location: { - page_index: MANAGEMENT_DEFAULT_PAGE, - page_size: MANAGEMENT_DEFAULT_PAGE_SIZE, + page: MANAGEMENT_DEFAULT_PAGE, + pageSize: MANAGEMENT_DEFAULT_PAGE_SIZE, show: undefined, filter: '', }, diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/test_utils/mocks.ts b/x-pack/plugins/security_solution/public/management/pages/policy/test_utils/mocks.ts index 3b9f6a45250ac7..c1b30b6fad10cc 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/test_utils/mocks.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/test_utils/mocks.ts @@ -5,34 +5,8 @@ * 2.0. */ -import { composeHttpHandlerMocks } from '../../../../common/mock/endpoint/http_handler_mock_factory'; -import { - GetTrustedAppsListResponse, - PostTrustedAppCreateResponse, -} from '../../../../../common/endpoint/types'; -import { createSampleTrustedApp, createSampleTrustedApps } from '../../trusted_apps/test_utils'; -import { - PolicyDetailsArtifactsPageListLocationParams, - PolicyDetailsArtifactsPageLocation, -} from '../types'; -import { - fleetGetAgentStatusHttpMock, - FleetGetAgentStatusHttpMockInterface, - fleetGetEndpointPackagePolicyHttpMock, - FleetGetEndpointPackagePolicyHttpMockInterface, - fleetGetEndpointPackagePolicyListHttpMock, - FleetGetEndpointPackagePolicyListHttpMockInterface, - trustedAppsGetListHttpMocks, - TrustedAppsGetListHttpMocksInterface, - trustedAppPutHttpMocks, - TrustedAppPutHttpMocksInterface, - trustedAppsGetOneHttpMocks, - TrustedAppsGetOneHttpMocksInterface, - fleetGetAgentPolicyListHttpMock, - FleetGetAgentPolicyListHttpMockInterface, - trustedAppsPostCreateListHttpMock, - TrustedAppsPostCreateListHttpMockInterface, -} from '../../mocks'; +import { GetTrustedAppsListResponse } from '../../../../../common/endpoint/types'; +import { createSampleTrustedApps } from '../../trusted_apps/test_utils'; export const getMockListResponse: () => GetTrustedAppsListResponse = () => ({ data: createSampleTrustedApps({}), @@ -40,56 +14,3 @@ export const getMockListResponse: () => GetTrustedAppsListResponse = () => ({ page: 1, total: 100, }); - -export const getMockPolicyDetailsArtifactsPageLocationUrlParams = ( - overrides: Partial = {} -): PolicyDetailsArtifactsPageLocation => { - return { - page_index: 0, - page_size: 10, - filter: '', - show: undefined, - ...overrides, - }; -}; - -export const getMockPolicyDetailsArtifactListUrlParams = ( - overrides: Partial = {} -): PolicyDetailsArtifactsPageListLocationParams => { - return { - page_index: 0, - page_size: 10, - filter: '', - ...overrides, - }; -}; - -export const getMockCreateResponse: () => PostTrustedAppCreateResponse = () => - createSampleTrustedApp(1) as unknown as unknown as PostTrustedAppCreateResponse; - -export const getAPIError = () => ({ - statusCode: 500, - error: 'Internal Server Error', - message: 'Something is not right', -}); - -export type PolicyDetailsPageAllApiHttpMocksInterface = - FleetGetEndpointPackagePolicyHttpMockInterface & - FleetGetAgentStatusHttpMockInterface & - FleetGetEndpointPackagePolicyListHttpMockInterface & - FleetGetAgentPolicyListHttpMockInterface & - TrustedAppsGetListHttpMocksInterface & - TrustedAppPutHttpMocksInterface & - TrustedAppsGetOneHttpMocksInterface & - TrustedAppsPostCreateListHttpMockInterface; -export const policyDetailsPageAllApiHttpMocks = - composeHttpHandlerMocks([ - fleetGetEndpointPackagePolicyHttpMock, - fleetGetAgentStatusHttpMock, - fleetGetEndpointPackagePolicyListHttpMock, - fleetGetAgentPolicyListHttpMock, - trustedAppsGetListHttpMocks, - trustedAppPutHttpMocks, - trustedAppsGetOneHttpMocks, - trustedAppsPostCreateListHttpMock, - ]); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/types.ts b/x-pack/plugins/security_solution/public/management/pages/policy/types.ts index 6057c0545fa635..dfdd0145992bf5 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/types.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/types.ts @@ -90,8 +90,8 @@ export interface PolicyArtifactsState { } export interface PolicyDetailsArtifactsPageListLocationParams { - page_index: number; - page_size: number; + page: number; + pageSize: number; filter: string; } diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/flyout/policy_artifacts_flyout.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/flyout/policy_artifacts_flyout.tsx index 1ba31da5653049..3372d4e122f7cf 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/flyout/policy_artifacts_flyout.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/flyout/policy_artifacts_flyout.tsx @@ -150,8 +150,9 @@ export const PolicyArtifactsFlyout = React.memo( if (!assignableArtifacts) { return ( {labels.flyoutNoArtifactsToBeAssignedMessage}

} + body={

{labels.flyoutNoArtifactsToBeAssignedMessage}

} /> ); } @@ -160,8 +161,9 @@ export const PolicyArtifactsFlyout = React.memo( if (artifacts?.total === 0) { return ( {labels.flyoutNoSearchResultsMessage}

} + body={

{labels.flyoutNoSearchResultsMessage}

} /> ); } diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.test.tsx index 9ce3d56dac4724..d59285f4d8b78b 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.test.tsx @@ -167,6 +167,16 @@ describe('Policy details artifacts list', () => { expect(renderResult.queryByTestId('remove-from-policy-action')).toBeNull(); }); + it('should replace old url search pagination params with correct ones', async () => { + history.replace(`${history.location.pathname}?page_index=0&page_size=10`); + await render(); + + expect(history.location.search).toMatch('pageSize=10'); + expect(history.location.search).toMatch('page=1'); + expect(history.location.search).not.toMatch('page_index'); + expect(history.location.search).not.toMatch('page_size'); + }); + describe('without external privileges', () => { it('should not display the delete action, do show the full details', async () => { mockedApi.responseProvider.eventFiltersList.mockReturnValue( diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.tsx index 4c87ba883f39a2..7f6e2e5cec1803 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/list/policy_artifacts_list.tsx @@ -15,6 +15,7 @@ import { useEndpointPoliciesToArtifactPolicies } from '../../../../../components import { useUrlParams } from '../../../../../components/hooks/use_url_params'; import { useUrlPagination } from '../../../../../components/hooks/use_url_pagination'; import { useGetEndpointSpecificPolicies } from '../../../../../services/policies/hooks'; +import { useOldUrlSearchPaginationReplace } from '../../../../../components/hooks/use_old_url_search_pagination_replace'; import { ArtifactCardGrid, ArtifactCardGridProps, @@ -58,6 +59,7 @@ export const PolicyArtifactsList = React.memo( onDeleteActionCallback, externalPrivileges = true, }) => { + useOldUrlSearchPaginationReplace(); const { getAppUrl } = useAppUrl(); const { canCreateArtifactsByPolicy } = useUserPrivileges().endpointPrivileges; const policiesRequest = useGetEndpointSpecificPolicies({ perPage: 1000 });