mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[APM] Support multiple route paths in useApmParams (#109370)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
60a74e8eaf
commit
6e3af2b524
7 changed files with 103 additions and 21 deletions
|
@ -201,6 +201,21 @@ describe('createRouter', () => {
|
|||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('supports multiple paths', () => {
|
||||
history.push('/service-map?rangeFrom=now-15m&rangeTo=now&maxNumNodes=3');
|
||||
|
||||
const params = router.getParams('/services', '/service-map', history.location);
|
||||
|
||||
expect(params).toEqual({
|
||||
path: {},
|
||||
query: {
|
||||
maxNumNodes: 3,
|
||||
rangeFrom: 'now-15m',
|
||||
rangeTo: 'now',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('matchRoutes', () => {
|
||||
|
|
|
@ -9,6 +9,7 @@ import { isLeft } from 'fp-ts/lib/Either';
|
|||
import { Location } from 'history';
|
||||
import { PathReporter } from 'io-ts/lib/PathReporter';
|
||||
import {
|
||||
MatchedRoute,
|
||||
matchRoutes as matchRoutesConfig,
|
||||
RouteConfig as ReactRouterConfig,
|
||||
} from 'react-router-config';
|
||||
|
@ -49,33 +50,44 @@ export function createRouter<TRoutes extends Route[]>(routes: TRoutes): Router<T
|
|||
}
|
||||
|
||||
const matchRoutes = (...args: any[]) => {
|
||||
let path: string = args[0];
|
||||
let location: Location = args[1];
|
||||
let optional: boolean = args[2];
|
||||
let optional: boolean = false;
|
||||
|
||||
if (args.length === 1) {
|
||||
location = args[0] as Location;
|
||||
path = location.pathname;
|
||||
optional = args[1];
|
||||
if (typeof args[args.length - 1] === 'boolean') {
|
||||
optional = args[args.length - 1];
|
||||
args.pop();
|
||||
}
|
||||
|
||||
const greedy = path.endsWith('/*') || args.length === 1;
|
||||
const location: Location = args[args.length - 1];
|
||||
args.pop();
|
||||
|
||||
if (!path) {
|
||||
path = '/';
|
||||
let paths: string[] = args;
|
||||
|
||||
if (paths.length === 0) {
|
||||
paths = [location.pathname || '/'];
|
||||
}
|
||||
|
||||
const matches = matchRoutesConfig(reactRouterConfigs, location.pathname);
|
||||
let matches: Array<MatchedRoute<{}, ReactRouterConfig>> = [];
|
||||
let matchIndex: number = -1;
|
||||
|
||||
const matchIndex = greedy
|
||||
? matches.length - 1
|
||||
: findLastIndex(matches, (match) => match.route.path === path);
|
||||
for (const path of paths) {
|
||||
const greedy = path.endsWith('/*') || args.length === 0;
|
||||
matches = matchRoutesConfig(reactRouterConfigs, location.pathname);
|
||||
|
||||
matchIndex = greedy
|
||||
? matches.length - 1
|
||||
: findLastIndex(matches, (match) => match.route.path === path);
|
||||
|
||||
if (matchIndex !== -1) {
|
||||
break;
|
||||
}
|
||||
matchIndex = -1;
|
||||
}
|
||||
|
||||
if (matchIndex === -1) {
|
||||
if (optional) {
|
||||
return [];
|
||||
}
|
||||
throw new Error(`No matching route found for ${path}`);
|
||||
throw new Error(`No matching route found for ${paths}`);
|
||||
}
|
||||
|
||||
return matches.slice(0, matchIndex + 1).map((matchedRoute) => {
|
||||
|
|
|
@ -134,6 +134,22 @@ export interface Router<TRoutes extends Route[]> {
|
|||
location: Location,
|
||||
optional: TOptional
|
||||
): TOptional extends true ? TypeOf<TRoutes, TPath> | undefined : TypeOf<TRoutes, TPath>;
|
||||
getParams<T1 extends PathsOf<TRoutes>, T2 extends PathsOf<TRoutes>>(
|
||||
path1: T1,
|
||||
path2: T2,
|
||||
location: Location
|
||||
): TypeOf<TRoutes, T1> | TypeOf<TRoutes, T2>;
|
||||
getParams<T1 extends PathsOf<TRoutes>, T2 extends PathsOf<TRoutes>, T3 extends PathsOf<TRoutes>>(
|
||||
path1: T1,
|
||||
path2: T2,
|
||||
path3: T3,
|
||||
location: Location
|
||||
): TypeOf<TRoutes, T1> | TypeOf<TRoutes, T2> | TypeOf<TRoutes, T3>;
|
||||
getParams<TPath extends PathsOf<TRoutes>, TOptional extends boolean>(
|
||||
path: TPath,
|
||||
location: Location,
|
||||
optional: TOptional
|
||||
): TOptional extends true ? TypeOf<TRoutes, TPath> | undefined : TypeOf<TRoutes, TPath>;
|
||||
link<TPath extends PathsOf<TRoutes>>(
|
||||
path: TPath,
|
||||
...args: TypeAsArgs<TypeOf<TRoutes, TPath, false>>
|
||||
|
|
|
@ -6,12 +6,26 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { Location } from 'history';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { useRouter } from './use_router';
|
||||
|
||||
export function useParams(path: string, optional: boolean = false) {
|
||||
export function useParams(...args: any[]) {
|
||||
const router = useRouter();
|
||||
const location = useLocation();
|
||||
|
||||
return router.getParams(path as never, location, optional);
|
||||
let optional: boolean = false;
|
||||
|
||||
const last: boolean | string | undefined = args[args.length - 1];
|
||||
|
||||
if (typeof last === 'boolean') {
|
||||
optional = last;
|
||||
args.pop();
|
||||
}
|
||||
|
||||
const paths = args as string[];
|
||||
|
||||
const getParamsArgs = [...paths, location, optional] as [never, Location<any>, boolean];
|
||||
|
||||
return router.getParams(...getParamsArgs);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,11 @@ import { ApmRoutes } from '../../../routing/apm_route_config';
|
|||
import { StatsList } from './stats_list';
|
||||
|
||||
export function BackendContents({ nodeData, environment }: ContentsProps) {
|
||||
const { query } = useApmParams('/*');
|
||||
const { query } = useApmParams(
|
||||
'/service-map',
|
||||
'/services/:serviceName/service-map'
|
||||
);
|
||||
|
||||
const apmRouter = useApmRouter();
|
||||
const {
|
||||
urlParams: { start, end },
|
||||
|
|
|
@ -17,9 +17,29 @@ export function useApmParams<TPath extends PathsOf<ApmRoutes>>(
|
|||
path: TPath
|
||||
): TypeOf<ApmRoutes, TPath>;
|
||||
|
||||
export function useApmParams<
|
||||
TPath1 extends PathsOf<ApmRoutes>,
|
||||
TPath2 extends PathsOf<ApmRoutes>
|
||||
>(
|
||||
path1: TPath1,
|
||||
path2: TPath2
|
||||
): TypeOf<ApmRoutes, TPath1> | TypeOf<ApmRoutes, TPath2>;
|
||||
|
||||
export function useApmParams<
|
||||
TPath1 extends PathsOf<ApmRoutes>,
|
||||
TPath2 extends PathsOf<ApmRoutes>,
|
||||
TPath3 extends PathsOf<ApmRoutes>
|
||||
>(
|
||||
path1: TPath1,
|
||||
path2: TPath2,
|
||||
path3: TPath3
|
||||
):
|
||||
| TypeOf<ApmRoutes, TPath1>
|
||||
| TypeOf<ApmRoutes, TPath2>
|
||||
| TypeOf<ApmRoutes, TPath3>;
|
||||
|
||||
export function useApmParams(
|
||||
path: string,
|
||||
optional?: true
|
||||
...args: any[]
|
||||
): TypeOf<ApmRoutes, PathsOf<ApmRoutes>> | undefined {
|
||||
return useParams(path, optional);
|
||||
return useParams(...args);
|
||||
}
|
||||
|
|
1
x-pack/plugins/apm/typings/common.d.ts
vendored
1
x-pack/plugins/apm/typings/common.d.ts
vendored
|
@ -10,6 +10,7 @@ import '../../../typings/rison_node';
|
|||
import '../../infra/types/eui';
|
||||
// EUIBasicTable
|
||||
import '../../reporting/public/components/report_listing';
|
||||
import '../../reporting/server/lib/puid';
|
||||
import './apm_rum_react';
|
||||
|
||||
// Allow unknown properties in an object
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue