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

Merge pull request #1409 from weseek/create-customize-title

create-customizeTitle
Yuki Takei 6 лет назад
Родитель
Сommit
eaef232310

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

@@ -685,6 +685,7 @@
     "update_behavior_success": "Succeeded to update behavior",
     "update_function_success": "Succeeded to update function",
     "update_highlight_success": "Succeeded to update code highlight",
+    "update_customTitle_success": "Succeeded to update customize title",
     "update_customHeader_success": "Succeeded to update customize html header",
     "update_customCss_success": "Succeeded to update customize css",
     "update_script_success": "Succeeded to update custom script",

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

@@ -669,6 +669,7 @@
     "update_behavior_success": "動作を更新しました",
     "update_function_success": "機能を更新しました",
     "update_highlight_success": "コードハイライトを更新しました",
+    "update_customTitle_success": "カスタムタイトルを更新しました",
     "update_customHeader_success": "カスタムHTMLヘッダーを更新しました",
     "update_customCss_success": "カスタムCSSを更新しました",
     "update_script_success": "カスタムスクリプトを更新しました",

+ 4 - 3
src/client/js/components/Admin/Customize/Customize.jsx

@@ -13,11 +13,11 @@ import CustomizeHighlightSetting from './CustomizeHighlightSetting';
 import CustomizeCssSetting from './CustomizeCssSetting';
 import CustomizeScriptSetting from './CustomizeScriptSetting';
 import CustomizeHeaderSetting from './CustomizeHeaderSetting';
+import CustomizeTitle from './CustomizeTitle';
 
 class Customize extends React.Component {
 
   render() {
-    const { t } = this.props;
 
     return (
       <Fragment>
@@ -33,8 +33,9 @@ class Customize extends React.Component {
         <div className="mb-5">
           <CustomizeHighlightSetting />
         </div>
-        <legend>{t('customize_page.custom_title')}</legend>
-        {/* カスタムタイトルフォームの react componentをここで呼ぶ(GW-278) */}
+        <div className="mb-5">
+          <CustomizeTitle />
+        </div>
         <div className="mb-5">
           <CustomizeHeaderSetting />
         </div>

+ 79 - 0
src/client/js/components/Admin/Customize/CustomizeTitle.jsx

@@ -0,0 +1,79 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { withTranslation } from 'react-i18next';
+
+import loggerFactory from '@alias/logger';
+
+import AppContainer from '../../../services/AppContainer';
+import AdminCustomizeContainer from '../../../services/AdminCustomizeContainer';
+import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
+import { createSubscribedElement } from '../../UnstatedUtils';
+import { toastSuccess, toastError } from '../../../util/apiNotification';
+
+const logger = loggerFactory('growi:Customize');
+
+class CustomizeTitle extends React.Component {
+
+  constructor(props) {
+    super(props);
+
+    this.onClickSubmit = this.onClickSubmit.bind(this);
+  }
+
+  async onClickSubmit() {
+    const { t, adminCustomizeContainer } = this.props;
+
+    try {
+      await adminCustomizeContainer.updateCustomizeTitle();
+      toastSuccess(t('customize_page.update_customTitle_success'));
+    }
+    catch (err) {
+      toastError(err);
+      logger.error(err);
+    }
+  }
+
+  render() {
+    const { t, adminCustomizeContainer } = this.props;
+    const { currentCustomizeTitle } = adminCustomizeContainer.state;
+
+    return (
+      <React.Fragment>
+        <h2 className="admin-setting-header">{t('customize_page.custom_title')}</h2>
+        <p
+          className="well"
+          // eslint-disable-next-line react/no-danger, max-len
+          dangerouslySetInnerHTML={{ __html: '<code>&lt;title&gt;</code>タグのコンテンツをカスタマイズできます。<br><code>&#123;&#123;sitename&#125;&#125;</code>がサイト名、<code>&#123;&#123;page&#125;&#125;</code>がページ名またはページパスに置換されます。' }}
+        />
+        {/* TODO i18n */}
+        <p className="help-block">
+          Default Value: <code>&#123;&#123;page&#125;&#125; - &#123;&#123;sitename&#125;&#125;</code>
+          <br />
+          Default Output: <pre><code className="xml">&lt;title&gt;/Sandbox - { 'GROWI' }&lt;&#047;title&gt;</code></pre>
+        </p>
+        <div className="form-group">
+          <input
+            className="form-control"
+            value={currentCustomizeTitle}
+            onChange={(e) => { adminCustomizeContainer.changeCustomizeTitle(e.target.value) }}
+          />
+        </div>
+
+        <AdminUpdateButtonRow onClick={this.onClickSubmit} />
+      </React.Fragment>
+    );
+  }
+
+}
+
+const CustomizeTitleWrapper = (props) => {
+  return createSubscribedElement(CustomizeTitle, props, [AppContainer, AdminCustomizeContainer]);
+};
+
+CustomizeTitle.propTypes = {
+  t: PropTypes.func.isRequired, // i18next
+  appContainer: PropTypes.instanceOf(AppContainer).isRequired,
+  adminCustomizeContainer: PropTypes.instanceOf(AdminCustomizeContainer).isRequired,
+};
+
+export default withTranslation()(CustomizeTitleWrapper);

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

@@ -162,6 +162,13 @@ export default class AdminCustomizeContainer extends Container {
     this.setState({ isHighlightJsStyleBorderEnabled: !this.state.isHighlightJsStyleBorderEnabled });
   }
 
+  /**
+   * Change customize Title
+   */
+  changeCustomizeTitle(inputValue) {
+    this.setState({ currentCustomizeTitle: inputValue });
+  }
+
   /**
    * Change customize Html header
    */
@@ -241,6 +248,19 @@ export default class AdminCustomizeContainer extends Container {
     return customizedParams;
   }
 
+  /**
+   * Update customTitle
+   * @memberOf AdminCustomizeContainer
+   * @return {string} Customize title
+   */
+  async updateCustomizeTitle() {
+    const response = await this.appContainer.apiv3.put('/customize-setting/customize-title', {
+      customizeTitle: this.state.currentCustomizeTitle,
+    });
+    const { customizedParams } = response.data;
+    return customizedParams;
+  }
+
   /**
    * Update customHeader
    * @memberOf AdminCustomizeContainer

+ 1 - 0
src/server/models/config.js

@@ -186,6 +186,7 @@ module.exports = function(crowi) {
       attrWhiteList: crowi.xssService.getAttrWhiteList(),
       highlightJsStyle: crowi.configManager.getConfig('crowi', 'customize:highlightJsStyle'),
       highlightJsStyleBorder: crowi.configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
+      customizeTitle: crowi.configManager.getConfig('crowi', 'customize:title'),
       customizeHeader: crowi.configManager.getConfig('crowi', 'customize:header'),
       customizeCss: crowi.configManager.getConfig('crowi', 'customize:css'),
       isSavedStatesOfTabChanges: crowi.configManager.getConfig('crowi', 'customize:isSavedStatesOfTabChanges'),

+ 47 - 0
src/server/routes/apiv3/customize-setting.js

@@ -49,6 +49,10 @@ const ErrorV3 = require('../../models/vo/error-apiv3');
  *                type: string
  *              styleBorder:
  *                type: boolean
+ *          CustomizeTitle:
+ *            type: object
+ *              customizeTitle:
+ *                type: string
  *          CustomizeHeader:
  *            type: object
  *              customizeHeader:
@@ -85,6 +89,9 @@ module.exports = (crowi) => {
       body('isEnabledAttachTitleHeader').isBoolean(),
       body('recentCreatedLimit').isInt().isInt({ min: 1, max: 1000 }),
     ],
+    customizeTitle: [
+      body('customizeTitle').isString(),
+    ],
     customizeHeader: [
       body('customizeHeader').isString(),
     ],
@@ -349,6 +356,46 @@ module.exports = (crowi) => {
     }
   });
 
+  /**
+   * @swagger
+   *
+   *    /customize-setting/customizeTitle:
+   *      put:
+   *        tags: [CustomizeSetting]
+   *        description: Update customizeTitle
+   *        requestBody:
+   *          required: true
+   *          content:
+   *            application/json:
+   *              schema:
+   *                type: object
+   *                properties:
+   *                  title:
+   *                    description: customized title
+   *                    type: string
+   *      responses:
+   *          200:
+   *            description: Succeeded to update customizeTitle
+   */
+  router.put('/customize-title', loginRequiredStrictly, adminRequired, csrf, validator.customizeTitle, ApiV3FormValidator, async(req, res) => {
+    const requestParams = {
+      'customize:title': req.body.customizeTitle,
+    };
+
+    try {
+      await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
+      const customizedParams = {
+        customizeTitle: await crowi.configManager.getConfig('crowi', 'customize:title'),
+      };
+      return res.apiv3({ customizedParams });
+    }
+    catch (err) {
+      const msg = 'Error occurred in updating customizeTitle';
+      logger.error('Error', err);
+      return res.apiv3Err(new ErrorV3(msg, 'update-customizeTitle-failed'));
+    }
+  });
+
   /**
    * @swagger
    *