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

Merge pull request #1318 from weseek/reactify-admin/create-layout-setting-frontside

Reactify admin/create layout setting frontside
Yuki Takei 6 лет назад
Родитель
Сommit
145730c3d7

+ 17 - 19
src/client/js/components/Admin/Customize/Customize.jsx

@@ -6,6 +6,7 @@ import { withTranslation } from 'react-i18next';
 import AppContainer from '../../../services/AppContainer';
 
 import { createSubscribedElement } from '../../UnstatedUtils';
+import CustomizeLayoutSetting from './CustomizeLayoutSetting';
 
 class Customize extends React.Component {
 
@@ -14,25 +15,22 @@ class Customize extends React.Component {
 
     return (
       <Fragment>
-        {/* fieldset + legend ではなく、row + header + フォームコンポーネントに書き換える(GC244着手時に対応) */}
-        <fieldset>
-          <legend>{t('customize_page.Layout')}</legend>
-          {/* レイアウトフォームの react componentをここで呼ぶ(GW-244) */}
-          <legend>{t('customize_page.Theme')}</legend>
-          {/* テーマフォームの react componentをここで呼ぶ(GW-245) */}
-          <legend>{t('customize_page.Behavior')}</legend>
-          {/* 挙動フォームの react componentをここで呼ぶ(GW-246) */}
-          <legend>{t('customize_page.Function')}</legend>
-          {/* 機能フォームの react componentをここで呼ぶ(GW-276) */}
-          <legend>{t('customize_page.Code Highlight')}</legend>
-          {/* コードハイライトフォームの react componentをここで呼ぶ(GW-277) */}
-          <legend>{t('customize_page.custom_title')}</legend>
-          {/* カスタムタイトルフォームの react componentをここで呼ぶ(GW-278) */}
-          <legend>{t('customize_page.Custom CSS')}</legend>
-          {/* カスタムCSSフォームの react componentをここで呼ぶ(GW-279) */}
-          <legend>{t('customize_page.Custom script')}</legend>
-          {/* カスタムスクリプトフォームの react componentをここで呼ぶ(GW-280) */}
-        </fieldset>
+        <div className="row my-3">
+          <h2>{t('customize_page.Layout')}</h2>
+          <CustomizeLayoutSetting />
+        </div>
+        <legend>{t('customize_page.Behavior')}</legend>
+        {/* 挙動フォームの react componentをここで呼ぶ(GW-246) */}
+        <legend>{t('customize_page.Function')}</legend>
+        {/* 機能フォームの react componentをここで呼ぶ(GW-276) */}
+        <legend>{t('customize_page.Code Highlight')}</legend>
+        {/* コードハイライトフォームの react componentをここで呼ぶ(GW-277) */}
+        <legend>{t('customize_page.custom_title')}</legend>
+        {/* カスタムタイトルフォームの react componentをここで呼ぶ(GW-278) */}
+        <legend>{t('customize_page.Custom CSS')}</legend>
+        {/* カスタムCSSフォームの react componentをここで呼ぶ(GW-279) */}
+        <legend>{t('customize_page.Custom script')}</legend>
+        {/* カスタムスクリプトフォームの react componentをここで呼ぶ(GW-280) */}
       </Fragment>
     );
   }

+ 42 - 0
src/client/js/components/Admin/Customize/CustomizeLayoutOption.jsx

@@ -0,0 +1,42 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { withTranslation } from 'react-i18next';
+
+class CustomizeLayoutOption extends React.Component {
+
+  render() {
+    const { layoutType } = this.props;
+
+    return (
+      <div className="col-sm-4">
+        <h4>
+          <div className="radio radio-primary">
+            <input type="radio" id={`radio-layout-${layoutType}`} checked={this.props.isSelected} onChange={this.props.onSelected} />
+            <label htmlFor={`radio-layout-${layoutType}`}>
+              {/* eslint-disable-next-line react/no-danger */}
+              <span dangerouslySetInnerHTML={{ __html: this.props.labelHtml }} />
+            </label>
+          </div>
+        </h4>
+        <a href={`/images/admin/customize/layout-${layoutType}.gif`} className="ss-container">
+          <img src={`/images/admin/customize/layout-${layoutType}-thumb.gif`} width="240px" />
+        </a>
+        {/* render layout description */}
+        {this.props.children}
+      </div>
+    );
+  }
+
+}
+
+CustomizeLayoutOption.propTypes = {
+  t: PropTypes.func.isRequired, // i18next
+
+  layoutType: PropTypes.string.isRequired,
+  labelHtml: PropTypes.string.isRequired,
+  isSelected: PropTypes.bool.isRequired,
+  onSelected: PropTypes.func.isRequired,
+  children: PropTypes.array.isRequired,
+};
+
+export default withTranslation()(CustomizeLayoutOption);

+ 80 - 0
src/client/js/components/Admin/Customize/CustomizeLayoutOptions.jsx

@@ -0,0 +1,80 @@
+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',
+    };
+
+    this.selectLayout = this.selectLayout.bind(this);
+  }
+
+  selectLayout(lauoutName) {
+    this.setState({ currentLayout: lauoutName });
+  }
+
+  render() {
+    return (
+      <React.Fragment>
+        <CustomizeLayoutOption
+          layoutType="crowi-plus"
+          isSelected={this.state.currentLayout === 'growi'}
+          onSelected={() => this.selectLayout('growi')}
+          labelHtml={'GROWI Enhanced Layout <small className="text-success">(Recommended)</small>'}
+        >
+          {/* TODO i18n */}
+          <h4>Simple and Clear</h4>
+          <ul>
+            <li>Full screen layout and thin margins/paddings</li>
+            <li>Show and post comments at the bottom of the page</li>
+            <li>Affix Table-of-contents</li>
+          </ul>
+        </CustomizeLayoutOption>
+
+        <CustomizeLayoutOption
+          layoutType="kibela"
+          isSelected={this.state.currentLayout === 'kibela'}
+          onSelected={() => this.selectLayout('kibela')}
+          labelHtml="Kibela Like Layout"
+        >
+          {/* TODO i18n */}
+          <h4>Easy Viewing Structure</h4>
+          <ul>
+            <li>Center aligned contents</li>
+            <li>Show and post comments at the bottom of the page</li>
+            <li>Affix Table-of-contents</li>
+          </ul>
+        </CustomizeLayoutOption>
+
+        <CustomizeLayoutOption
+          layoutType="classic"
+          isSelected={this.state.currentLayout === 'crowi'}
+          onSelected={() => this.selectLayout('crowi')}
+          labelHtml="Crowi Classic Layout"
+        >
+          {/* TODO i18n */}
+          <h4>Separated Functions</h4>
+          <ul>
+            <li>Collapsible Sidebar</li>
+            <li>Show and post comments in Sidebar</li>
+            <li>Collapsible Table-of-contents</li>
+          </ul>
+        </CustomizeLayoutOption>
+      </React.Fragment>
+    );
+  }
+
+}
+
+CustomizeLayoutOptions.propTypes = {
+  t: PropTypes.func.isRequired, // i18next
+
+};
+
+export default withTranslation()(CustomizeLayoutOptions);

+ 30 - 0
src/client/js/components/Admin/Customize/CustomizeLayoutSetting.jsx

@@ -0,0 +1,30 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { withTranslation } from 'react-i18next';
+import CustomizeLayoutOptions from './CustomizeLayoutOptions';
+
+class CustomizeLayoutSetting extends React.Component {
+
+  render() {
+    const { t } = this.props;
+
+    return (
+      <form>
+        <CustomizeLayoutOptions />
+        {/* TODO GW-245 create themeForm Component */}
+        <div className="form-group my-3">
+          <div className="col-xs-offset-4 col-xs-5">
+            <div className="btn btn-primary" onClick={this.onClickSubmit}>{ t('Update') }</div>
+          </div>
+        </div>
+      </form>
+    );
+  }
+
+}
+
+CustomizeLayoutSetting.propTypes = {
+  t: PropTypes.func.isRequired, // i18next
+};
+
+export default withTranslation()(CustomizeLayoutSetting);