Jelajahi Sumber

improve async GrowiZipImportForm processing

Yuki Takei 6 tahun lalu
induk
melakukan
dad00d5966

+ 12 - 20
src/client/js/components/Admin/ImportData/GrowiZipImportForm.jsx

@@ -1,7 +1,6 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import { withTranslation } from 'react-i18next';
-import * as toastr from 'toastr';
 
 import GrowiArchiveImportOption from '@commons/models/admin/growi-archive-import-option';
 import ImportOptionForPages from '@commons/models/admin/import-option-for-pages';
@@ -130,6 +129,16 @@ class GrowiImportForm extends React.Component {
 
       toastSuccess(undefined, 'Import process has terminated.');
     });
+
+    // websocket event
+    socket.on('admin:onErrorForImport', (err) => {
+      this.setState({
+        isImporting: false,
+        isImported: false,
+      });
+
+      toastError(err, 'Import process has failed.');
+    });
   }
 
   teardownWebsocketEventHandler() {
@@ -300,27 +309,10 @@ class GrowiImportForm extends React.Component {
         onPostImport();
       }
 
-      // TODO: toastSuccess, toastError
-      toastr.success(undefined, 'Export process has requested.', {
-        closeButton: true,
-        progressBar: true,
-        newestOnTop: false,
-        showDuration: '100',
-        hideDuration: '100',
-        timeOut: '1200',
-        extendedTimeOut: '150',
-      });
+      toastSuccess(undefined, 'Import process has requested.');
     }
     catch (err) {
-      // TODO: toastSuccess, toastError
-      toastr.error(err, 'Error', {
-        closeButton: true,
-        progressBar: true,
-        newestOnTop: false,
-        showDuration: '100',
-        hideDuration: '100',
-        timeOut: '3000',
-      });
+      toastError(err, 'Import request failed.');
     }
   }
 

+ 6 - 4
src/client/js/components/Admin/ImportData/GrowiZipImportItem.jsx

@@ -79,7 +79,7 @@ export default class GrowiZipImportItem extends React.Component {
 
   renderCheckbox() {
     const {
-      collectionName, isSelected,
+      collectionName, isSelected, isImporting,
     } = this.props;
 
     return (
@@ -91,6 +91,7 @@ export default class GrowiZipImportItem extends React.Component {
           className="form-check-input"
           value={collectionName}
           checked={isSelected}
+          disabled={isImporting}
           onChange={this.changeHandler}
         />
         <label className="text-capitalize form-check-label" htmlFor={collectionName}>
@@ -102,7 +103,7 @@ export default class GrowiZipImportItem extends React.Component {
 
   renderModeSelector() {
     const {
-      collectionName, option,
+      collectionName, option, isImporting,
     } = this.props;
 
     const attrMap = MODE_ATTR_MAP[option.mode];
@@ -118,6 +119,7 @@ export default class GrowiZipImportItem extends React.Component {
             className={`btn ${btnColor} btn-xs dropdown-toggle`}
             type="button"
             id="ddmMode"
+            disabled={isImporting}
             data-toggle="dropdown"
             aria-haspopup="true"
             aria-expanded="true"
@@ -142,13 +144,13 @@ export default class GrowiZipImportItem extends React.Component {
   }
 
   renderConfigButton() {
-    const { isConfigButtonAvailable } = this.props;
+    const { isImporting, isConfigButtonAvailable } = this.props;
 
     return (
       <button
         type="button"
         className="btn btn-default btn-xs ml-2"
-        disabled={!isConfigButtonAvailable}
+        disabled={isImporting || !isConfigButtonAvailable}
         onClick={isConfigButtonAvailable ? this.configButtonClickedHandler : null}
       >
         <i className="icon-settings"></i>

+ 11 - 4
src/server/routes/apiv3/import.js

@@ -75,6 +75,9 @@ module.exports = (crowi) => {
   this.adminEvent.on('onTerminateForImport', (data) => {
     crowi.getIo().sockets.emit('admin:onTerminateForImport', data);
   });
+  this.adminEvent.on('onErrorForImport', (data) => {
+    crowi.getIo().sockets.emit('admin:onErrorForImport', data);
+  });
 
   const uploads = multer({
     storage: multer.diskStorage({
@@ -164,6 +167,9 @@ module.exports = (crowi) => {
     const { fileName, collections, optionsMap } = req.body;
     const zipFile = importService.getFile(fileName);
 
+    // return response first
+    res.apiv3();
+
     /*
      * unzip, parse
      */
@@ -184,7 +190,8 @@ module.exports = (crowi) => {
     }
     catch (err) {
       logger.error(err);
-      return res.apiv3Err(err, 500);
+      this.adminEvent.emit('onErrorForImport', { message: err.message });
+      return;
     }
 
     /*
@@ -195,7 +202,8 @@ module.exports = (crowi) => {
     }
     catch (err) {
       logger.error(err);
-      return res.apiv3Err(err);
+      this.adminEvent.emit('onErrorForImport', { message: err.message });
+      return;
     }
 
     // generate maps of ImportSettings to import
@@ -219,11 +227,10 @@ module.exports = (crowi) => {
      */
     try {
       importService.import(collections, importSettingsMap);
-      return res.apiv3();
     }
     catch (err) {
       logger.error(err);
-      return res.apiv3Err(err, 500);
+      this.adminEvent.emit('onErrorForImport', { message: err.message });
     }
   });