cloud-link.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import React from 'react';
  2. import { connect } from 'react-redux';
  3. import filterInvalidDOMProps from 'filter-invalid-dom-props';
  4. import CloudFeature from './cloud-feature';
  5. /**
  6. * CloudLink provides an anchor that allows to set a target
  7. * that is comprised of Weave Cloud related pieces.
  8. *
  9. * We support here relative links with a leading `/` that rewrite
  10. * the browser url as well as cloud-related placeholders (:instanceId).
  11. *
  12. * If no `url` is given, only the children is rendered (no anchor).
  13. *
  14. * If you want to render the content even if not on the cloud, set
  15. * the `alwaysShow` property. A location redirect will be made for
  16. * clicks instead.
  17. */
  18. const CloudLink = ({ alwaysShow, ...props }) => (
  19. <CloudFeature alwaysShow={alwaysShow}>
  20. <LinkWrapper {...props} />
  21. </CloudFeature>
  22. );
  23. class LinkWrapper extends React.Component {
  24. constructor(props, context) {
  25. super(props, context);
  26. this.handleClick = this.handleClick.bind(this);
  27. this.buildHref = this.buildHref.bind(this);
  28. }
  29. handleClick(ev, href) {
  30. ev.preventDefault();
  31. if (!href) return;
  32. const { router, onClick } = this.props;
  33. if (onClick) {
  34. onClick();
  35. }
  36. if (router && href[0] === '/') {
  37. router.push(href);
  38. } else {
  39. window.location.href = href;
  40. }
  41. }
  42. buildHref(url) {
  43. const { params } = this.props;
  44. if (!url || !params || !params.instanceId) return url;
  45. return url.replace(/:instanceid/gi, encodeURIComponent(params.instanceId));
  46. }
  47. render() {
  48. const { url, children, ...props } = this.props;
  49. if (!url) {
  50. return React.isValidElement(children) ? children : (<span>{children}</span>);
  51. }
  52. const href = this.buildHref(url);
  53. return (
  54. <a {...filterInvalidDOMProps(props)} href={href} onClick={e => this.handleClick(e, href)}>
  55. {children}
  56. </a>
  57. );
  58. }
  59. }
  60. export default connect()(CloudLink);