Răsfoiți Sursa

create unstated container about app settings

yusuketk 6 ani în urmă
părinte
comite
900870f403

+ 15 - 2
src/client/js/app.jsx

@@ -40,7 +40,7 @@ import CustomScriptEditor from './components/Admin/CustomScriptEditor';
 import CustomHeaderEditor from './components/Admin/CustomHeaderEditor';
 import MarkdownSetting from './components/Admin/MarkdownSetting/MarkDownSetting';
 import UserManagement from './components/Admin/UserManagement';
-import AppSettingPage from './components/Admin/AppSettingPage';
+import AppSettingPage from './components/Admin/App/AppSettingPage';
 import ManageExternalAccount from './components/Admin/ManageExternalAccount';
 import UserGroupPage from './components/Admin/UserGroup/UserGroupPage';
 import Customize from './components/Admin/Customize/Customize';
@@ -55,6 +55,7 @@ import EditorContainer from './services/EditorContainer';
 import TagContainer from './services/TagContainer';
 import UserGroupDetailContainer from './services/UserGroupDetailContainer';
 import AdminUsersContainer from './services/AdminUsersContainer';
+import AdminAppContainer from './services/AdminAppContainer';
 import WebsocketContainer from './services/WebsocketContainer';
 import MarkDownSettingContainer from './services/MarkDownSettingContainer';
 import AdminExternalAccountsContainer from './services/AdminExternalAccountsContainer';
@@ -110,7 +111,6 @@ let componentMappings = {
   'user-created-list': <RecentCreated />,
   'user-draft-list': <MyDraftList />,
 
-  'admin-app': <AppSettingPage />,
   'admin-full-text-search-management': <FullTextSearchManagement />,
   'admin-customize': <Customize />,
 
@@ -160,6 +160,19 @@ Object.keys(componentMappings).forEach((key) => {
 });
 
 // render for admin
+const adminAppElem = document.getElementById('admin-app');
+if (adminAppElem != null) {
+  const adminAppContainer = new AdminAppContainer(appContainer);
+  ReactDOM.render(
+    <Provider inject={[injectableContainers, adminAppContainer]}>
+      <I18nextProvider i18n={i18n}>
+        <AppSettingPage />
+      </I18nextProvider>
+    </Provider>,
+    adminAppElem,
+  );
+}
+
 const adminUsersElem = document.getElementById('admin-user-page');
 if (adminUsersElem != null) {
   const adminUsersContainer = new AdminUsersContainer(appContainer);

+ 8 - 6
src/client/js/components/Admin/App/AppSetting.jsx

@@ -7,6 +7,7 @@ import { createSubscribedElement } from '../../UnstatedUtils';
 import { toastSuccess, toastError } from '../../../util/apiNotification';
 
 import AppContainer from '../../../services/AppContainer';
+import AdminAppContainer from '../../../services/AdminAppContainer';
 
 const logger = loggerFactory('growi:appSettings');
 
@@ -15,13 +16,13 @@ class AppSetting extends React.Component {
   constructor(props) {
     super(props);
 
-    const currentValues = props;
+    const { adminAppContainer } = this.props;
 
     this.state = {
-      title: currentValues.title,
-      confidential: currentValues.confidential,
-      globalLang: currentValues.globalLang,
-      fileUpload: currentValues.fileUpload,
+      title: adminAppContainer.state.title,
+      confidential: adminAppContainer.state.confidential,
+      globalLang: adminAppContainer.state.globalLang,
+      fileUpload: adminAppContainer.state.fileUpload,
     };
 
     this.submitHandler = this.submitHandler.bind(this);
@@ -181,12 +182,13 @@ class AppSetting extends React.Component {
  * Wrapper component for using unstated
  */
 const AppSettingWrapper = (props) => {
-  return createSubscribedElement(AppSetting, props, [AppContainer]);
+  return createSubscribedElement(AppSetting, props, [AppContainer, AdminAppContainer]);
 };
 
 AppSetting.propTypes = {
   t: PropTypes.func.isRequired, // i18next
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
+  adminAppContainer: PropTypes.instanceOf(AdminAppContainer).isRequired,
 };
 
 export default withTranslation()(AppSettingWrapper);

+ 7 - 5
src/client/js/components/Admin/App/SiteUrlSetting.jsx

@@ -7,6 +7,7 @@ import { createSubscribedElement } from '../../UnstatedUtils';
 import { toastSuccess, toastError } from '../../../util/apiNotification';
 
 import AppContainer from '../../../services/AppContainer';
+import AdminAppContainer from '../../../services/AdminAppContainer';
 
 const logger = loggerFactory('growi:appSettings');
 
@@ -15,12 +16,12 @@ class SiteUrlSetting extends React.Component {
   constructor(props) {
     super(props);
 
-    const currentValues = props;
+    const { adminAppContainer } = this.props;
 
     this.state = {
-      siteUrl: currentValues.siteUrl,
-      envSiteUrl: currentValues.envSiteUrl,
-      isSetSiteUrl: currentValues.isSetSiteUrl,
+      siteUrl: adminAppContainer.state.siteUrl,
+      envSiteUrl: adminAppContainer.state.envSiteUrl,
+      isSetSiteUrl: adminAppContainer.state.isSetSiteUrl,
     };
 
     this.submitHandler = this.submitHandler.bind(this);
@@ -121,12 +122,13 @@ class SiteUrlSetting extends React.Component {
  * Wrapper component for using unstated
  */
 const SiteUrlSettingWrapper = (props) => {
-  return createSubscribedElement(SiteUrlSetting, props, [AppContainer]);
+  return createSubscribedElement(SiteUrlSetting, props, [AppContainer, AdminAppContainer]);
 };
 
 SiteUrlSetting.propTypes = {
   t: PropTypes.func.isRequired, // i18next
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
+  adminAppContainer: PropTypes.instanceOf(AdminAppContainer).isRequired,
 };
 
 export default withTranslation()(SiteUrlSettingWrapper);

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

@@ -0,0 +1,81 @@
+import { Container } from 'unstated';
+
+import loggerFactory from '@alias/logger';
+
+import { toastError } from '../util/apiNotification';
+
+const logger = loggerFactory('growi:appSettings');
+
+/**
+ * Service container for admin app setting page (AppSettings.jsx)
+ * @extends {Container} unstated Container
+ */
+export default class AdminAppContainer extends Container {
+
+  constructor(appContainer) {
+    super();
+
+    this.appContainer = appContainer;
+
+    this.state = {
+      title: '',
+      confidential: '',
+      globalLang: '',
+      fileUpload: '',
+      siteUrl: '',
+      envSiteUrl: '',
+      isSetSiteUrl: true,
+    };
+
+  }
+
+  /**
+   * Workaround for the mangling in production build to break constructor.name
+   */
+  static getClassName() {
+    return 'AdminAppContainer';
+  }
+
+  /**
+   * retrieve app sttings data
+   */
+  async retrieveAppSettingsData() {
+    try {
+      const response = await this.appContainer.apiv3.get('/app-settings/');
+      const { appSettingParams } = response.data;
+
+      this.setState({
+        title: appSettingParams.title,
+        confidential: appSettingParams.confidential,
+        globalLang: appSettingParams.globalLang,
+        fileUpload: appSettingParams.fileUpload,
+        siteUrl: appSettingParams.siteUrl,
+        envSiteUrl: appSettingParams.envSiteUrl,
+        isSetSiteUrl: !!appSettingParams.siteUrl,
+      });
+
+    }
+    catch (err) {
+      logger.error(err);
+      toastError(new Error('Failed to fetch data'));
+    }
+  }
+
+
+  inputTitleChangeHandler(event) {
+    this.setState({ title: event.target.value });
+  }
+
+  inputConfidentialChangeHandler(event) {
+    this.setState({ confidential: event.target.value });
+  }
+
+  inputGlobalLangChangeHandler(event) {
+    this.setState({ globalLang: event.target.value });
+  }
+
+  inputFileUploadChangeHandler(event) {
+    this.setState({ fileUpload: event.target.checked });
+  }
+
+}