12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- import {Location} from 'history';
- import findLastIndex from 'lodash/findLastIndex';
- import replaceRouterParams from 'sentry/utils/replaceRouterParams';
- import {RouteWithName} from 'sentry/views/settings/components/settingsBreadcrumb/types';
- type Options = {
- // parameters to replace any route string parameters (e.g. if route is `:orgId`,
- // params should have `{orgId: slug}`
- params: {[key: string]: string | undefined};
- routes: RouteWithName[];
- location?: Location;
- /**
- * The number of routes to to pop off of `routes
- * Must be < 0
- *
- * There's no ts type for negative numbers so we are arbitrarily specifying -1-9
- */
- stepBack?: -1 | -2 | -3 | -4 | -5 | -6 | -7 | -8 | -9;
- };
- /**
- * Given a route object or a string and a list of routes + params from router, this will attempt to recreate a location string while replacing url params.
- * Can additionally specify the number of routes to move back
- *
- * See tests for examples
- */
- export default function recreateRoute(
- to: string | RouteWithName,
- options: Options
- ): string {
- const {routes, params, location, stepBack} = options;
- const paths = routes.map(({path}) => path || '');
- let lastRootIndex: number;
- let routeIndex: number | undefined;
- // TODO(ts): typescript things
- if (typeof to !== 'string') {
- routeIndex = routes.indexOf(to) + 1;
- lastRootIndex = findLastIndex(paths.slice(0, routeIndex), path => path[0] === '/');
- } else {
- lastRootIndex = findLastIndex(paths, path => path[0] === '/');
- }
- let baseRoute = paths.slice(lastRootIndex, routeIndex);
- if (typeof stepBack !== 'undefined') {
- baseRoute = baseRoute.slice(0, stepBack);
- }
- const search = location?.search ?? '';
- const hash = location?.hash ?? '';
- const fullRoute = `${baseRoute.join('')}${
- typeof to !== 'string' ? '' : to
- }${search}${hash}`;
- return replaceRouterParams(fullRoute, params);
- }
|