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

use suspense in app settings page

yusuketk 5 лет назад
Родитель
Сommit
adc8f9b0bf

+ 6 - 61
src/client/js/components/Admin/App/AppSettingsPage.jsx

@@ -1,4 +1,4 @@
-import React, { Fragment } from 'react';
+import React, { Suspense } from 'react';
 import { withTranslation } from 'react-i18next';
 import PropTypes from 'prop-types';
 import loggerFactory from '@alias/logger';
@@ -6,34 +6,19 @@ import loggerFactory from '@alias/logger';
 import { withUnstatedContainers } from '../../UnstatedUtils';
 import { toastError } from '../../../util/apiNotification';
 
-import AppContainer from '../../../services/AppContainer';
 import AdminAppContainer from '../../../services/AdminAppContainer';
 
-import AppSetting from './AppSetting';
-import SiteUrlSetting from './SiteUrlSetting';
-import MailSetting from './MailSetting';
-import AwsSetting from './AwsSetting';
-import PluginSetting from './PluginSetting';
+import RenderAppSettingsPage from './RenderAppSettingsPage';
 
 const logger = loggerFactory('growi:appSettings');
 
 class AppSettingsPage extends React.Component {
 
-  constructor(props) {
-    super(props);
-
-    this.state = {
-      isRetrieving: true,
-    };
-
-  }
-
   async componentDidMount() {
     const { adminAppContainer } = this.props;
 
     try {
       await adminAppContainer.retrieveAppSettingsData();
-      this.setState({ isRetrieving: false });
     }
     catch (err) {
       toastError(err);
@@ -43,49 +28,10 @@ class AppSettingsPage extends React.Component {
   }
 
   render() {
-    if (this.state.isRetrieving) {
-      return null;
-    }
-
-    const { t } = this.props;
-
     return (
-      <Fragment>
-        <div className="row">
-          <div className="col-lg-12">
-            <h2 className="admin-setting-header">{t('App Settings')}</h2>
-            <AppSetting />
-          </div>
-        </div>
-
-        <div className="row mt-5">
-          <div className="col-lg-12">
-            <h2 className="admin-setting-header">{t('Site URL settings')}</h2>
-            <SiteUrlSetting />
-          </div>
-        </div>
-
-        <div className="row mt-5">
-          <div className="col-lg-12">
-            <h2 className="admin-setting-header">{t('admin:app_setting.mail_settings')}</h2>
-            <MailSetting />
-          </div>
-        </div>
-
-        <div className="row mt-5">
-          <div className="col-lg-12">
-            <h2 className="admin-setting-header">{t('admin:app_setting.aws_settings')}</h2>
-            <AwsSetting />
-          </div>
-        </div>
-
-        <div className="row mt-5">
-          <div className="col-lg-12">
-            <h2 className="admin-setting-header">{t('admin:app_setting.plugin_settings')}</h2>
-            <PluginSetting />
-          </div>
-        </div>
-      </Fragment>
+      <Suspense fallback={<div className="text-center"><i className="fa fa-5x fa-spinner fa-pulse mx-auto text-muted"></i></div>}>
+        <RenderAppSettingsPage />
+      </Suspense>
     );
   }
 
@@ -93,14 +39,13 @@ class AppSettingsPage extends React.Component {
 
 AppSettingsPage.propTypes = {
   t: PropTypes.func.isRequired, // i18next
-  appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   adminAppContainer: PropTypes.instanceOf(AdminAppContainer).isRequired,
 };
 
 /**
  * Wrapper component for using unstated
  */
-const AppSettingsPageWrapper = withUnstatedContainers(AppSettingsPage, [AppContainer, AdminAppContainer]);
+const AppSettingsPageWrapper = withUnstatedContainers(AppSettingsPage, [AdminAppContainer]);
 
 
 export default withTranslation()(AppSettingsPageWrapper);

+ 79 - 0
src/client/js/components/Admin/App/RenderAppSettingsPage.jsx

@@ -0,0 +1,79 @@
+import React, { Fragment } from 'react';
+import { withTranslation } from 'react-i18next';
+import PropTypes from 'prop-types';
+
+import { withUnstatedContainers } from '../../UnstatedUtils';
+
+import AdminAppContainer from '../../../services/AdminAppContainer';
+
+import AppSetting from './AppSetting';
+import SiteUrlSetting from './SiteUrlSetting';
+import MailSetting from './MailSetting';
+import AwsSetting from './AwsSetting';
+import PluginSetting from './PluginSetting';
+
+
+class AppSettingsPage extends React.Component {
+
+  render() {
+    // activate suspense
+    if (this.props.adminAppContainer.state.isRetrieving) {
+      throw new Promise(() => {});
+    }
+
+    const { t } = this.props;
+
+    return (
+      <Fragment>
+        <div className="row">
+          <div className="col-lg-12">
+            <h2 className="admin-setting-header">{t('App Settings')}</h2>
+            <AppSetting />
+          </div>
+        </div>
+
+        <div className="row mt-5">
+          <div className="col-lg-12">
+            <h2 className="admin-setting-header">{t('Site URL settings')}</h2>
+            <SiteUrlSetting />
+          </div>
+        </div>
+
+        <div className="row mt-5">
+          <div className="col-lg-12">
+            <h2 className="admin-setting-header">{t('admin:app_setting.mail_settings')}</h2>
+            <MailSetting />
+          </div>
+        </div>
+
+        <div className="row mt-5">
+          <div className="col-lg-12">
+            <h2 className="admin-setting-header">{t('admin:app_setting.aws_settings')}</h2>
+            <AwsSetting />
+          </div>
+        </div>
+
+        <div className="row mt-5">
+          <div className="col-lg-12">
+            <h2 className="admin-setting-header">{t('admin:app_setting.plugin_settings')}</h2>
+            <PluginSetting />
+          </div>
+        </div>
+      </Fragment>
+    );
+  }
+
+}
+
+AppSettingsPage.propTypes = {
+  t: PropTypes.func.isRequired, // i18next
+  adminAppContainer: PropTypes.instanceOf(AdminAppContainer).isRequired,
+};
+
+/**
+ * Wrapper component for using unstated
+ */
+const AppSettingsPageWrapper = withUnstatedContainers(AppSettingsPage, [AdminAppContainer]);
+
+
+export default withTranslation()(AppSettingsPageWrapper);

+ 2 - 0
src/client/js/services/AdminAppContainer.js

@@ -18,6 +18,7 @@ export default class AdminAppContainer extends Container {
     this.appContainer = appContainer;
 
     this.state = {
+      isRetrieving: true,
       retrieveError: null,
       title: '',
       confidential: '',
@@ -78,6 +79,7 @@ export default class AdminAppContainer extends Container {
       const { appSettingsParams } = response.data;
 
       this.setState({
+        isRetrieving: false,
         title: appSettingsParams.title,
         confidential: appSettingsParams.confidential,
         globalLang: appSettingsParams.globalLang,