globalSelectionLink.tsx 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import React from 'react';
  2. import {Link as RouterLink, withRouter, WithRouterProps} from 'react-router';
  3. import {LocationDescriptor} from 'history';
  4. import * as qs from 'query-string';
  5. import {extractSelectionParameters} from 'app/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 RouterLink>['onClick'];
  23. };
  24. /**
  25. * A modified link used for navigating between organization level pages that
  26. * will keep the global selection values (projects, environments, time) in the
  27. * querystring when navigating if it's present
  28. *
  29. * Falls back to <a> if there is no router present.
  30. */
  31. class GlobalSelectionLink extends React.Component<Props> {
  32. render() {
  33. const {location, to} = this.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. let toWithGlobalQuery;
  40. if (hasGlobalQuery) {
  41. if (typeof to === 'string') {
  42. toWithGlobalQuery = {pathname: to, query};
  43. } else {
  44. toWithGlobalQuery = {...to, query};
  45. }
  46. }
  47. const routerProps = hasGlobalQuery
  48. ? {...this.props, to: toWithGlobalQuery}
  49. : {...this.props, to};
  50. return <RouterLink {...routerProps}>{this.props.children}</RouterLink>;
  51. } else {
  52. let queryStringObject = {};
  53. if (typeof to === 'object' && to.search) {
  54. queryStringObject = qs.parse(to.search);
  55. }
  56. queryStringObject = {...queryStringObject, ...globalQuery};
  57. if (typeof to === 'object' && to.query) {
  58. queryStringObject = {...queryStringObject, ...to.query};
  59. }
  60. const url =
  61. (typeof to === 'string' ? to : to.pathname) +
  62. '?' +
  63. qs.stringify(queryStringObject);
  64. return (
  65. <a {...this.props} href={url}>
  66. {this.props.children}
  67. </a>
  68. );
  69. }
  70. }
  71. }
  72. export default withRouter(GlobalSelectionLink);