CopyDropdown.jsx 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import { withTranslation } from 'react-i18next';
  4. import {
  5. UncontrolledDropdown, 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. isParamsAppended: true,
  16. };
  17. this.id = (Math.random() * 1000).toString();
  18. this.toggle = this.toggle.bind(this);
  19. this.showToolTip = this.showToolTip.bind(this);
  20. this.generatePagePathWithParams = this.generatePagePathWithParams.bind(this);
  21. this.generatePagePathUrl = this.generatePagePathUrl.bind(this);
  22. this.generatePermalink = this.generatePermalink.bind(this);
  23. this.generateMarkdownLink = this.generateMarkdownLink.bind(this);
  24. }
  25. toggle() {
  26. this.setState({ dropdownOpen: !this.state.dropdownOpen });
  27. }
  28. showToolTip() {
  29. this.setState({ tooltipOpen: true });
  30. setTimeout(() => {
  31. this.setState({ tooltipOpen: false });
  32. }, 1000);
  33. }
  34. get uriParams() {
  35. const { isParamsAppended } = this.state;
  36. if (!isParamsAppended) {
  37. return '';
  38. }
  39. const {
  40. search, hash,
  41. } = window.location;
  42. return `${search}${hash}`;
  43. }
  44. generatePagePathWithParams() {
  45. const { pagePath } = this.props;
  46. return decodeURI(`${pagePath}${this.uriParams}`);
  47. }
  48. generatePagePathUrl() {
  49. const { origin } = window.location;
  50. return `${origin}${this.generatePagePathWithParams()}`;
  51. }
  52. generatePermalink() {
  53. const { pageId } = this.props;
  54. if (pageId == null) {
  55. return null;
  56. }
  57. return decodeURI(`${origin}/${pageId}${this.uriParams}`);
  58. }
  59. generateMarkdownLink() {
  60. const { pagePath } = this.props;
  61. const label = decodeURI(`${pagePath}${this.uriParams}`);
  62. const permalink = this.generatePermalink();
  63. return `[${label}](${permalink})`;
  64. }
  65. DropdownItemContents = ({ title, contents }) => (
  66. <>
  67. <div className="h6 mt-1 mb-2"><strong>{title}</strong></div>
  68. <div className="card well mb-1 p-2">{contents}</div>
  69. </>
  70. );
  71. render() {
  72. const { t, pageId } = this.props;
  73. const { isParamsAppended } = this.state;
  74. const pagePathWithParams = this.generatePagePathWithParams();
  75. const pagePathUrl = this.generatePagePathUrl();
  76. const permalink = this.generatePermalink();
  77. const { id, DropdownItemContents } = this;
  78. const customSwitchForParamsId = `customSwitchForParams_${id}`;
  79. return (
  80. <>
  81. <UncontrolledDropdown id="copyPagePathDropdown" className="grw-copy-dropdown">
  82. <DropdownToggle
  83. caret
  84. className="d-block text-muted bg-transparent btn-copy border-0"
  85. style={this.props.buttonStyle}
  86. >
  87. <i className="ti-clipboard"></i>
  88. </DropdownToggle>
  89. <DropdownMenu>
  90. <div className="d-flex align-items-center justify-content-between">
  91. <DropdownItem header className="px-3">
  92. { t('copy_to_clipboard.Copy to clipboard') }
  93. </DropdownItem>
  94. <div className="px-3 custom-control custom-switch custom-switch-sm">
  95. <input
  96. type="checkbox"
  97. id={customSwitchForParamsId}
  98. className="custom-control-input"
  99. checked={isParamsAppended}
  100. onChange={e => this.setState({ isParamsAppended: !isParamsAppended })}
  101. />
  102. <label className="custom-control-label small" htmlFor={customSwitchForParamsId}>Append params</label>
  103. </div>
  104. </div>
  105. <DropdownItem divider className="my-0"></DropdownItem>
  106. {/* Page path */}
  107. <CopyToClipboard text={pagePathWithParams} onCopy={this.showToolTip}>
  108. <DropdownItem className="px-3">
  109. <DropdownItemContents title={t('copy_to_clipboard.Page path')} contents={pagePathWithParams} />
  110. </DropdownItem>
  111. </CopyToClipboard>
  112. <DropdownItem divider className="my-0"></DropdownItem>
  113. {/* Page path URL */}
  114. <CopyToClipboard text={pagePathUrl} onCopy={this.showToolTip}>
  115. <DropdownItem className="px-3">
  116. <DropdownItemContents title={t('copy_to_clipboard.Page URL')} contents={pagePathUrl} />
  117. </DropdownItem>
  118. </CopyToClipboard>
  119. <DropdownItem divider className="my-0"></DropdownItem>
  120. {/* Parmanent Link */}
  121. { pageId && (
  122. <CopyToClipboard text={permalink} onCopy={this.showToolTip}>
  123. <DropdownItem className="px-3">
  124. <DropdownItemContents title={t('copy_to_clipboard.Parmanent link')} contents={permalink} />
  125. </DropdownItem>
  126. </CopyToClipboard>
  127. )}
  128. <DropdownItem divider className="my-0"></DropdownItem>
  129. {/* Page path + Parmanent Link */}
  130. { pageId && (
  131. <CopyToClipboard text={`${pagePathWithParams}\n${permalink}`} onCopy={this.showToolTip}>
  132. <DropdownItem className="px-3">
  133. <DropdownItemContents title={t('copy_to_clipboard.Page path and parmanent link')} contents={<>{pagePathWithParams}<br />{permalink}</>} />
  134. </DropdownItem>
  135. </CopyToClipboard>
  136. )}
  137. <DropdownItem divider className="my-0"></DropdownItem>
  138. {/* Markdown Link */}
  139. { pageId && (
  140. <CopyToClipboard text={this.generateMarkdownLink()} onCopy={this.showToolTip}>
  141. <DropdownItem className="px-3 text-wrap">
  142. <DropdownItemContents title={t('copy_to_clipboard.Markdown link')} contents={this.generateMarkdownLink()} isContentsWrap />
  143. </DropdownItem>
  144. </CopyToClipboard>
  145. )}
  146. </DropdownMenu>
  147. </UncontrolledDropdown>
  148. <Tooltip placement="bottom" isOpen={this.state.tooltipOpen} target="copyPagePathDropdown" fade={false}>
  149. copied!
  150. </Tooltip>
  151. </>
  152. );
  153. }
  154. }
  155. CopyDropdown.propTypes = {
  156. t: PropTypes.func.isRequired, // i18next
  157. pagePath: PropTypes.string.isRequired,
  158. pageId: PropTypes.string,
  159. buttonStyle: PropTypes.object,
  160. };
  161. export default withTranslation()(CopyDropdown);