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

Merge pull request #1146 from weseek/reacrify-admin-importer-2

Reacrify admin importer 2
Yuki Takei 6 лет назад
Родитель
Сommit
20f4df1873


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

@@ -725,7 +725,8 @@
   },
 
   "importer_management": {
-    "import_from": "Import from %s",
+    "import_from_esa": "Import from esa.io",
+    "import_from_qiita": "import_from Qiita:Team",
     "esa_settings": {
       "team_name": "Team name",
       "access_token": "Access token",

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

@@ -709,7 +709,8 @@
   },
 
   "importer_management": {
-    "import_from": "%s からインポート",
+    "import_from_esa": "esa.ioからインポート",
+    "import_from_qiita": "Qiita:Teamからインポート",
     "esa_settings": {
       "team_name": "チーム名",
       "access_token": "アクセストークン",

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

@@ -103,6 +103,7 @@ let componentMappings = {
   'admin-full-text-search-management': <FullTextSearchManagement />,
 
   'staff-credit': <StaffCredit />,
+  'admin-importer': <Importer />,
 };
 
 // additional definitions if data exists
@@ -195,15 +196,6 @@ if (adminUserGroupPageElem != null) {
   );
 }
 
-const adminImporterElem = document.getElementById('admin-importer');
-if (adminImporterElem != null) {
-  ReactDOM.render(
-    <Importer />,
-    adminImporterElem,
-  );
-}
-
-
 // うわーもうー (commented by Crowi team -- 2018.03.23 Yuki Takei)
 $('a[data-toggle="tab"][href="#revision-history"]').on('show.bs.tab', () => {
   ReactDOM.render(

+ 170 - 3
src/client/js/components/Admin/Importer.jsx

@@ -1,19 +1,186 @@
 import React, { Fragment } from 'react';
+import { withTranslation } from 'react-i18next';
+import PropTypes from 'prop-types';
+
+import AppContainer from '../../services/AppContainer';
+import { createSubscribedElement } from '../UnstatedUtils';
+import { toastSuccess, toastError } from '../../util/apiNotification';
 
 class Importer extends React.Component {
 
   constructor(props) {
-    super();
+    super(props);
+    this.state = {
+      esaTeamName: '',
+      esaAccessToken: '',
+    };
+    this.esaHandleSubmit = this.esaHandleSubmit.bind(this);
+    this.esaHandleSubmitTest = this.esaHandleSubmitTest.bind(this);
+    this.esaHandleSubmitUpdate = this.esaHandleSubmitUpdate.bind(this);
+    this.handleInputValue = this.handleInputValue.bind(this);
+  }
+
+  handleInputValue(event) {
+    this.setState({
+      [event.target.name]: event.target.value,
+    });
+  }
+
+  esaHandleSubmit() {
+    try {
+      const params = {
+        'importer:esa:team_name': this.state.esaTeamName,
+        'importer:esa:access_token': this.state.esaAccessToken,
+      };
+      this.props.appContainer.apiPost('/admin/import/esa', params);
+      toastSuccess('Import posts from esa success.');
+    }
+    catch (error) {
+      toastError(error, 'Error occurred in importing pages from esa.io');
+    }
+  }
+
+  esaHandleSubmitTest() {
+    try {
+      const params = {
+        'importer:esa:team_name': this.state.esaTeamName,
+        'importer:esa:access_token': this.state.esaAccessToken,
+
+      };
+
+      this.props.appContainer.apiPost('/admin/import/testEsaAPI', params);
+      toastSuccess('Test connection to esa success.');
+    }
+    catch (error) {
+      toastError(error, 'Test connection to esa failed.');
+    }
+  }
+
+  esaHandleSubmitUpdate() {
+    try {
+      const params = {
+        'importer:esa:team_name': this.state.esaTeamName,
+        'importer:esa:access_token': this.state.esaAccessToken,
+      };
+      this.props.appContainer.apiPost('/admin/settings/importerEsa', params);
+      toastSuccess('Update');
+    }
+    catch (error) {
+      toastError(error);
+    }
   }
 
   render() {
+    const { esaTeamName, esaAccessToken } = this.state;
+    const { t } = this.props;
     return (
       <Fragment>
-        <h1>連打</h1>
+        <form
+          className="form-horizontal"
+          id="importerSettingFormEsa"
+          role="form"
+        >
+          <fieldset>
+            <legend>{ t('importer_management.import_from_esa') }</legend>
+            <table className="table table-bordered table-mapping">
+              <thead>
+                <tr>
+                  <th width="45%">esa.io</th>
+                  <th width="10%"></th>
+                  <th>GROWI</th>
+                </tr>
+              </thead>
+              <tbody>
+                <tr>
+                  <th>{ t('Article') }</th>
+                  <th><i className="icon-arrow-right-circle text-success"></i></th>
+                  <th>{ t('Page') }</th>
+                </tr>
+                <tr>
+                  <th>{ t('Category') }</th>
+                  <th><i className="icon-arrow-right-circle text-success"></i></th>
+                  <th>{ t('Page Path') }</th>
+                </tr>
+                <tr>
+                  <th>{ t('User') }</th>
+                  <th></th>
+                  <th>(TBD)</th>
+                </tr>
+              </tbody>
+            </table>
+
+            <div className="well well-sm mb-0 small">
+              <ul>
+                <li>{ t('importer_management.page_skip') }</li>
+              </ul>
+            </div>
+
+            <div className="form-group">
+              <input type="password" name="dummypass" style={{ display: 'none', top: '-100px', left: '-100px' }} />
+            </div>
+
+            <div className="form-group">
+              <label htmlFor="settingForm[importer:esa:team_name]" className="col-xs-3 control-label">
+                { t('importer_management.esa_settings.team_name') }
+              </label>
+              <div className="col-xs-6">
+                <input className="form-control" type="text" name="esaTeamName" value={esaTeamName} onChange={this.handleInputValue} />
+              </div>
+
+            </div>
+
+            <div className="form-group">
+              <label htmlFor="settingForm[importer:esa:access_token]" className="col-xs-3 control-label">
+                { t('importer_management.esa_settings.access_token') }
+              </label>
+              <div className="col-xs-6">
+                <input className="form-control" type="password" name="esaAccessToken" value={esaAccessToken} onChange={this.handleInputValue} />
+              </div>
+            </div>
+
+            <div className="form-group">
+              <div className="col-xs-offset-3 col-xs-6">
+                <input
+                  id="testConnectionToEsa"
+                  type="button"
+                  className="btn btn-primary btn-esa"
+                  name="Esa"
+                  onClick={this.esaHandleSubmit}
+                  value={t('importer_management.import')}
+                />
+                <input type="button" className="btn btn-secondary" onClick={this.esaHandleSubmitUpdate} value={t('Update')} />
+                <span className="col-xs-offset-1">
+                  <input
+                    name="Esa"
+                    type="button"
+                    id="importFromEsa"
+                    className="btn btn-default btn-esa"
+                    onClick={this.esaHandleSubmitTest}
+                    value={t('importer_management.esa_settings.test_connection')}
+                  />
+                </span>
+
+              </div>
+            </div>
+          </fieldset>
+        </form>
       </Fragment>
+
     );
   }
 
 }
 
-export default Importer;
+/**
+ * Wrapper component for using unstated
+ */
+const ImporterWrapper = (props) => {
+  return createSubscribedElement(Importer, props, [AppContainer]);
+};
+
+Importer.propTypes = {
+  appContainer: PropTypes.instanceOf(AppContainer).isRequired,
+  t: PropTypes.func.isRequired, // i18next
+};
+
+export default withTranslation()(ImporterWrapper);

+ 1 - 5
src/server/routes/admin.js

@@ -1168,11 +1168,7 @@ module.exports = function(crowi, app) {
    * @param {*} res
    */
   actions.api.importerSettingEsa = async(req, res) => {
-    const form = req.form.settingForm;
-
-    if (!req.form.isValid) {
-      return res.json({ status: false, message: req.form.errors.join('\n') });
-    }
+    const form = req.body;
 
     await configManager.updateConfigsInTheSameNamespace('crowi', form);
     importer.initializeEsaClient(); // let it run in the back aftert res

+ 34 - 2
src/server/views/admin/importer.html

@@ -1,4 +1,3 @@
-
 {% extends '../layout/admin.html' %}
 
 {% block html_title %}{{ customizeService.generateCustomTitle(t('Import Data')) }}{% endblock %}
@@ -12,7 +11,40 @@
 {% endblock %}
 
 {% block content_main %}
-<div id ="admin-importer"></div>
+<div class="content-main admin-importer">
+
+  <div class="row">
+    <div class="col-md-3">
+      {% include './widget/menu.html' with {current: 'importer'} %}
+    </div>
+    <div class="col-lg-7 col-md-9">
+
+      <!-- Flash message for success -->
+      {% set smessage = req.flash('successMessage') %}
+      {% if smessage.length %}
+      <div class="alert alert-success">
+        {% for e in smessage %}
+        {{ e }}<br>
+        {% endfor %}
+      </div>
+      {% endif %}
+
+      <!-- Flash message for error -->
+      {% set emessage = req.flash('errorMessage') %}
+      {% if emessage.length %}
+      <div class="alert alert-danger">
+        {% for e in emessage %}
+        {{ e }}<br>
+        {% endfor %}
+      </div>
+      {% endif %}
+
+      <div id="admin-importer"></div>
+
+    </div>
+  </div>
+</div>
+
 {% endblock content_main %}
 
 {% block content_footer %}