fix: do not route back to overview tab when changing the resource attributes (#5058)

* fix: do not route back to overview tab when changing the resource attributes

* fix: retain the resource attributes in query params on tab change

* feat: added jest test case for the same

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
This commit is contained in:
Vikrant Gupta 2024-05-27 15:23:06 +05:30 committed by GitHub
parent ab444af8e6
commit 83d0ddeec0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 58 additions and 23 deletions

View File

@ -7,7 +7,7 @@ export const ServicesTablePage = Loadable(
export const ServiceMetricsPage = Loadable(
() =>
import(
/* webpackChunkName: "ServiceMetricsPage" */ 'pages/MetricsApplication'
/* webpackChunkName: "ServiceMetricsPage" */ 'pages/MetricsApplication/MetricsApplication'
),
);

View File

@ -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<IResourceAttribute[]>(
getResourceAttributeQueriesFromURL(),
);
const urlQuery = useUrlQuery();
const [optionsData, setOptionsData] = useState<OptionsData>({
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, {

View File

@ -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 => (
<Router history={history}>
<ResourceProvider>{children}</ResourceProvider>
</Router>
);
const { result } = renderHook(() => useResourceAttribute(), { wrapper });
act(() => {
result.current.handleEnvironmentChange(['production']);
});
await waitFor(() =>
expect(history.location.search).toContain('tab=overview'),
);
});
});

View File

@ -176,8 +176,6 @@ export const GetTagValues = async (tagKey: string): Promise<IOption[]> => {
export const createQuery = (
selectedItems: Array<string | string[]> = [],
): 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<string | string[]> = [],
// eslint-disable-next-line sonarjs/no-identical-functions
): IResourceAttribute | null => {
if (selectedItems.length === 3) {
return {

View File

@ -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 (