globalSelectionLink.tsx 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import {withRouter, WithRouterProps} from 'react-router';
  2. import {LocationDescriptor} from 'history';
  3. import * as qs from 'query-string';
  4. import Link from 'sentry/components/links/link';
  5. import {extractSelectionParameters} from 'sentry/components/organizations/globalSelectionHeader/utils';
  6. type Props = WithRouterProps & {
  7. /**
  8. * Location that is being linked to
  9. */
  10. to: LocationDescriptor;
  11. /**
  12. * Styles applied to the component's root
  13. */
  14. className?: string;
  15. /**
  16. * Inline styles
  17. */
  18. style?: React.CSSProperties;
  19. /**
  20. * Click event (not for navigation)
  21. */
  22. onClick?: React.ComponentProps<typeof Link>['onClick'];
  23. children?: React.ReactNode;
  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 url =
  58. (typeof to === 'string' ? to : to.pathname) + '?' + qs.stringify(queryStringObject);
  59. return <a {...props} href={url} />;
  60. }
  61. export default withRouter(GlobalSelectionLink);