mizozobu 6 лет назад
Родитель
Сommit
404b7509b7

+ 3 - 4
src/client/js/components/Admin/UserGroup/UserGroupCreateForm.jsx

@@ -1,11 +1,10 @@
-/* eslint-disable react/no-multi-comp */
 import React from 'react';
 import React from 'react';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
 import { withTranslation } from 'react-i18next';
 import { withTranslation } from 'react-i18next';
 
 
 import { createSubscribedElement } from '../../UnstatedUtils';
 import { createSubscribedElement } from '../../UnstatedUtils';
 import AppContainer from '../../../services/AppContainer';
 import AppContainer from '../../../services/AppContainer';
-import { apiErrorHandler, apiSuccessHandler } from '../../../util/apiNotification';
+import { toastSuccess, toastError } from '../../../util/apiNotification';
 
 
 class UserGroupCreateForm extends React.Component {
 class UserGroupCreateForm extends React.Component {
 
 
@@ -52,10 +51,10 @@ class UserGroupCreateForm extends React.Component {
 
 
       this.setState({ name: '' });
       this.setState({ name: '' });
 
 
-      apiSuccessHandler(`Created a user group "${this.xss.process(userGroup.name)}"`);
+      toastSuccess(`Created a user group "${this.xss.process(userGroup.name)}"`);
     }
     }
     catch (err) {
     catch (err) {
-      apiErrorHandler(err);
+      toastError(err);
     }
     }
   }
   }
 
 

+ 0 - 1
src/client/js/components/Admin/UserGroup/UserGroupDeleteModal.jsx

@@ -1,4 +1,3 @@
-/* eslint-disable react/no-multi-comp */
 import React from 'react';
 import React from 'react';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
 import { withTranslation } from 'react-i18next';
 import { withTranslation } from 'react-i18next';

+ 20 - 16
src/client/js/components/Admin/UserGroup/UserGroupPage.jsx

@@ -1,4 +1,3 @@
-/* eslint-disable react/no-multi-comp */
 import React, { Fragment } from 'react';
 import React, { Fragment } from 'react';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
 
 
@@ -8,7 +7,7 @@ import UserGroupDeleteModal from './UserGroupDeleteModal';
 
 
 import { createSubscribedElement } from '../../UnstatedUtils';
 import { createSubscribedElement } from '../../UnstatedUtils';
 import AppContainer from '../../../services/AppContainer';
 import AppContainer from '../../../services/AppContainer';
-import { apiErrorHandler, apiSuccessHandler } from '../../../util/apiNotification';
+import { toastSuccess, toastError } from '../../../util/apiNotification';
 
 
 class UserGroupPage extends React.Component {
 class UserGroupPage extends React.Component {
 
 
@@ -40,7 +39,7 @@ class UserGroupPage extends React.Component {
       });
       });
     }
     }
     catch (err) {
     catch (err) {
-      apiErrorHandler(new Error('Unable to fetch groups from server'));
+      toastError(err);
     }
     }
   }
   }
 
 
@@ -86,10 +85,10 @@ class UserGroupPage extends React.Component {
         };
         };
       });
       });
 
 
-      apiSuccessHandler(`Deleted a group "${this.xss.process(res.data.userGroup.name)}"`);
+      toastSuccess(`Deleted a group "${this.xss.process(res.data.userGroup.name)}"`);
     }
     }
     catch (err) {
     catch (err) {
-      apiErrorHandler(new Error('Unable to delete the group'));
+      toastError(new Error('Unable to delete the group'));
     }
     }
   }
   }
 
 
@@ -97,19 +96,24 @@ class UserGroupPage extends React.Component {
     let userGroups = [];
     let userGroups = [];
     let userGroupRelations = {};
     let userGroupRelations = {};
 
 
-    const responses = await Promise.all([
-      this.props.appContainer.apiv3.get('/user-groups'),
-      this.props.appContainer.apiv3.get('/user-group-relations'),
-    ]);
+    try {
+      const responses = await Promise.all([
+        this.props.appContainer.apiv3.get('/user-groups'),
+        this.props.appContainer.apiv3.get('/user-group-relations'),
+      ]);
 
 
-    const [userGroupsRes, userGroupRelationsRes] = responses;
-    userGroups = userGroupsRes.data.userGroups;
-    userGroupRelations = userGroupRelationsRes.data.userGroupRelations;
+      const [userGroupsRes, userGroupRelationsRes] = responses;
+      userGroups = userGroupsRes.data.userGroups;
+      userGroupRelations = userGroupRelationsRes.data.userGroupRelations;
 
 
-    this.setState({
-      userGroups,
-      userGroupRelations,
-    });
+      this.setState({
+        userGroups,
+        userGroupRelations,
+      });
+    }
+    catch (err) {
+      toastError(err);
+    }
   }
   }
 
 
   render() {
   render() {

+ 0 - 1
src/client/js/components/Admin/UserGroup/UserGroupTable.jsx

@@ -1,4 +1,3 @@
-/* eslint-disable react/no-multi-comp */
 import React, { Fragment } from 'react';
 import React, { Fragment } from 'react';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
 import { withTranslation } from 'react-i18next';
 import { withTranslation } from 'react-i18next';

+ 2 - 2
src/client/js/components/Page/TagLabels.jsx

@@ -56,7 +56,7 @@ class TagLabels extends React.Component {
         pageContainer.setState({ tags });
         pageContainer.setState({ tags });
         editorContainer.setState({ tags });
         editorContainer.setState({ tags });
 
 
-        this.apiSuccessHandler();
+        this.toastSuccess();
       }
       }
       catch (err) {
       catch (err) {
         this.apiErrorHandler(err);
         this.apiErrorHandler(err);
@@ -69,7 +69,7 @@ class TagLabels extends React.Component {
     }
     }
   }
   }
 
 
-  apiSuccessHandler() {
+  toastSuccess() {
     toastr.success(undefined, 'updated tags successfully', {
     toastr.success(undefined, 'updated tags successfully', {
       closeButton: true,
       closeButton: true,
       progressBar: true,
       progressBar: true,

+ 16 - 7
src/client/js/services/AppContainer.js

@@ -1,6 +1,7 @@
 import { Container } from 'unstated';
 import { Container } from 'unstated';
 
 
 import axios from 'axios';
 import axios from 'axios';
+import urljoin from 'url-join';
 
 
 import InterceptorManager from '@commons/service/interceptor-manager';
 import InterceptorManager from '@commons/service/interceptor-manager';
 
 
@@ -13,6 +14,7 @@ import {
 } from '../util/interceptor/detach-code-blocks';
 } from '../util/interceptor/detach-code-blocks';
 
 
 import i18nFactory from '../util/i18n';
 import i18nFactory from '../util/i18n';
+import apiv3ErrorHandler from '../util/apiv3ErrorHandler';
 
 
 /**
 /**
  * Service container related to options for Application
  * Service container related to options for Application
@@ -68,6 +70,8 @@ export default class AppContainer extends Container {
     this.apiGet = this.apiGet.bind(this);
     this.apiGet = this.apiGet.bind(this);
     this.apiPost = this.apiPost.bind(this);
     this.apiPost = this.apiPost.bind(this);
     this.apiRequest = this.apiRequest.bind(this);
     this.apiRequest = this.apiRequest.bind(this);
+
+    this.apiv3Root = '/_api/v3';
     this.apiv3 = {
     this.apiv3 = {
       get: this.apiv3Get.bind(this),
       get: this.apiv3Get.bind(this),
       post: this.apiv3Post.bind(this),
       post: this.apiv3Post.bind(this),
@@ -345,16 +349,21 @@ export default class AppContainer extends Container {
   }
   }
 
 
   async apiv3Request(method, path, params) {
   async apiv3Request(method, path, params) {
-    const res = await axios[method](`/_api/v3${path}`, params);
-
-    return res.data;
+    try {
+      const res = await axios[method](urljoin(this.apiv3Root, path), params);
+      return res.data;
+    }
+    catch (err) {
+      const errors = apiv3ErrorHandler(err);
+      throw errors;
+    }
   }
   }
 
 
-  apiv3Get(path, params) {
+  async apiv3Get(path, params) {
     return this.apiv3Request('get', path, { params });
     return this.apiv3Request('get', path, { params });
   }
   }
 
 
-  apiv3Post(path, params) {
+  async apiv3Post(path, params) {
     if (!params._csrf) {
     if (!params._csrf) {
       params._csrf = this.csrfToken;
       params._csrf = this.csrfToken;
     }
     }
@@ -362,7 +371,7 @@ export default class AppContainer extends Container {
     return this.apiv3Request('post', path, params);
     return this.apiv3Request('post', path, params);
   }
   }
 
 
-  apiv3Put(path, params) {
+  async apiv3Put(path, params) {
     if (!params._csrf) {
     if (!params._csrf) {
       params._csrf = this.csrfToken;
       params._csrf = this.csrfToken;
     }
     }
@@ -370,7 +379,7 @@ export default class AppContainer extends Container {
     return this.apiv3Request('put', path, params);
     return this.apiv3Request('put', path, params);
   }
   }
 
 
-  apiv3Delete(path, params) {
+  async apiv3Delete(path, params) {
     if (!params._csrf) {
     if (!params._csrf) {
       params._csrf = this.csrfToken;
       params._csrf = this.csrfToken;
     }
     }

+ 21 - 35
src/client/js/util/apiNotification.js

@@ -1,47 +1,33 @@
 import * as toastr from 'toastr';
 import * as toastr from 'toastr';
 import toArrayIfNot from '../../../lib/util/toArrayIfNot';
 import toArrayIfNot from '../../../lib/util/toArrayIfNot';
 
 
-const logger = require('@alias/logger')('growi');
-
-const errorFormatter = (err) => {
-  const prefixRegexp = /^Error: /;
-  let message = err.toString();
-
-  if (prefixRegexp.test(message)) {
-    message = message.replace(prefixRegexp, '');
-  }
-
-  return message;
+const toastrOption = {
+  error: {
+    closeButton: true,
+    progressBar: true,
+    newestOnTop: false,
+    showDuration: '100',
+    hideDuration: '100',
+    timeOut: '3000',
+  },
+  success: {
+    closeButton: true,
+    progressBar: true,
+    newestOnTop: false,
+    showDuration: '100',
+    hideDuration: '100',
+    timeOut: '3000',
+  },
 };
 };
 
 
-export const apiErrorHandler = (_err, header = 'Error') => {
-  // extract api errors from general 400 err
-  const err = _err.response ? _err.response.data.errors : _err;
+export const toastError = (err, header = 'Error', option = toastrOption.error) => {
   const errs = toArrayIfNot(err);
   const errs = toArrayIfNot(err);
 
 
   for (const err of errs) {
   for (const err of errs) {
-    logger.error(err.message);
-
-    toastr.error(errorFormatter(err.message), header, {
-      closeButton: true,
-      progressBar: true,
-      newestOnTop: false,
-      showDuration: '100',
-      hideDuration: '100',
-      timeOut: '3000',
-    });
+    toastr.error(err.message, header, option);
   }
   }
 };
 };
 
 
-export const apiSuccessHandler = (body, header = 'Success') => {
-  toastr.success(body, header, {
-    closeButton: true,
-    progressBar: true,
-    newestOnTop: false,
-    showDuration: '100',
-    hideDuration: '100',
-    timeOut: '3000',
-  });
+export const toastSuccess = (body, header = 'Success', option = toastrOption.success) => {
+  toastr.success(body, header, option);
 };
 };
-
-export default apiErrorHandler;

+ 17 - 0
src/client/js/util/apiv3ErrorHandler.js

@@ -0,0 +1,17 @@
+import toArrayIfNot from '../../../lib/util/toArrayIfNot';
+
+const logger = require('@alias/logger')('growi:apiv3');
+
+const apiv3ErrorHandler = (_err, header = 'Error') => {
+  // extract api errors from general 400 err
+  const err = _err.response ? _err.response.data.errors : _err;
+  const errs = toArrayIfNot(err);
+
+  for (const err of errs) {
+    logger.error(err.message);
+  }
+
+  return errs;
+};
+
+export default apiv3ErrorHandler;