chore: fix regex issue in route tab (#8440)

This commit is contained in:
Amlan Kumar Nandy 2025-07-07 16:55:23 +07:00 committed by GitHub
parent 273452352d
commit 8b62c8dced
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 69 additions and 56 deletions

View File

@ -1,5 +1,10 @@
import { Tabs, TabsProps } from 'antd'; import { Tabs, TabsProps } from 'antd';
import { useLocation, useParams } from 'react-router-dom'; import {
generatePath,
matchPath,
useLocation,
useParams,
} from 'react-router-dom';
import { RouteTabProps } from './types'; import { RouteTabProps } from './types';
@ -17,20 +22,13 @@ function RouteTab({
const params = useParams<Params>(); const params = useParams<Params>();
const location = useLocation(); const location = useLocation();
// Replace dynamic parameters in routes
const routesWithParams = routes.map((route) => ({
...route,
route: route.route.replace(
/:(\w+)/g,
(match, param) => params[param] || match,
),
}));
// Find the matching route for the current pathname // Find the matching route for the current pathname
const currentRoute = routesWithParams.find((route) => { const currentRoute = routes.find((route) => {
const routePattern = route.route.replace(/:(\w+)/g, '([^/]+)'); const routePath = route.route.split('?')[0];
const regex = new RegExp(`^${routePattern}$`); return matchPath(location.pathname, {
return regex.test(location.pathname); path: routePath,
exact: true,
});
}); });
const onChange = (activeRoute: string): void => { const onChange = (activeRoute: string): void => {
@ -38,14 +36,15 @@ function RouteTab({
onChangeHandler(activeRoute); onChangeHandler(activeRoute);
} }
const selectedRoute = routesWithParams.find((e) => e.key === activeRoute); const selectedRoute = routes.find((e) => e.key === activeRoute);
if (selectedRoute) { if (selectedRoute) {
history.push(selectedRoute.route); const resolvedRoute = generatePath(selectedRoute.route, params);
history.push(resolvedRoute);
} }
}; };
const items = routesWithParams.map(({ Component, name, route, key }) => ({ const items = routes.map(({ Component, name, route, key }) => ({
label: name, label: name,
key, key,
tabKey: route, tabKey: route,

View File

@ -46,4 +46,5 @@ export enum QueryParams {
msgSystem = 'msgSystem', msgSystem = 'msgSystem',
destination = 'destination', destination = 'destination',
kindString = 'kindString', kindString = 'kindString',
tab = 'tab',
} }

View File

@ -1,3 +1,26 @@
.service-route-tab { .service-route-tab {
margin-bottom: 64px; margin-bottom: 64px;
.ant-tabs-nav {
&::before {
border-bottom: 1px solid var(--bg-slate-400);
}
.ant-tabs-nav-wrap {
.ant-tabs-nav-list {
.ant-tabs-ink-bar {
background-color: var(--bg-robin-500) !important;
}
.ant-tabs-tab {
font-size: 13px;
font-family: 'Inter';
color: var(--text-vanilla-100);
line-height: 20px;
letter-spacing: -0.07px;
gap: 10px;
}
.ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn {
color: var(--bg-robin-500);
}
}
}
}
} }

View File

@ -1,15 +1,14 @@
import './MetricsApplication.styles.scss'; import './MetricsApplication.styles.scss';
import RouteTab from 'components/RouteTab'; import { Tabs, TabsProps } from 'antd/lib';
import ROUTES from 'constants/routes'; import { QueryParams } from 'constants/query';
import DBCall from 'container/MetricsApplication/Tabs/DBCall'; import DBCall from 'container/MetricsApplication/Tabs/DBCall';
import External from 'container/MetricsApplication/Tabs/External'; import External from 'container/MetricsApplication/Tabs/External';
import Overview from 'container/MetricsApplication/Tabs/Overview'; import Overview from 'container/MetricsApplication/Tabs/Overview';
import ResourceAttributesFilter from 'container/ResourceAttributesFilter'; import ResourceAttributesFilter from 'container/ResourceAttributesFilter';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
import useUrlQuery from 'hooks/useUrlQuery'; import useUrlQuery from 'hooks/useUrlQuery';
import history from 'lib/history'; import { useParams } from 'react-router-dom';
import { useCallback, useMemo } from 'react';
import { generatePath, useParams } from 'react-router-dom';
import ApDexApplication from './ApDex/ApDexApplication'; import ApDexApplication from './ApDex/ApDexApplication';
import { MetricsApplicationTab, TAB_KEY_VS_LABEL } from './types'; import { MetricsApplicationTab, TAB_KEY_VS_LABEL } from './types';
@ -25,50 +24,41 @@ function MetricsApplication(): JSX.Element {
const activeKey = useMetricsApplicationTabKey(); const activeKey = useMetricsApplicationTabKey();
const urlQuery = useUrlQuery(); const urlQuery = useUrlQuery();
const { safeNavigate } = useSafeNavigate();
const getRouteUrl = useCallback( const items: TabsProps['items'] = [
(tab: MetricsApplicationTab): string => { {
urlQuery.set('tab', tab); label: TAB_KEY_VS_LABEL[MetricsApplicationTab.OVER_METRICS],
return `${generatePath(ROUTES.SERVICE_METRICS, { key: MetricsApplicationTab.OVER_METRICS,
servicename, children: <Overview />,
})}?${urlQuery.toString()}`;
}, },
[servicename, urlQuery], {
); label: TAB_KEY_VS_LABEL[MetricsApplicationTab.DB_CALL_METRICS],
key: MetricsApplicationTab.DB_CALL_METRICS,
children: <DBCall />,
},
{
label: TAB_KEY_VS_LABEL[MetricsApplicationTab.EXTERNAL_METRICS],
key: MetricsApplicationTab.EXTERNAL_METRICS,
children: <External />,
},
];
const routes = useMemo( const onTabChange = (tab: string): void => {
() => [ urlQuery.set(QueryParams.tab, tab);
{ safeNavigate(`/services/${servicename}?${urlQuery.toString()}`);
Component: Overview, };
name: TAB_KEY_VS_LABEL[MetricsApplicationTab.OVER_METRICS],
route: getRouteUrl(MetricsApplicationTab.OVER_METRICS),
key: MetricsApplicationTab.OVER_METRICS,
},
{
Component: DBCall,
name: TAB_KEY_VS_LABEL[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: getRouteUrl(MetricsApplicationTab.EXTERNAL_METRICS),
key: MetricsApplicationTab.EXTERNAL_METRICS,
},
],
[getRouteUrl],
);
return ( return (
<div className="metrics-application-container"> <div className="metrics-application-container">
<ResourceAttributesFilter /> <ResourceAttributesFilter />
<ApDexApplication /> <ApDexApplication />
<RouteTab <Tabs
routes={routes} items={items}
history={history}
activeKey={activeKey} activeKey={activeKey}
className="service-route-tab" className="service-route-tab"
destroyInactiveTabPane
onChange={onTabChange}
/> />
</div> </div>
); );