Просмотр исходного кода

Merge pull request #2641 from weseek/imprv/refactor-api-get-revisions

Imprv/refactor api get revisions
Yuki Takei 5 лет назад
Родитель
Сommit
203a802fa6

+ 3 - 1
src/client/js/app.jsx

@@ -141,7 +141,9 @@ $('a[data-toggle="tab"][href="#revision-history"]').on('show.bs.tab', () => {
   ReactDOM.render(
     <I18nextProvider i18n={i18n}>
       <ErrorBoundary>
-        <PageHistory shareLinkId={pageContainer.state.shareLinkId} pageId={pageContainer.state.pageId} crowi={appContainer} />
+        <Provider inject={injectableContainers}>
+          <PageHistory />
+        </Provider>
       </ErrorBoundary>
     </I18nextProvider>, document.getElementById('revision-history'),
   );

+ 21 - 13
src/client/js/components/PageHistory.jsx

@@ -3,8 +3,11 @@ import PropTypes from 'prop-types';
 import loggerFactory from '@alias/logger';
 
 import { withTranslation } from 'react-i18next';
+import { withUnstatedContainers } from './UnstatedUtils';
 
 import PageRevisionList from './PageHistory/PageRevisionList';
+import AppContainer from '../services/AppContainer';
+import PageContainer from '../services/PageContainer';
 
 const logger = loggerFactory('growi:PageHistory');
 class PageHistory extends React.Component {
@@ -13,6 +16,7 @@ class PageHistory extends React.Component {
     super(props);
 
     this.state = {
+      // TODO use suspense
       isLoaded: false,
       isLoading: false,
       errorMessage: null,
@@ -25,8 +29,8 @@ class PageHistory extends React.Component {
   }
 
   async componentWillMount() {
-    const pageId = this.props.pageId;
-    const shareLinkId = this.props.shareLinkId || null;
+    const { appContainer, pageContainer } = this.props;
+    const { shareLinkId, pageId } = pageContainer.state;
 
     if (!pageId) {
       return;
@@ -35,7 +39,7 @@ class PageHistory extends React.Component {
     let res;
     try {
       this.setState({ isLoading: true });
-      res = await this.props.crowi.apiGet('/revisions.ids', { page_id: pageId, share_link_id: shareLinkId });
+      res = await appContainer.apiv3Get('/revisions/list', { pageId, share_link_id: shareLinkId });
     }
     catch (err) {
       logger.error(err);
@@ -45,11 +49,11 @@ class PageHistory extends React.Component {
     finally {
       this.setState({ isLoading: false });
     }
-
-    const rev = res.revisions;
+    const rev = res.data.revisions;
     const diffOpened = {};
     const lastId = rev.length - 1;
-    res.revisions.forEach((revision, i) => {
+
+    res.data.revisions.forEach((revision, i) => {
       const user = revision.author;
       if (user) {
         rev[i].author = user;
@@ -111,14 +115,15 @@ class PageHistory extends React.Component {
   }
 
   fetchPageRevisionBody(revision) {
-    const shareLinkId = this.props.shareLinkId || null;
+    const { appContainer, pageContainer } = this.props;
+    const { shareLinkId, pageId } = pageContainer.state;
 
     if (revision.body) {
       return;
     }
 
-    this.props.crowi.apiGet('/revisions.get',
-      { page_id: this.props.pageId, revision_id: revision._id, share_link_id: shareLinkId })
+    appContainer.apiGet('/revisions.get',
+      { page_id: pageId, revision_id: revision._id, share_link_id: shareLinkId })
       .then((res) => {
         if (res.ok) {
           this.setState({
@@ -167,12 +172,15 @@ class PageHistory extends React.Component {
 
 }
 
+const PageHistoryWrapper = withUnstatedContainers(PageHistory, [AppContainer, PageContainer]);
+
+
 PageHistory.propTypes = {
+  appContainer: PropTypes.instanceOf(AppContainer).isRequired,
+  pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
+
   t: PropTypes.func.isRequired, // i18next
 
-  shareLinkId: PropTypes.string,
-  pageId: PropTypes.string,
-  crowi: PropTypes.object.isRequired,
 };
 
-export default withTranslation()(PageHistory);
+export default withTranslation()(PageHistoryWrapper);

+ 2 - 0
src/server/routes/apiv3/index.js

@@ -39,6 +39,8 @@ module.exports = (crowi) => {
 
   router.use('/page', require('./page')(crowi));
   router.use('/pages', require('./pages')(crowi));
+  router.use('/revisions', require('./revisions')(crowi));
+
   router.use('/share-links', require('./share-links')(crowi));
 
   router.use('/bookmarks', require('./bookmarks')(crowi));

+ 75 - 0
src/server/routes/apiv3/revisions.js

@@ -0,0 +1,75 @@
+const loggerFactory = require('@alias/logger');
+
+const logger = loggerFactory('growi:routes:apiv3:pages');
+
+const express = require('express');
+
+const { query } = require('express-validator/check');
+const ErrorV3 = require('../../models/vo/error-apiv3');
+
+const router = express.Router();
+
+/**
+ * @swagger
+ *  tags:
+ *    name: Revisions
+ */
+module.exports = (crowi) => {
+  const certifySharedPage = require('../../middlewares/certify-shared-file')(crowi);
+  const accessTokenParser = require('../../middlewares/access-token-parser')(crowi);
+  const loginRequired = require('../../middlewares/login-required')(crowi);
+  const apiV3FormValidator = require('../../middlewares/apiv3-form-validator')(crowi);
+
+  const {
+    Revision,
+    Page,
+  } = crowi.models;
+
+  const validator = {
+    retrieveRevisions: [
+      query('pageId').exists().withMessage('pageId is required'),
+    ],
+  };
+
+  /**
+   * @swagger
+   *
+   *    /revisions/list:
+   *      get:
+   *        tags: [Revisions]
+   *        description: Get revisions by page id
+   *        parameters:
+   *          - in: query
+   *            name: pageId
+   *            schema:
+   *              type: string
+   *              description:  page id
+   *        responses:
+   *          200:
+   *            description: Return revisions belong to page
+   *
+   */
+  router.get('/list', certifySharedPage, accessTokenParser, loginRequired, validator.retrieveRevisions, apiV3FormValidator, async(req, res) => {
+    const { pageId } = req.query;
+    const { isSharedPage } = req;
+
+    // check whether accessible
+    if (!isSharedPage && !(await Page.isAccessiblePageByViewer(pageId, req.user))) {
+      return res.apiv3Err(new ErrorV3('Current user is not accessible to this page.', 'forbidden-page'), 403);
+    }
+
+    try {
+      const page = await Page.findOne({ _id: pageId });
+      const revisions = await Revision.findRevisionIdList(page.path);
+      return res.apiv3({ revisions });
+    }
+    catch (err) {
+      const msg = 'Error occurred in getting revisions by poge id';
+      logger.error('Error', err);
+      return res.apiv3Err(new ErrorV3(msg, 'faild-to-find-revisions'), 500);
+    }
+
+  });
+
+  return router;
+};