globalSelectionLink.tsx 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import {LocationDescriptor} from 'history';
  2. import * as qs from 'query-string';
  3. import Link, {LinkProps} from 'sentry/components/links/link';
  4. import {extractSelectionParameters} from 'sentry/components/organizations/pageFilters/utils';
  5. import {useLocation} from 'sentry/utils/useLocation';
  6. interface Props {
  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 {to} = props;
  34. const location = useLocation();
  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 GlobalSelectionLink;