PageRevisionList.jsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import { withTranslation } from 'react-i18next';
  4. import PageHistroyContainer from '../../services/PageHistoryContainer';
  5. import Revision from './Revision';
  6. import RevisionSelector from '../RevisionComparer/RevisionSelector';
  7. class PageRevisionList extends React.Component {
  8. constructor(props) {
  9. super(props);
  10. this.state = {
  11. isCompactNodiffRevisions: true,
  12. };
  13. this.cbCompactizeChangeHandler = this.cbCompactizeChangeHandler.bind(this);
  14. }
  15. cbCompactizeChangeHandler() {
  16. this.setState({ isCompactNodiffRevisions: !this.state.isCompactNodiffRevisions });
  17. }
  18. /**
  19. * render a row (Revision component and RevisionDiff component)
  20. * @param {Revison} revision
  21. * @param {Revision} previousRevision
  22. * @param {boolean} hasDiff whether revision has difference to previousRevision
  23. * @param {boolean} isContiguousNodiff true if the current 'hasDiff' and one of previous row is both false
  24. */
  25. renderRow(revision, previousRevision, hasDiff, isContiguousNodiff) {
  26. const { latestRevision } = this.props.pageHistoryContainer.state;
  27. const revisionId = revision._id;
  28. const revisionDiffOpened = this.props.diffOpened[revisionId] || false;
  29. const classNames = ['revision-history-outer', 'row', 'no-gutters'];
  30. if (isContiguousNodiff) {
  31. classNames.push('revision-history-outer-contiguous-nodiff');
  32. }
  33. return (
  34. <div className={classNames.join(' ')} key={`revision-history-${revisionId}`}>
  35. <div className="col-8 d-flex" key={`revision-history-top-${revisionId}`}>
  36. <Revision
  37. t={this.props.t}
  38. revision={revision}
  39. isLatestRevision={revision === latestRevision}
  40. revisionDiffOpened={revisionDiffOpened}
  41. hasDiff={hasDiff}
  42. isCompactNodiffRevisions={this.state.isCompactNodiffRevisions}
  43. key={`revision-history-rev-${revisionId}`}
  44. />
  45. {hasDiff && (
  46. <div className="dropdown mt-auto mb-3 ml-5">
  47. <button
  48. className="btn btn-primary dropdown-toggle"
  49. type="button"
  50. id="dropdownMenuButton"
  51. data-toggle="dropdown"
  52. aria-haspopup="true"
  53. aria-expanded="true"
  54. >
  55. <span className="float-left">
  56. hoge
  57. </span>
  58. </button>
  59. <div className="dropdown-menu" aria-labelledby="dropdownMenuButton">
  60. <button className="dropdown-item" type="button" onClick={() => { console.log('Readonly') }}>
  61. button
  62. </button>
  63. </div>
  64. </div>
  65. )}
  66. </div>
  67. <div className="col-4 align-self-center">
  68. <RevisionSelector
  69. revision={revision}
  70. hasDiff={hasDiff}
  71. key={`revision-compare-target-selector-${revisionId}`}
  72. />
  73. </div>
  74. </div>
  75. );
  76. }
  77. render() {
  78. const { t, pageHistoryContainer } = this.props;
  79. const revisions = this.props.revisions;
  80. const revisionCount = this.props.revisions.length;
  81. let hasDiffPrev;
  82. const revisionList = this.props.revisions.map((revision, idx) => {
  83. // Returns null because the last revision is for the bottom diff display
  84. if (idx === pageHistoryContainer.state.pagingLimit) {
  85. return null;
  86. }
  87. let previousRevision;
  88. if (idx + 1 < revisionCount) {
  89. previousRevision = revisions[idx + 1];
  90. }
  91. else {
  92. previousRevision = revision; // if it is the first revision, show full text as diff text
  93. }
  94. const hasDiff = revision.hasDiffToPrev !== false; // set 'true' if undefined for backward compatibility
  95. const isContiguousNodiff = !hasDiff && !hasDiffPrev;
  96. hasDiffPrev = hasDiff;
  97. return this.renderRow(revision, previousRevision, hasDiff, isContiguousNodiff);
  98. });
  99. const classNames = ['revision-history-list'];
  100. if (this.state.isCompactNodiffRevisions) {
  101. classNames.push('revision-history-list-compact');
  102. }
  103. return (
  104. <React.Fragment>
  105. <div className="d-flex">
  106. <h3>{t('page_history.revision_list')}</h3>
  107. <div className="custom-control custom-checkbox custom-checkbox-info ml-auto">
  108. <input
  109. type="checkbox"
  110. id="cbCompactize"
  111. className="custom-control-input"
  112. checked={this.state.isCompactNodiffRevisions}
  113. onChange={this.cbCompactizeChangeHandler}
  114. />
  115. <label className="custom-control-label" htmlFor="cbCompactize">{ t('Shrink versions that have no diffs') }</label>
  116. </div>
  117. </div>
  118. <hr />
  119. <div className={classNames.join(' ')}>
  120. <div className="revision-history-list-container">
  121. <div className="revision-history-list-content-header sticky-top bg-white">
  122. <div className="row no-gutters">
  123. <div className="col-8">{ t('page_history.revision') }</div>
  124. <div className="col-2 text-center">{ t('page_history.comparing_source') }</div>
  125. <div className="col-2 text-center">{ t('page_history.comparing_target') }</div>
  126. </div>
  127. </div>
  128. <div className="revision-history-list-content-body">
  129. {revisionList}
  130. </div>
  131. </div>
  132. </div>
  133. </React.Fragment>
  134. );
  135. }
  136. }
  137. PageRevisionList.propTypes = {
  138. t: PropTypes.func.isRequired, // i18next
  139. pageHistoryContainer: PropTypes.instanceOf(PageHistroyContainer).isRequired,
  140. revisions: PropTypes.array,
  141. diffOpened: PropTypes.object,
  142. };
  143. export default withTranslation()(PageRevisionList);