RevisionComparer.jsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import React, { useState, useEffect } from 'react';
  2. import { pagePathUtils } from '@growi/core';
  3. import PropTypes from 'prop-types';
  4. import { CopyToClipboard } from 'react-copy-to-clipboard';
  5. import { useTranslation } from 'react-i18next';
  6. import {
  7. Dropdown, DropdownToggle, DropdownMenu, DropdownItem,
  8. } from 'reactstrap';
  9. import { useCurrentPagePath } from '~/stores/context';
  10. import RevisionDiff from '../PageHistory/RevisionDiff';
  11. const { encodeSpaces } = pagePathUtils;
  12. /* eslint-disable react/prop-types */
  13. const DropdownItemContents = ({ title, contents }) => (
  14. <>
  15. <div className="h6 mt-1 mb-2"><strong>{title}</strong></div>
  16. <div className="card well mb-1 p-2">{contents}</div>
  17. </>
  18. );
  19. /* eslint-enable react/prop-types */
  20. const RevisionComparer = (props) => {
  21. const { t } = useTranslation();
  22. const { data: currentPagePath } = useCurrentPagePath();
  23. const [dropdownOpen, setDropdownOpen] = useState(false);
  24. const {
  25. sourceRevision, targetRevision,
  26. currentPageId,
  27. } = props;
  28. function toggleDropdown() {
  29. setDropdownOpen(!dropdownOpen);
  30. }
  31. const generateURL = (pathName) => {
  32. const { origin } = window.location;
  33. const url = new URL(pathName, origin);
  34. if (sourceRevision != null && targetRevision != null) {
  35. const urlParams = `${sourceRevision._id}...${targetRevision._id}`;
  36. url.searchParams.set('compare', urlParams);
  37. }
  38. return encodeSpaces(decodeURI(url));
  39. };
  40. let isNodiff;
  41. if (sourceRevision == null || targetRevision == null) {
  42. isNodiff = true;
  43. }
  44. else {
  45. isNodiff = sourceRevision._id === targetRevision._id;
  46. }
  47. if (currentPageId == null || currentPagePath == null) {
  48. return <>{ t('not_found_page.page_not_exist')}</>;
  49. }
  50. return (
  51. <div className="revision-compare">
  52. <div className="d-flex">
  53. <h4 className="align-self-center">{ t('page_history.comparing_revisions') }</h4>
  54. <Dropdown
  55. className="grw-copy-dropdown align-self-center ml-auto"
  56. isOpen={dropdownOpen}
  57. toggle={() => toggleDropdown()}
  58. >
  59. <DropdownToggle
  60. caret
  61. className="d-block text-muted bg-transparent btn-copy border-0 py-0"
  62. >
  63. <i className="ti-clipboard"></i>
  64. </DropdownToggle>
  65. <DropdownMenu positionFixed right modifiers={{ preventOverflow: { boundariesElement: undefined } }}>
  66. {/* Page path URL */}
  67. <CopyToClipboard text={generateURL(currentPagePath)}>
  68. <DropdownItem className="px-3">
  69. <DropdownItemContents title={t('copy_to_clipboard.Page URL')} contents={generateURL(currentPagePath)} />
  70. </DropdownItem>
  71. </CopyToClipboard>
  72. {/* Permanent Link URL */}
  73. <CopyToClipboard text={generateURL(currentPageId)}>
  74. <DropdownItem className="px-3">
  75. <DropdownItemContents title={t('copy_to_clipboard.Permanent link')} contents={generateURL(currentPageId)} />
  76. </DropdownItem>
  77. </CopyToClipboard>
  78. <DropdownItem divider className="my-0"></DropdownItem>
  79. </DropdownMenu>
  80. </Dropdown>
  81. </div>
  82. <div className={`revision-compare-container ${isNodiff ? 'nodiff' : ''}`}>
  83. { isNodiff
  84. ? (
  85. <span className="h3 text-muted">{t('No diff')}</span>
  86. )
  87. : (
  88. <RevisionDiff
  89. revisionDiffOpened
  90. previousRevision={sourceRevision}
  91. currentRevision={targetRevision}
  92. />
  93. )
  94. }
  95. </div>
  96. </div>
  97. );
  98. };
  99. RevisionComparer.propTypes = {
  100. sourceRevision: PropTypes.instanceOf(Object),
  101. targetRevision: PropTypes.instanceOf(Object),
  102. currentPageId: PropTypes.string,
  103. };
  104. export default RevisionComparer;