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

Merge pull request #1185 from weseek/create-invite-api

Create invite api
Yuki Takei 6 лет назад
Родитель
Сommit
a558026286

+ 2 - 1
resource/locales/en-US/translation.json

@@ -698,7 +698,8 @@
     "administrator_menu":"Administrator Menu",
     "cannot_remove":"You cannot remove yourself from administrator",
     "cannot_invite_maximum_users": "Can not invite more than the maximum number of users.",
-    "current_users": "Current users:"
+    "current_users": "Current users:",
+    "valid_email": "Valid email address is required"
   },
 
   "user_group_management": {

+ 2 - 1
resource/locales/ja/translation.json

@@ -681,7 +681,8 @@
     "administrator_menu": "管理者メニュー",
     "cannot_remove": "自分自身を管理者から外すことはできません",
     "cannot_invite_maximum_users": "ユーザーが上限に達したため招待できません。",
-    "current_users": "現在のユーザー数:"
+    "current_users": "現在のユーザー数:",
+    "valid_email": "メールアドレスを入力してください。"
   },
 
   "user_group_management": {

+ 19 - 3
src/client/js/components/Admin/Users/UserInviteModal.jsx

@@ -5,6 +5,8 @@ import { withTranslation } from 'react-i18next';
 import Button from 'react-bootstrap/es/Button';
 import Modal from 'react-bootstrap/es/Modal';
 
+import { toastSuccess, toastError } from '../../../util/apiNotification';
+
 import { createSubscribedElement } from '../../UnstatedUtils';
 import AppContainer from '../../../services/AppContainer';
 
@@ -23,9 +25,21 @@ class UserInviteModal extends React.Component {
     this.handleCheckBox = this.handleCheckBox.bind(this);
   }
 
-  handleSubmit() {
-    // TODO GW-165 新規ユーザーを招待するAPIを叩く
-    console.log('push submit');
+  validEmail() {
+    return this.state.email.match(/.+@.+\..+/) != null;
+  }
+
+  async handleSubmit() {
+    const { appContainer } = this.props;
+
+    try {
+      await appContainer.apiPost('/admin/user/invite', { email: this.state.email, sendEmail: this.state.sendEmail });
+      this.props.onToggleModal();
+      toastSuccess('Inviting user success');
+    }
+    catch (err) {
+      toastError(err);
+    }
   }
 
   handleInput(event) {
@@ -54,6 +68,7 @@ class UserInviteModal extends React.Component {
             value={this.state.email}
             onChange={this.handleInput}
           />
+          {!this.validEmail() && <p className="m-2 text-danger">{ t('user_management.valid_email') }</p>}
         </Modal.Body>
         <Modal.Footer className="d-flex">
           <label className="mr-3 text-left" style={{ flex: 1 }}>
@@ -72,6 +87,7 @@ class UserInviteModal extends React.Component {
               bsStyle="primary"
               className="fcbtn btn btn-primary btn-outline btn-rounded btn-1b"
               onClick={this.handleSubmit}
+              disabled={!this.validEmail()}
             >
               Done
             </Button>

+ 20 - 17
src/server/routes/admin.js

@@ -438,24 +438,28 @@ module.exports = function(crowi, app) {
       isUserCountExceedsUpperLimit,
     });
   };
+  api.validators = {};
+  actions.user.api = api;
 
-  actions.user.invite = function(req, res) {
-    const form = req.form.inviteForm;
-    const toSendEmail = form.sendEmail || false;
-    if (req.form.isValid) {
-      User.createUsersByInvitation(form.emailList.split('\n'), toSendEmail, (err, userList) => {
-        if (err) {
-          req.flash('errorMessage', req.form.errors.join('\n'));
-        }
-        else {
-          req.flash('createdUser', userList);
-        }
-        return res.redirect('/admin/users');
-      });
+  api.validators.inviteEmail = [
+    check('email').isEmail().withMessage('Error. Valid email address is required'),
+  ];
+
+  actions.user.invite = async function(req, res) {
+
+    const { validationResult } = require('express-validator');
+    const errors = validationResult(req);
+    if (!errors.isEmpty()) {
+      return res.json(ApiResponse.error('Valid email address is required'));
     }
-    else {
-      req.flash('errorMessage', req.form.errors.join('\n'));
-      return res.redirect('/admin/users');
+
+    try {
+      // TODO GW-170 after inputting multiple people
+      // await User.createUsersByInvitation(req.body.email.split('\n'), req.body.sendEmail);
+      return res.json(ApiResponse.success());
+    }
+    catch (err) {
+      return res.json(ApiResponse.error(err));
     }
   };
 
@@ -812,7 +816,6 @@ module.exports = function(crowi, app) {
   // Importer management
   actions.importer = {};
   actions.importer.api = api;
-  api.validators = {};
   api.validators.importer = {};
 
   actions.importer.index = function(req, res) {

+ 1 - 1
src/server/routes/index.js

@@ -118,7 +118,7 @@ module.exports = function(crowi, app) {
   app.post('/admin/global-notification/:id/remove', loginRequired() , adminRequired , admin.globalNotification.remove);
 
   app.get('/admin/users'                , loginRequired() , adminRequired , admin.user.index);
-  app.post('/admin/user/invite'         , form.admin.userInvite ,  loginRequired() , adminRequired , csrf, admin.user.invite);
+  app.post('/_api/admin/user/invite'         , form.admin.userInvite ,  loginRequired() , adminRequired , csrf, admin.user.api.validators.inviteEmail, admin.user.invite);
   app.post('/admin/user/:id/makeAdmin'  , loginRequired() , adminRequired , csrf, admin.user.makeAdmin);
   app.post('/admin/user/:id/removeFromAdmin', loginRequired() , adminRequired , admin.user.removeFromAdmin);
   app.post('/admin/user/:id/activate'   , loginRequired() , adminRequired , csrf, admin.user.activate);