RevisionDiff.tsx 2.4 KB

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