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

Merge pull request #2751 from weseek/feat/gw-3705

gw-3705
takeru0001 5 лет назад
Родитель
Сommit
4eba98054d

+ 15 - 9
src/client/js/components/BookmarkButton.jsx

@@ -10,6 +10,7 @@ class BookmarkButton extends React.Component {
 
     this.state = {
       isBookmarked: false,
+      sumOfBookmarks: 0,
     };
 
     this.handleClick = this.handleClick.bind(this);
@@ -28,6 +29,8 @@ class BookmarkButton extends React.Component {
       if (response.data.bookmark != null) {
         this.setState({ isBookmarked: true });
       }
+      const result = await crowi.apiv3.get('/bookmarks/count-bookmarks', { pageId });
+      this.setState({ sumOfBookmarks: result.data.sumOfBookmarks });
     }
     catch (err) {
       toastError(err);
@@ -59,17 +62,20 @@ class BookmarkButton extends React.Component {
     }
 
     return (
-      <button
-        type="button"
-        href="#"
-        title="Bookmark"
-        onClick={this.handleClick}
-        className={`btn rounded-circle btn-bookmark border-0 d-edit-none
+      <div className="d-flex">
+        <button
+          type="button"
+          onClick={this.handleClick}
+          className={`btn rounded-circle btn-bookmark border-0 d-edit-none
           ${`btn-${this.props.size}`}
           ${this.state.isBookmarked ? 'active' : ''}`}
-      >
-        <i className="icon-star"></i>
-      </button>
+        >
+          <i className="icon-star"></i>
+        </button>
+        <div className="total-bookmarks">
+          {this.state.sumOfBookmarks}
+        </div>
+      </div>
     );
   }
 

+ 13 - 0
src/client/styles/scss/_subnav.scss

@@ -46,6 +46,13 @@
     font-size: 16px;
   }
 
+  .total-bookmarks {
+    width: 8px;
+    height: 16px;
+    padding: 0.5em 0 0 0;
+    font-size: 16px;
+  }
+
   ul.authors {
     padding: 0.7em 0 0.7em 1.5em;
     margin-bottom: 0;
@@ -96,6 +103,12 @@
       height: 12px;
       font-size: 12px;
     }
+
+    .total-bookmarks {
+      width: 6px;
+      height: 12px;
+      font-size: 12px;
+    }
   }
 }
 

+ 45 - 4
src/server/routes/apiv3/bookmarks.js

@@ -3,7 +3,7 @@ const loggerFactory = require('@alias/logger');
 const logger = loggerFactory('growi:routes:apiv3:bookmarks'); // eslint-disable-line no-unused-vars
 
 const express = require('express');
-const { body } = require('express-validator');
+const { body, query } = require('express-validator');
 
 const router = express.Router();
 
@@ -54,7 +54,8 @@ const router = express.Router();
 
 module.exports = (crowi) => {
   const accessTokenParser = require('../../middlewares/access-token-parser')(crowi);
-  const loginRequired = require('../../middlewares/login-required')(crowi);
+  const loginRequiredStrictly = require('../../middlewares/login-required')(crowi);
+  const loginRequired = require('../../middlewares/login-required')(crowi, true);
   const csrf = require('../../middlewares/csrf')(crowi);
   const apiV3FormValidator = require('../../middlewares/apiv3-form-validator')(crowi);
 
@@ -62,9 +63,12 @@ module.exports = (crowi) => {
 
   const validator = {
     bookmarks: [
-      body('pageId').isString(),
+      body('pageId').isMongoId(),
       body('bool').isBoolean(),
     ],
+    countBookmarks: [
+      query('pageId').isMongoId(),
+    ],
   };
 
   /**
@@ -126,7 +130,7 @@ module.exports = (crowi) => {
    *                schema:
    *                  $ref: '#/components/schemas/Bookmark'
    */
-  router.put('/', accessTokenParser, loginRequired, csrf, validator.bookmarks, apiV3FormValidator, async(req, res) => {
+  router.put('/', accessTokenParser, loginRequiredStrictly, csrf, validator.bookmarks, apiV3FormValidator, async(req, res) => {
     const { pageId, bool } = req.body;
 
     let bookmark;
@@ -153,5 +157,42 @@ module.exports = (crowi) => {
     return res.apiv3({ bookmark });
   });
 
+  /**
+   * @swagger
+   *
+   *    /count-bookmarks:
+   *      get:
+   *        tags: [Bookmarks]
+   *        summary: /bookmarks
+   *        description: Count bookmsrks
+   *        requestBody:
+   *          content:
+   *            application/json:
+   *              schema:
+   *                $ref: '#/components/schemas/BookmarkParams'
+   *        responses:
+   *          200:
+   *            description: Succeeded to count bookmarks.
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  $ref: '#/components/schemas/Bookmark'
+   */
+
+
+  router.get('/count-bookmarks', accessTokenParser, loginRequired, validator.countBookmarks, apiV3FormValidator, async(req, res) => {
+    const { pageId } = req.query;
+
+    try {
+      const sumOfBookmarks = await Bookmark.countByPageId(pageId);
+      return res.apiv3({ sumOfBookmarks });
+    }
+    catch (err) {
+      logger.error('get-bookmarks-list-failed', err);
+      return res.apiv3Err(err, 500);
+    }
+  });
+
+
   return router;
 };