globalSelectionLink.tsx 2.1 KB

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