Ver código fonte

Merge pull request #1319 from weseek/reactify-admin/create-customize-container

Reactify admin/create customize container
Yuki Takei 6 anos atrás
pai
commit
81ed400381

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

@@ -676,7 +676,8 @@
     "attach_title_header": "Add h1 section when create new page automatically",
     "attach_title_header_desc": "Add page path to the first line as h1 section when create new page",
     "recent_created__n_draft_num_desc": "Number of Recently Created Pages & Drafts Displayed",
-    "recently_created_n_draft_num_desc": "Number of recently created pages and drafts displayed on user page"
+    "recently_created_n_draft_num_desc": "Number of recently created pages and drafts displayed on user page",
+    "update_layout_success": "Succeeded to update layout"
   },
 
   "user_management": {

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

@@ -660,7 +660,8 @@
     "attach_title_header": "新規ページ作成時の h1 セクション自動挿入",
     "attach_title_header_desc": "新規作成したページの1行目に、ページのパスを h1 セクションとして挿入します。",
     "recent_created__n_draft_num_desc": "最近作成したページと下書きの表示数",
-    "recently_created_n_draft_num_desc": "ホーム画面の Recently Created での、1ページの表示数を設定します。"
+    "recently_created_n_draft_num_desc": "ホーム画面の Recently Created での、1ページの表示数を設定します。",
+    "update_layout_success": "レイアウトを更新しました"
   },
 
   "user_management": {

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

@@ -52,6 +52,7 @@ import PageContainer from './services/PageContainer';
 import CommentContainer from './services/CommentContainer';
 import EditorContainer from './services/EditorContainer';
 import TagContainer from './services/TagContainer';
+import AdminCustomizeContainer from './services/AdminCustomizeContainer';
 import UserGroupDetailContainer from './services/UserGroupDetailContainer';
 import AdminUsersContainer from './services/AdminUsersContainer';
 import WebsocketContainer from './services/WebsocketContainer';
@@ -109,7 +110,6 @@ let componentMappings = {
   'user-draft-list': <MyDraftList />,
 
   'admin-full-text-search-management': <FullTextSearchManagement />,
-  'admin-customize': <Customize />,
   'admin-external-account-setting': <ManageExternalAccount />,
 
   'staff-credit': <StaffCredit />,
@@ -157,6 +157,19 @@ Object.keys(componentMappings).forEach((key) => {
   }
 });
 
+const adminCustomizeElem = document.getElementById('admin-customize');
+if (adminCustomizeElem != null) {
+  const adminCustomizeContainer = new AdminCustomizeContainer(appContainer);
+  ReactDOM.render(
+    <Provider inject={[injectableContainers, adminCustomizeContainer]}>
+      <I18nextProvider i18n={i18n}>
+        <Customize />
+      </I18nextProvider>
+    </Provider>,
+    adminCustomizeElem,
+  );
+}
+
 // render for admin
 const adminUsersElem = document.getElementById('admin-user-page');
 if (adminUsersElem != null) {

+ 20 - 22
src/client/js/components/Admin/Customize/CustomizeLayoutOptions.jsx

@@ -1,31 +1,24 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import { withTranslation } from 'react-i18next';
-import CustomizeLayoutOption from './CustomizeLayoutOption';
-
-class CustomizeLayoutOptions extends React.Component {
 
-  constructor(props) {
-    super(props);
-    this.state = {
-      // TODO GW-477 save setting at customizeContainer
-      currentLayout: 'growi',
-    };
+import { createSubscribedElement } from '../../UnstatedUtils';
+import AdminCustomizeContainer from '../../../services/AdminCustomizeContainer';
+import AppContainer from '../../../services/AppContainer';
 
-    this.selectLayout = this.selectLayout.bind(this);
-  }
+import CustomizeLayoutOption from './CustomizeLayoutOption';
 
-  selectLayout(lauoutName) {
-    this.setState({ currentLayout: lauoutName });
-  }
+class CustomizeLayoutOptions extends React.Component {
 
   render() {
+    const { adminCustomizeContainer } = this.props;
+
     return (
       <React.Fragment>
         <CustomizeLayoutOption
           layoutType="crowi-plus"
-          isSelected={this.state.currentLayout === 'growi'}
-          onSelected={() => this.selectLayout('growi')}
+          isSelected={adminCustomizeContainer.state.currentLayout === 'growi'}
+          onSelected={() => adminCustomizeContainer.switchLayoutType('growi')}
           labelHtml={'GROWI Enhanced Layout <small className="text-success">(Recommended)</small>'}
         >
           {/* TODO i18n */}
@@ -39,8 +32,8 @@ class CustomizeLayoutOptions extends React.Component {
 
         <CustomizeLayoutOption
           layoutType="kibela"
-          isSelected={this.state.currentLayout === 'kibela'}
-          onSelected={() => this.selectLayout('kibela')}
+          isSelected={adminCustomizeContainer.state.currentLayout === 'kibela'}
+          onSelected={() => adminCustomizeContainer.switchLayoutType('kibela')}
           labelHtml="Kibela Like Layout"
         >
           {/* TODO i18n */}
@@ -54,8 +47,8 @@ class CustomizeLayoutOptions extends React.Component {
 
         <CustomizeLayoutOption
           layoutType="classic"
-          isSelected={this.state.currentLayout === 'crowi'}
-          onSelected={() => this.selectLayout('crowi')}
+          isSelected={adminCustomizeContainer.state.currentLayout === 'crowi'}
+          onSelected={() => adminCustomizeContainer.switchLayoutType('crowi')}
           labelHtml="Crowi Classic Layout"
         >
           {/* TODO i18n */}
@@ -72,9 +65,14 @@ class CustomizeLayoutOptions extends React.Component {
 
 }
 
+const CustomizeLayoutOptionsWrapper = (props) => {
+  return createSubscribedElement(CustomizeLayoutOptions, props, [AppContainer, AdminCustomizeContainer]);
+};
+
 CustomizeLayoutOptions.propTypes = {
   t: PropTypes.func.isRequired, // i18next
-
+  appContainer: PropTypes.instanceOf(AppContainer).isRequired,
+  adminCustomizeContainer: PropTypes.instanceOf(AdminCustomizeContainer).isRequired,
 };
 
-export default withTranslation()(CustomizeLayoutOptions);
+export default withTranslation()(CustomizeLayoutOptionsWrapper);

+ 38 - 1
src/client/js/components/Admin/Customize/CustomizeLayoutSetting.jsx

@@ -1,10 +1,41 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import { withTranslation } from 'react-i18next';
+
+import loggerFactory from '@alias/logger';
+
+import { createSubscribedElement } from '../../UnstatedUtils';
+import { toastSuccess, toastError } from '../../../util/apiNotification';
+
+import AppContainer from '../../../services/AppContainer';
+import AdminCustomizeContainer from '../../../services/AdminCustomizeContainer';
+
 import CustomizeLayoutOptions from './CustomizeLayoutOptions';
 
+const logger = loggerFactory('growi:importer');
+
+
 class CustomizeLayoutSetting extends React.Component {
 
+  constructor(props) {
+    super(props);
+
+    this.onClickSubmit = this.onClickSubmit.bind(this);
+  }
+
+  async onClickSubmit() {
+    const { t, adminCustomizeContainer } = this.props;
+
+    try {
+      await adminCustomizeContainer.updateCustomizeLayout();
+      toastSuccess(t('customize_page.update_layout_success'));
+    }
+    catch (err) {
+      toastError(err);
+      logger.error(err);
+    }
+  }
+
   render() {
     const { t } = this.props;
 
@@ -23,8 +54,14 @@ class CustomizeLayoutSetting extends React.Component {
 
 }
 
+const CustomizeLayoutSettingWrapper = (props) => {
+  return createSubscribedElement(CustomizeLayoutSetting, props, [AppContainer, AdminCustomizeContainer]);
+};
+
 CustomizeLayoutSetting.propTypes = {
   t: PropTypes.func.isRequired, // i18next
+  appContainer: PropTypes.instanceOf(AppContainer).isRequired,
+  adminCustomizeContainer: PropTypes.instanceOf(AdminCustomizeContainer).isRequired,
 };
 
-export default withTranslation()(CustomizeLayoutSetting);
+export default withTranslation()(CustomizeLayoutSettingWrapper);

+ 39 - 0
src/client/js/services/AdminCustomizeContainer.js

@@ -0,0 +1,39 @@
+import { Container } from 'unstated';
+
+/**
+ * Service container for admin customize setting page (Customize.jsx)
+ * @extends {Container} unstated Container
+ */
+export default class AdminCustomizeContainer extends Container {
+
+  constructor(appContainer) {
+    super();
+
+    this.appContainer = appContainer;
+
+    this.state = {
+      currentLayout: appContainer.config.layoutType,
+    };
+
+    this.switchLayoutType = this.switchLayoutType.bind(this);
+  }
+
+  /**
+   * Workaround for the mangling in production build to break constructor.name
+   */
+  static getClassName() {
+    return 'AdminCustomizeContainer';
+  }
+
+  /**
+   * Switch layoutType
+   */
+  switchLayoutType(lauoutName) {
+    this.setState({ currentLayout: lauoutName });
+  }
+
+  updateCustomizeLayout() {
+    // TODO GW-479 post api
+  }
+
+}