diff --git a/frontend/src/AppRoutes/pageComponents.ts b/frontend/src/AppRoutes/pageComponents.ts index 1252496c08..bda390afbf 100644 --- a/frontend/src/AppRoutes/pageComponents.ts +++ b/frontend/src/AppRoutes/pageComponents.ts @@ -7,7 +7,7 @@ export const ServicesTablePage = Loadable( export const ServiceMetricsPage = Loadable( () => import( - /* webpackChunkName: "ServiceMetricsPage" */ 'pages/MetricsApplication' + /* webpackChunkName: "ServiceMetricsPage" */ 'pages/MetricsApplication/MetricsApplication' ), ); diff --git a/frontend/src/hooks/useResourceAttribute/ResourceProvider.tsx b/frontend/src/hooks/useResourceAttribute/ResourceProvider.tsx index 8a3de793e8..895f67ac34 100644 --- a/frontend/src/hooks/useResourceAttribute/ResourceProvider.tsx +++ b/frontend/src/hooks/useResourceAttribute/ResourceProvider.tsx @@ -1,5 +1,7 @@ import { useMachine } from '@xstate/react'; +import { QueryParams } from 'constants/query'; import ROUTES from 'constants/routes'; +import useUrlQuery from 'hooks/useUrlQuery'; import { encode } from 'js-base64'; import history from 'lib/history'; import { ReactNode, useCallback, useMemo, useState } from 'react'; @@ -30,6 +32,7 @@ function ResourceProvider({ children }: Props): JSX.Element { const [queries, setQueries] = useState( getResourceAttributeQueriesFromURL(), ); + const urlQuery = useUrlQuery(); const [optionsData, setOptionsData] = useState({ mode: undefined, @@ -45,17 +48,15 @@ function ResourceProvider({ children }: Props): JSX.Element { const dispatchQueries = useCallback( (queries: IResourceAttribute[]): void => { - history.replace({ - pathname, - search: - queries && queries.length - ? `?resourceAttribute=${encode(JSON.stringify(queries))}` - : '', - }); - + urlQuery.set( + QueryParams.resourceAttributes, + encode(JSON.stringify(queries)), + ); + const generatedUrl = `${pathname}?${urlQuery.toString()}`; + history.replace(generatedUrl); setQueries(queries); }, - [pathname], + [pathname, urlQuery], ); const [state, send] = useMachine(ResourceAttributesFilterMachine, { diff --git a/frontend/src/hooks/useResourceAttribute/__tests__/useResourceAttribute.test.tsx b/frontend/src/hooks/useResourceAttribute/__tests__/useResourceAttribute.test.tsx new file mode 100644 index 0000000000..653cf48e53 --- /dev/null +++ b/frontend/src/hooks/useResourceAttribute/__tests__/useResourceAttribute.test.tsx @@ -0,0 +1,28 @@ +import { act, renderHook, waitFor } from '@testing-library/react'; +import { createMemoryHistory } from 'history'; +import { Router } from 'react-router-dom'; + +import ResourceProvider from '../ResourceProvider'; +import useResourceAttribute from '../useResourceAttribute'; + +describe('useResourceAttribute component hook', () => { + it('should not change other query params except for resourceAttribute', async () => { + const history = createMemoryHistory({ + initialEntries: ['/inital-url?tab=overview'], + }); + const wrapper = ({ children }: { children: any }): JSX.Element => ( + + {children} + + ); + const { result } = renderHook(() => useResourceAttribute(), { wrapper }); + + act(() => { + result.current.handleEnvironmentChange(['production']); + }); + + await waitFor(() => + expect(history.location.search).toContain('tab=overview'), + ); + }); +}); diff --git a/frontend/src/hooks/useResourceAttribute/utils.ts b/frontend/src/hooks/useResourceAttribute/utils.ts index ca70e8bd5c..77fdddfbea 100644 --- a/frontend/src/hooks/useResourceAttribute/utils.ts +++ b/frontend/src/hooks/useResourceAttribute/utils.ts @@ -176,8 +176,6 @@ export const GetTagValues = async (tagKey: string): Promise => { export const createQuery = ( selectedItems: Array = [], ): IResourceAttribute | null => { - console.log('selectedItems', selectedItems); - if (selectedItems.length === 3) { return { id: uuid().slice(0, 8), @@ -192,6 +190,7 @@ export const createQuery = ( export const updateQuery = ( queryKey: string, selectedItems: Array = [], + // eslint-disable-next-line sonarjs/no-identical-functions ): IResourceAttribute | null => { if (selectedItems.length === 3) { return { diff --git a/frontend/src/pages/MetricsApplication/index.tsx b/frontend/src/pages/MetricsApplication/MetricsApplication.tsx similarity index 73% rename from frontend/src/pages/MetricsApplication/index.tsx rename to frontend/src/pages/MetricsApplication/MetricsApplication.tsx index 1b0229e5d1..497cdc1f5f 100644 --- a/frontend/src/pages/MetricsApplication/index.tsx +++ b/frontend/src/pages/MetricsApplication/MetricsApplication.tsx @@ -4,8 +4,9 @@ import DBCall from 'container/MetricsApplication/Tabs/DBCall'; import External from 'container/MetricsApplication/Tabs/External'; import Overview from 'container/MetricsApplication/Tabs/Overview'; import ResourceAttributesFilter from 'container/ResourceAttributesFilter'; +import useUrlQuery from 'hooks/useUrlQuery'; import history from 'lib/history'; -import { useMemo } from 'react'; +import { useCallback, useMemo } from 'react'; import { generatePath, useParams } from 'react-router-dom'; import ApDexApplication from './ApDex/ApDexApplication'; @@ -21,34 +22,40 @@ function MetricsApplication(): JSX.Element { const activeKey = useMetricsApplicationTabKey(); + const urlQuery = useUrlQuery(); + + const getRouteUrl = useCallback( + (tab: MetricsApplicationTab): string => { + urlQuery.set('tab', tab); + return `${generatePath(ROUTES.SERVICE_METRICS, { + servicename, + })}?${urlQuery.toString()}`; + }, + [servicename, urlQuery], + ); + const routes = useMemo( () => [ { Component: Overview, name: TAB_KEY_VS_LABEL[MetricsApplicationTab.OVER_METRICS], - route: `${generatePath(ROUTES.SERVICE_METRICS, { - servicename, - })}?tab=${MetricsApplicationTab.OVER_METRICS}`, + route: getRouteUrl(MetricsApplicationTab.OVER_METRICS), key: MetricsApplicationTab.OVER_METRICS, }, { Component: DBCall, name: TAB_KEY_VS_LABEL[MetricsApplicationTab.DB_CALL_METRICS], - route: `${generatePath(ROUTES.SERVICE_METRICS, { - servicename, - })}?tab=${MetricsApplicationTab.DB_CALL_METRICS}`, + route: getRouteUrl(MetricsApplicationTab.DB_CALL_METRICS), key: MetricsApplicationTab.DB_CALL_METRICS, }, { Component: External, name: TAB_KEY_VS_LABEL[MetricsApplicationTab.EXTERNAL_METRICS], - route: `${generatePath(ROUTES.SERVICE_METRICS, { - servicename, - })}?tab=${MetricsApplicationTab.EXTERNAL_METRICS}`, + route: getRouteUrl(MetricsApplicationTab.EXTERNAL_METRICS), key: MetricsApplicationTab.EXTERNAL_METRICS, }, ], - [servicename], + [getRouteUrl], ); return (