RevisionDiff.tsx 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import React from 'react';
  2. import { IRevisionHasPageId, pathUtils } from '@growi/core';
  3. import { createPatch } from 'diff';
  4. import { html, Diff2HtmlConfig } from 'diff2html';
  5. import { useTranslation } from 'next-i18next';
  6. import Link from 'next/link';
  7. import urljoin from 'url-join';
  8. import UserDate from '../User/UserDate';
  9. import styles from './RevisionDiff.module.scss';
  10. import 'diff2html/bundles/css/diff2html.min.css';
  11. type RevisioinDiffProps = {
  12. currentRevision: IRevisionHasPageId,
  13. previousRevision: IRevisionHasPageId,
  14. revisionDiffOpened: boolean,
  15. currentPageId: string,
  16. currentPagePath: string,
  17. onClose: () => void,
  18. }
  19. export const RevisionDiff = (props: RevisioinDiffProps): JSX.Element => {
  20. const { t } = useTranslation();
  21. const {
  22. currentRevision, previousRevision, revisionDiffOpened, currentPageId, currentPagePath, onClose,
  23. } = props;
  24. const { returnPathForURL } = pathUtils;
  25. const previousText = (currentRevision._id === previousRevision._id) ? '' : previousRevision.body;
  26. const patch = createPatch(
  27. currentRevision.pageId, // currentRevision.path is DEPRECATED
  28. previousText,
  29. currentRevision.body,
  30. );
  31. const option: Diff2HtmlConfig = {
  32. outputFormat: 'side-by-side',
  33. drawFileList: false,
  34. };
  35. const diffViewHTML = (currentRevision.body && previousRevision.body && revisionDiffOpened) ? html(patch, option) : '';
  36. const diffView = { __html: diffViewHTML };
  37. return (
  38. <div className={`${styles['revision-diff-container']}`}>
  39. <div className='comparison-header'>
  40. <div className="container pt-1 pr-0">
  41. <div className="row">
  42. <div className="col comparison-source-wrapper pt-1 px-0">
  43. <span className="comparison-source pr-3">{t('page_history.comparing_source')}</span><UserDate dateTime={previousRevision.createdAt} />
  44. <Link href={urljoin(returnPathForURL(currentPagePath, currentPageId), `?revisionId=${previousRevision._id}`)}>
  45. <a className="ml-3" onClick={onClose}>
  46. <i className="icon-login"></i>
  47. </a>
  48. </Link>
  49. </div>
  50. <div className="col comparison-target-wrapper pt-1">
  51. <span className="comparison-target pr-3">{t('page_history.comparing_target')}</span><UserDate dateTime={currentRevision.createdAt} />
  52. <Link href={urljoin(returnPathForURL(currentPagePath, currentPageId), `?revisionId=${currentRevision._id}`)}>
  53. <a className="ml-3" onClick={onClose}>
  54. <i className="icon-login"></i>
  55. </a>
  56. </Link>
  57. </div>
  58. </div>
  59. </div>
  60. </div>
  61. <div className="revision-history-diff pb-1" dangerouslySetInnerHTML={diffView} />
  62. </div>
  63. );
  64. };