jam411 3 лет назад
Родитель
Сommit
b27090182d

+ 3 - 3
packages/app/src/components/PageHistory.tsx

@@ -6,7 +6,7 @@ import { useCurrentPageId } from '~/stores/context';
 import { useSWRxPageRevisions } from '~/stores/page';
 import loggerFactory from '~/utils/logger';
 
-import PageRevisionTable from './PageHistory/PageRevisionTable';
+import { PageRevisionTable } from './PageHistory/PageRevisionTable';
 import PaginationWrapper from './PaginationWrapper';
 import { RevisionComparer } from './RevisionComparer/RevisionComparer';
 
@@ -57,8 +57,8 @@ export const PageHistory = (): JSX.Element => {
       <PageRevisionTable
         revisions={revisionsData.revisions}
         pagingLimit={pagingLimit}
-        sourceRevision={sourceRevision}
-        targetRevision={targetRevision}
+        sourceRevision={sourceRevision as IRevisionHasPageId}
+        targetRevision={targetRevision as IRevisionHasPageId}
         onChangeSourceInvoked={setSourceRevision}
         onChangeTargetInvoked={setTargetRevision}
       />

+ 5 - 0
packages/app/src/components/PageHistory/PageRevisionTable.module.scss

@@ -0,0 +1,5 @@
+.revision-history-table :global {
+  tbody {
+    max-height: 250px;
+  }
+}

+ 62 - 86
packages/app/src/components/PageHistory/PageRevisionTable.jsx → packages/app/src/components/PageHistory/PageRevisionTable.tsx

@@ -1,23 +1,35 @@
 import React from 'react';
 
+import { IRevisionHasId } from '@growi/core';
 import { useTranslation } from 'next-i18next';
-import PropTypes from 'prop-types';
-
-import Revision from './Revision';
-
-class PageRevisionTable extends React.Component {
-
-  /**
-   * render a row (Revision component and RevisionDiff component)
-   * @param {Revison} revision
-   * @param {Revision} previousRevision
-   * @param {boolean} hasDiff whether revision has difference to previousRevision
-   * @param {boolean} isContiguousNodiff true if the current 'hasDiff' and one of previous row is both false
-   */
-  renderRow(revision, previousRevision, latestRevision, isOldestRevision, hasDiff) {
-    const {
-      t, sourceRevision, targetRevision, onChangeSourceInvoked, onChangeTargetInvoked,
-    } = this.props;
+
+import { Revision } from './Revision';
+
+import styles from './PageRevisionTable.module.scss';
+
+type PageRevisionTAble = {
+  revisions: IRevisionHasId[],
+  pagingLimit: number,
+  sourceRevision: IRevisionHasId,
+  targetRevision: IRevisionHasId,
+  onChangeSourceInvoked: React.Dispatch<React.SetStateAction<IRevisionHasId | undefined>>,
+  onChangeTargetInvoked: React.Dispatch<React.SetStateAction<IRevisionHasId | undefined>>,
+}
+
+export const PageRevisionTable = (props: PageRevisionTAble): JSX.Element => {
+  const { t } = useTranslation();
+
+  const {
+    revisions, pagingLimit, sourceRevision, targetRevision, onChangeSourceInvoked, onChangeTargetInvoked,
+  } = props;
+
+  const revisionCount = revisions.length;
+  const latestRevision = revisions[0];
+  const oldestRevision = revisions[revisions.length - 1];
+
+  const renderRow = (revision: IRevisionHasId, previousRevision: IRevisionHasId, latestRevision: IRevisionHasId,
+      isOldestRevision: boolean, hasDiff: boolean) => {
+
     const revisionId = revision._id;
 
     const handleCompareLatestRevisionButton = () => {
@@ -35,7 +47,6 @@ class PageRevisionTable extends React.Component {
         <td className="col" key={`revision-history-top-${revisionId}`}>
           <div className="d-lg-flex">
             <Revision
-              t={this.props.t}
               revision={revision}
               isLatestRevision={revision === latestRevision}
               hasDiff={hasDiff}
@@ -98,73 +109,38 @@ class PageRevisionTable extends React.Component {
         </td>
       </tr>
     );
-  }
-
-  render() {
-    const { t, pagingLimit } = this.props;
-
-    const revisions = this.props.revisions;
-    const revisionCount = this.props.revisions.length;
-    const latestRevision = revisions[0];
-    const oldestRevision = revisions[revisions.length - 1];
-
-    let hasDiffPrev;
-
-    const revisionList = this.props.revisions.map((revision, idx) => {
-      // Returns null because the last revision is for the bottom diff display
-      if (idx === pagingLimit) {
-        return null;
-      }
-
-      let previousRevision;
-      if (idx + 1 < revisionCount) {
-        previousRevision = revisions[idx + 1];
-      }
-      else {
-        previousRevision = revision; // if it is the first revision, show full text as diff text
-      }
+  };
+
+  const revisionList = revisions.map((revision, idx) => {
+    // Returns null because the last revision is for the bottom diff display
+    if (idx === pagingLimit) {
+      return null;
+    }
+
+    // if it is the first revision, show full text as diff text
+    const previousRevision = (idx + 1 < revisionCount) ? revisions[idx + 1] : revision;
+
+    const isOldestRevision = revision === oldestRevision;
+
+    // set 'true' if undefined for backward compatibility
+    const hasDiff = revision.hasDiffToPrev !== false;
+
+    return renderRow(revision, previousRevision, latestRevision, isOldestRevision, hasDiff);
+  });
+
+  return (
+    <table className={`${styles['revision-history-table']} table revision-history-table`}>
+      <thead>
+        <tr className="d-flex">
+          <th className="col">{ t('page_history.revision') }</th>
+          <th className="col-1">{ t('page_history.comparing_source') }</th>
+          <th className="col-2">{ t('page_history.comparing_target') }</th>
+        </tr>
+      </thead>
+      <tbody className="overflow-auto d-block">
+        {revisionList}
+      </tbody>
+    </table>
+  );
 
-      const isOldestRevision = revision === oldestRevision;
-
-      const hasDiff = revision.hasDiffToPrev !== false; // set 'true' if undefined for backward compatibility
-
-      hasDiffPrev = hasDiff;
-
-      return this.renderRow(revision, previousRevision, latestRevision, isOldestRevision, hasDiff);
-    });
-
-    return (
-      <table className="table revision-history-table">
-        <thead>
-          <tr className="d-flex">
-            <th className="col">{ t('page_history.revision') }</th>
-            <th className="col-1">{ t('page_history.comparing_source') }</th>
-            <th className="col-2">{ t('page_history.comparing_target') }</th>
-          </tr>
-        </thead>
-        <tbody className="overflow-auto d-block">
-          {revisionList}
-        </tbody>
-      </table>
-    );
-  }
-
-}
-
-PageRevisionTable.propTypes = {
-  t: PropTypes.func.isRequired, // i18next
-
-  revisions: PropTypes.array,
-  pagingLimit: PropTypes.number,
-  sourceRevision: PropTypes.instanceOf(Object),
-  targetRevision: PropTypes.instanceOf(Object),
-  onChangeSourceInvoked: PropTypes.func.isRequired,
-  onChangeTargetInvoked: PropTypes.func.isRequired,
 };
-
-const PageRevisionTableWrapperFC = (props) => {
-  const { t } = useTranslation();
-  return <PageRevisionTable t={t} {...props} />;
-};
-
-export default PageRevisionTableWrapperFC;

+ 0 - 88
packages/app/src/components/PageHistory/Revision.jsx

@@ -1,88 +0,0 @@
-import React from 'react';
-
-import { UserPicture } from '@growi/ui';
-import PropTypes from 'prop-types';
-
-import UserDate from '../User/UserDate';
-import Username from '../User/Username';
-
-export default class Revision extends React.Component {
-
-  componentDidMount() {
-  }
-
-  renderSimplifiedNodiff(revision) {
-    const { t } = this.props;
-
-    const author = revision.author;
-
-    let pic = '';
-    if (typeof author === 'object') {
-      pic = <UserPicture user={author} size="sm" />;
-    }
-
-    return (
-      <div className="revision-history-main revision-history-main-nodiff my-1 d-flex align-items-center">
-        <div className="picture-container">
-          {pic}
-        </div>
-        <div className="ml-3">
-          <span className="text-muted small">
-            <UserDate dateTime={revision.createdAt} /> ({ t('No diff') })
-          </span>
-        </div>
-      </div>
-    );
-  }
-
-  renderFull(revision) {
-    const { t } = this.props;
-
-    const author = revision.author;
-
-    let pic = '';
-    if (typeof author === 'object') {
-      pic = <UserPicture user={author} size="lg" />;
-    }
-
-    return (
-      <div className="revision-history-main d-flex">
-        <div className="picture-container">
-          {pic}
-        </div>
-        <div className="ml-2">
-          <div className="revision-history-author mb-1">
-            <strong><Username user={author}></Username></strong>
-            {this.props.isLatestRevision && <span className="badge badge-info ml-2">Latest</span>}
-          </div>
-          <div className="mb-1">
-            <UserDate dateTime={revision.createdAt} />
-            <br className="d-xl-none d-block" />
-            <a className="ml-xl-3" href={`?revisionId=${revision._id}`}>
-              <i className="icon-login"></i> { t('Go to this version') }
-            </a>
-          </div>
-        </div>
-      </div>
-    );
-  }
-
-  render() {
-    const revision = this.props.revision;
-
-    if (!this.props.hasDiff) {
-      return this.renderSimplifiedNodiff(revision);
-    }
-
-    return this.renderFull(revision);
-
-  }
-
-}
-
-Revision.propTypes = {
-  t: PropTypes.func.isRequired, // i18next
-  revision: PropTypes.object,
-  isLatestRevision: PropTypes.bool.isRequired,
-  hasDiff: PropTypes.bool.isRequired,
-};

+ 13 - 0
packages/app/src/components/PageHistory/Revision.module.scss

@@ -0,0 +1,13 @@
+.revision-history-main :global {
+  img.picture-lg {
+    width: 32px;
+    height: 32px;
+  }
+}
+
+.revision-history-main-nodiff :global {
+  .picture-container {
+    min-width: 32px;
+    text-align: center; // centering .picture
+  }
+}

+ 79 - 0
packages/app/src/components/PageHistory/Revision.tsx

@@ -0,0 +1,79 @@
+import React from 'react';
+
+import { IRevisionHasId } from '@growi/core';
+import { UserPicture } from '@growi/ui';
+import { useTranslation } from 'next-i18next';
+
+import UserDate from '../User/UserDate';
+import Username from '../User/Username';
+
+import styles from './Revision.module.scss';
+
+type RevisionProps = {
+  revision: IRevisionHasId,
+  isLatestRevision: boolean,
+  hasDiff: boolean,
+}
+
+export const Revision = (props: RevisionProps): JSX.Element => {
+  const { t } = useTranslation();
+
+  const { revision, isLatestRevision, hasDiff } = props;
+
+  const renderSimplifiedNodiff = (revision: IRevisionHasId) => {
+
+    const author = revision.author;
+
+    const pic = (typeof author === 'object') ? <UserPicture user={author} size="sm" /> : <></>;
+
+    return (
+      <div className={`${styles['revision-history-main']} ${styles['revision-history-main-nodiff']}
+        revision-history-main revision-history-main-nodiff my-1 d-flex align-items-center`}>
+        <div className="picture-container">
+          { pic }
+        </div>
+        <div className="ml-3">
+          <span className="text-muted small">
+            <UserDate dateTime={revision.createdAt} /> ({ t('No diff') })
+          </span>
+        </div>
+      </div>
+    );
+  };
+
+  const renderFull = (revision: IRevisionHasId) => {
+
+    const author = revision.author;
+
+    const pic = (typeof author === 'object') ? <UserPicture user={author} size="lg" /> : <></>;
+
+    return (
+      <div className={`${styles['revision-history-main']} revision-history-main d-flex`}>
+        <div className="picture-container">
+          { pic }
+        </div>
+        <div className="ml-2">
+          <div className="revision-history-author mb-1">
+            <strong><Username user={author}></Username></strong>
+            { isLatestRevision && <span className="badge badge-info ml-2">Latest</span> }
+          </div>
+          <div className="mb-1">
+            <UserDate dateTime={revision.createdAt} />
+            <br className="d-xl-none d-block" />
+            <a className="ml-xl-3" href={`?revisionId=${revision._id}`}>
+              <i className="icon-login"></i> { t('Go to this version') }
+            </a>
+          </div>
+        </div>
+      </div>
+    );
+  };
+
+
+  if (hasDiff) {
+    return renderSimplifiedNodiff(revision);
+  }
+
+  return renderFull(revision);
+
+};

+ 35 - 0
packages/app/src/components/PageHistory/RevisionDiff.module.scss

@@ -0,0 +1,35 @@
+@use '~/styles/bootstrap/init' as bs;
+
+.revision-diff-container :global {
+  .comparison-header {
+    height: 34px;
+    background-color: #ffffff;
+    border: 1px solid bs.$gray-300;
+    .comparison-source-wrapper {
+      height: 26px;
+      margin-right: 1px;
+      border-right: 1px solid bs.$gray-300;
+      .comparison-source {
+        color: bs.$gray-500;
+      }
+    }
+    .comparison-target-wrapper {
+      height: 26px;
+      .comparison-target {
+        color: bs.$gray-500;
+      }
+    }
+  }
+
+  .revision-history-diff {
+    color: bs.$gray-900;
+    table-layout: fixed;
+
+    // revision-history
+    // to stay d2h-code-side-line-number in the revision history diff area
+    .d2h-wrapper {
+      position: relative;
+    }
+  }
+}
+

+ 5 - 3
packages/app/src/components/PageHistory/RevisionDiff.tsx

@@ -7,6 +7,8 @@ import { useTranslation } from 'next-i18next';
 
 import UserDate from '../User/UserDate';
 
+import styles from './RevisionDiff.module.scss';
+
 type RevisioinDiffProps = {
   currentRevision: IRevisionHasPageId,
   previousRevision: IRevisionHasPageId,
@@ -46,8 +48,8 @@ export const RevisionDiff = (props: RevisioinDiffProps): JSX.Element => {
   const diffView = { __html: diffViewHTML };
 
   return (
-    <>
-      <div className="comparison-header">
+    <div className={`${styles['revision-diff-container']}`}>
+      <div className='comparison-header'>
         <div className="container pt-1 pr-0">
           <div className="row">
             <div className="col comparison-source-wrapper pt-1 px-0">
@@ -67,7 +69,7 @@ export const RevisionDiff = (props: RevisioinDiffProps): JSX.Element => {
         </div>
       </div>
       <div className="revision-history-diff pb-1" dangerouslySetInnerHTML={diffView} />
-    </>
+    </div>
   );
 
 };

+ 14 - 0
packages/app/src/components/RevisionComparer/RevisionComparer.module.scss

@@ -0,0 +1,14 @@
+.revision-compare :global {
+  .revision-compare-container {
+    min-height: 100px;
+
+    &.nodiff {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+  }
+  .d2h-file-header {
+    display: none;
+  }
+}

+ 3 - 1
packages/app/src/components/RevisionComparer/RevisionComparer.tsx

@@ -11,6 +11,8 @@ import { useCurrentPagePath } from '~/stores/context';
 
 import { RevisionDiff } from '../PageHistory/RevisionDiff';
 
+import styles from './RevisionComparer.module.scss';
+
 const { encodeSpaces } = pagePathUtils;
 
 const DropdownItemContents = ({ title, contents }) => (
@@ -66,7 +68,7 @@ export const RevisionComparer = (props: RevisionComparerProps): JSX.Element => {
   }
 
   return (
-    <div className="revision-compare">
+    <div className={`${styles['revision-compare']} revision-compare`}>
       <div className="d-flex">
         <h4 className="align-self-center">{ t('page_history.comparing_revisions') }</h4>
         <Dropdown

+ 58 - 58
packages/app/src/styles/_page-history.scss

@@ -1,68 +1,68 @@
 // @import '../scss/variables';
 // @import '../scss/override-bootstrap-variables';
 
-.revision-history-table {
-  tbody {
-    max-height: 250px;
-  }
-}
+// .revision-history-table {
+//   tbody {
+//     max-height: 250px;
+//   }
+// }
 
-.revision-history-main {
-  img.picture-lg {
-    width: 32px;
-    height: 32px;
-  }
-}
+// .revision-history-main {
+//   img.picture-lg {
+//     width: 32px;
+//     height: 32px;
+//   }
+// }
 
-.revision-history-main-nodiff {
-  .picture-container {
-    min-width: 32px;
-    text-align: center; // centering .picture
-  }
-}
+// .revision-history-main-nodiff {
+//   .picture-container {
+//     min-width: 32px;
+//     text-align: center; // centering .picture
+//   }
+// }
 
-.revision-history-diff {
-  color: $gray-900;
-  table-layout: fixed;
+// .revision-history-diff {
+//   color: $gray-900;
+//   table-layout: fixed;
 
-  // revision-history
-  // to stay d2h-code-side-line-number in the revision history diff area
-  .d2h-wrapper {
-    position: relative;
-  }
-}
+//   // revision-history
+//   // to stay d2h-code-side-line-number in the revision history diff area
+//   .d2h-wrapper {
+//     position: relative;
+//   }
+// }
 
-.comparison-header {
-  height: 34px;
-  background-color: #ffffff;
-  border: 1px solid $gray-300;
-  .comparison-source-wrapper {
-    height: 26px;
-    margin-right: 1px;
-    border-right: 1px solid $gray-300;
-    .comparison-source {
-      color: $gray-500;
-    }
-  }
-  .comparison-target-wrapper {
-    height: 26px;
-    .comparison-target {
-      color: $gray-500;
-    }
-  }
-}
+// .comparison-header {
+//   height: 34px;
+//   background-color: #ffffff;
+//   border: 1px solid $gray-300;
+//   .comparison-source-wrapper {
+//     height: 26px;
+//     margin-right: 1px;
+//     border-right: 1px solid $gray-300;
+//     .comparison-source {
+//       color: $gray-500;
+//     }
+//   }
+//   .comparison-target-wrapper {
+//     height: 26px;
+//     .comparison-target {
+//       color: $gray-500;
+//     }
+//   }
+// }
 
-.revision-compare {
-  .revision-compare-container {
-    min-height: 100px;
+// .revision-compare {
+//   .revision-compare-container {
+//     min-height: 100px;
 
-    &.nodiff {
-      display: flex;
-      align-items: center;
-      justify-content: center;
-    }
-  }
-  .d2h-file-header {
-    display: none;
-  }
-}
+//     &.nodiff {
+//       display: flex;
+//       align-items: center;
+//       justify-content: center;
+//     }
+//   }
+//   .d2h-file-header {
+//     display: none;
+//   }
+// }

+ 2 - 2
packages/app/src/styles/_page.scss

@@ -1,5 +1,5 @@
-// import diff2html styles
-@import '~diff2html/bundles/css/diff2html.min.css';
+// // import diff2html styles
+// @import '~/diff2html/bundles/css/diff2html.min.css';
 
 /**
  * for table with handsontable modal button

+ 3 - 0
packages/app/src/styles/style-next.scss

@@ -5,6 +5,9 @@
 // // override codemirror
 // @import 'override-codemirror';
 
+// import diff2html styles
+@import '~diff2html/bundles/css/diff2html.min.css';
+
 // react-bootstrap-typeahead
 @import '~react-bootstrap-typeahead/css/Typeahead';
 @import 'override-rbt';