globalSelectionLink.tsx 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import * as React from 'react';
  2. import {withRouter, WithRouterProps} from 'react-router';
  3. import {LocationDescriptor} from 'history';
  4. import * as qs from 'query-string';
  5. import Link from 'app/components/links/link';
  6. import {extractSelectionParameters} from 'app/components/organizations/globalSelectionHeader/utils';
  7. type Props = WithRouterProps & {
  8. /**
  9. * Location that is being linked to
  10. */
  11. to: LocationDescriptor;
  12. /**
  13. * Styles applied to the component's root
  14. */
  15. className?: string;
  16. /**
  17. * Inline styles
  18. */
  19. style?: React.CSSProperties;
  20. /**
  21. * Click event (not for navigation)
  22. */
  23. onClick?: React.ComponentProps<typeof Link>['onClick'];
  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. class GlobalSelectionLink extends React.Component<Props> {
  33. render() {
  34. const {location, to} = this.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. ? typeof to === 'string'
  42. ? {pathname: to, query}
  43. : {...to, query}
  44. : {};
  45. const routerProps = hasGlobalQuery
  46. ? {...this.props, to: toWithGlobalQuery}
  47. : {...this.props, to};
  48. return <Link {...routerProps}>{this.props.children}</Link>;
  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 url =
  59. (typeof to === 'string' ? to : to.pathname) + '?' + qs.stringify(queryStringObject);
  60. return (
  61. <a {...this.props} href={url}>
  62. {this.props.children}
  63. </a>
  64. );
  65. }
  66. }
  67. export default withRouter(GlobalSelectionLink);