globalSelectionLink.tsx 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // eslint-disable-next-line no-restricted-imports
  2. import {withRouter, WithRouterProps} from 'react-router';
  3. import {LocationDescriptor} from 'history';
  4. import * as qs from 'query-string';
  5. import Link, {LinkProps} from 'sentry/components/links/link';
  6. import {extractSelectionParameters} from 'sentry/components/organizations/pageFilters/utils';
  7. interface Props extends WithRouterProps {
  8. /**
  9. * Location that is being linked to
  10. */
  11. to: LocationDescriptor;
  12. children?: React.ReactNode;
  13. /**
  14. * Styles applied to the component's root
  15. */
  16. className?: string;
  17. /**
  18. * Click event (not for navigation)
  19. */
  20. onClick?: LinkProps['onClick'];
  21. /**
  22. * Inline styles
  23. */
  24. style?: React.CSSProperties;
  25. }
  26. /**
  27. * A modified link used for navigating between organization level pages that
  28. * will keep the global selection values (projects, environments, time) in the
  29. * querystring when navigating if it's present
  30. *
  31. * Falls back to <a> if there is no router present.
  32. */
  33. function GlobalSelectionLink(props: Props) {
  34. const {location, to} = props;
  35. const globalQuery = extractSelectionParameters(location?.query);
  36. const hasGlobalQuery = Object.keys(globalQuery).length > 0;
  37. const query =
  38. typeof to === 'object' && to.query ? {...globalQuery, ...to.query} : globalQuery;
  39. if (location) {
  40. const toWithGlobalQuery: LocationDescriptor = !hasGlobalQuery
  41. ? {}
  42. : typeof to === 'string'
  43. ? {pathname: to, query}
  44. : {...to, query};
  45. const routerProps = hasGlobalQuery
  46. ? {...props, to: toWithGlobalQuery}
  47. : {...props, to};
  48. return <Link {...routerProps} />;
  49. }
  50. let queryStringObject = {};
  51. if (typeof to === 'object' && to.search) {
  52. queryStringObject = qs.parse(to.search);
  53. }
  54. queryStringObject = {...queryStringObject, ...globalQuery};
  55. if (typeof to === 'object' && to.query) {
  56. queryStringObject = {...queryStringObject, ...to.query};
  57. }
  58. const queryString = qs.stringify(queryStringObject);
  59. const url =
  60. (typeof to === 'string' ? to : to.pathname) + (queryString ? `?${queryString}` : '');
  61. return <a {...props} href={url} />;
  62. }
  63. export default withRouter(GlobalSelectionLink);