CopyDropdown.jsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import { withTranslation } from 'react-i18next';
  4. import {
  5. Dropdown, DropdownToggle, DropdownMenu, DropdownItem,
  6. Tooltip,
  7. } from 'reactstrap';
  8. import { CopyToClipboard } from 'react-copy-to-clipboard';
  9. class CopyDropdown extends React.Component {
  10. constructor(props) {
  11. super(props);
  12. this.state = {
  13. dropdownOpen: false,
  14. tooltipOpen: false,
  15. };
  16. this.toggle = this.toggle.bind(this);
  17. this.showToolTip = this.showToolTip.bind(this);
  18. this.generatePagePathWithParams = this.generatePagePathWithParams.bind(this);
  19. this.generatePagePathUrl = this.generatePagePathUrl.bind(this);
  20. this.generatePermalink = this.generatePermalink.bind(this);
  21. this.generateMarkdownLink = this.generateMarkdownLink.bind(this);
  22. }
  23. toggle() {
  24. this.setState({ dropdownOpen: !this.state.dropdownOpen });
  25. }
  26. showToolTip() {
  27. this.setState({ tooltipOpen: true });
  28. setTimeout(() => {
  29. this.setState({ tooltipOpen: false });
  30. }, 1000);
  31. }
  32. generatePagePathWithParams() {
  33. const { pagePath } = this.props;
  34. const {
  35. search, hash,
  36. } = window.location;
  37. return decodeURI(`${pagePath}${search}${hash}`);
  38. }
  39. generatePagePathUrl() {
  40. const { origin } = window.location;
  41. return `${origin}${this.generatePagePathWithParams()}`;
  42. }
  43. generatePermalink() {
  44. const { pageId } = this.props;
  45. const { location } = window;
  46. if (pageId == null) {
  47. return null;
  48. }
  49. const {
  50. origin, search, hash,
  51. } = location;
  52. return decodeURI(`${origin}/${pageId}${search}${hash}`);
  53. }
  54. generateMarkdownLink() {
  55. const { pagePath } = this.props;
  56. const {
  57. search, hash,
  58. } = window.location;
  59. const label = `${pagePath}${search}${hash}`;
  60. const permalink = this.generatePermalink();
  61. return decodeURI(`[${label}](${permalink})`);
  62. }
  63. DropdownItemContents = ({ title, contents }) => (
  64. <>
  65. <div className="h6 mt-1 mb-2"><strong>{title}</strong></div>
  66. <div className="card well mb-1 p-2">{contents}</div>
  67. </>
  68. );
  69. render() {
  70. const { t, pageId } = this.props;
  71. const pagePathWithParams = this.generatePagePathWithParams();
  72. const pagePathUrl = this.generatePagePathUrl();
  73. const permalink = this.generatePermalink();
  74. const { DropdownItemContents } = this;
  75. return (
  76. <>
  77. <Dropdown id="copyPagePathDropdown" className="grw-copy-dropdown" isOpen={this.state.dropdownOpen} toggle={this.toggle}>
  78. <DropdownToggle
  79. caret
  80. className="d-block text-muted bg-transparent btn-copy border-0"
  81. style={this.props.buttonStyle}
  82. >
  83. <i className="ti-clipboard"></i>
  84. </DropdownToggle>
  85. <DropdownMenu>
  86. <DropdownItem header className="px-3">{ t('copy_to_clipboard.Copy to clipboard') }</DropdownItem>
  87. <DropdownItem divider className="my-0"></DropdownItem>
  88. {/* Page path */}
  89. <CopyToClipboard text={pagePathWithParams} onCopy={this.showToolTip}>
  90. <DropdownItem className="px-3">
  91. <DropdownItemContents title={t('copy_to_clipboard.Page path')} contents={pagePathWithParams} />
  92. </DropdownItem>
  93. </CopyToClipboard>
  94. <DropdownItem divider className="my-0"></DropdownItem>
  95. {/* Page path URL */}
  96. <CopyToClipboard text={pagePathUrl} onCopy={this.showToolTip}>
  97. <DropdownItem className="px-3">
  98. <DropdownItemContents title={t('copy_to_clipboard.Page URL')} contents={pagePathUrl} />
  99. </DropdownItem>
  100. </CopyToClipboard>
  101. <DropdownItem divider className="my-0"></DropdownItem>
  102. {/* Parmanent Link */}
  103. { pageId && (
  104. <CopyToClipboard text={permalink} onCopy={this.showToolTip}>
  105. <DropdownItem className="px-3">
  106. <DropdownItemContents title={t('copy_to_clipboard.Parmanent link')} contents={permalink} />
  107. </DropdownItem>
  108. </CopyToClipboard>
  109. )}
  110. <DropdownItem divider className="my-0"></DropdownItem>
  111. {/* Page path + Parmanent Link */}
  112. { pageId && (
  113. <CopyToClipboard text={`${pagePathWithParams}\n${permalink}`} onCopy={this.showToolTip}>
  114. <DropdownItem className="px-3">
  115. <DropdownItemContents title={t('copy_to_clipboard.Page path and parmanent link')} contents={<>{pagePathWithParams}<br />{permalink}</>} />
  116. </DropdownItem>
  117. </CopyToClipboard>
  118. )}
  119. <DropdownItem divider className="my-0"></DropdownItem>
  120. {/* Markdown Link */}
  121. { pageId && (
  122. <CopyToClipboard text={this.generateMarkdownLink()} onCopy={this.showToolTip}>
  123. <DropdownItem className="px-3 text-wrap">
  124. <DropdownItemContents title={t('copy_to_clipboard.Markdown link')} contents={this.generateMarkdownLink()} isContentsWrap />
  125. </DropdownItem>
  126. </CopyToClipboard>
  127. )}
  128. </DropdownMenu>
  129. </Dropdown>
  130. <Tooltip placement="bottom" isOpen={this.state.tooltipOpen} target="copyPagePathDropdown" fade={false}>
  131. copied!
  132. </Tooltip>
  133. </>
  134. );
  135. }
  136. }
  137. CopyDropdown.propTypes = {
  138. t: PropTypes.func.isRequired, // i18next
  139. pagePath: PropTypes.string.isRequired,
  140. pageId: PropTypes.string,
  141. buttonStyle: PropTypes.object,
  142. };
  143. export default withTranslation()(CopyDropdown);