Skip to content

Commit

Permalink
[APM] Support multiple route paths in useApmParams (elastic#109370) (e…
Browse files Browse the repository at this point in the history
…lastic#109653)

Co-authored-by: Kibana Machine <[email protected]>

Co-authored-by: Dario Gieselaar <[email protected]>
  • Loading branch information
kibanamachine and dgieselaar authored Aug 23, 2021
1 parent 4981a8b commit bf9413d
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 22 deletions.
15 changes: 15 additions & 0 deletions packages/kbn-typed-react-router-config/src/create_router.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down
44 changes: 28 additions & 16 deletions packages/kbn-typed-react-router-config/src/create_router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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];

if (args.length === 1) {
location = args[0] as Location;
path = location.pathname;
optional = args[1];
let optional: boolean = false;

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();

let paths: string[] = args;

if (!path) {
path = '/';
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) => {
Expand Down
16 changes: 16 additions & 0 deletions packages/kbn-typed-react-router-config/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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>>
Expand Down
18 changes: 16 additions & 2 deletions packages/kbn-typed-react-router-config/src/use_params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down
26 changes: 23 additions & 3 deletions x-pack/plugins/apm/public/hooks/use_apm_params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 change: 1 addition & 0 deletions x-pack/plugins/apm/typings/common.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit bf9413d

Please sign in to comment.