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

Merge pull request #2703 from weseek/imprv/add-kibela-theme-option

Imprv/add kibela theme option
Yuki Takei 5 лет назад
Родитель
Сommit
7b52152d59

BIN
public/images/admin/customize/layout-classic-thumb.gif


BIN
public/images/admin/customize/layout-classic.gif


BIN
public/images/admin/customize/layout-crowi-plus-thumb.gif


BIN
public/images/admin/customize/layout-crowi-plus.gif


BIN
public/images/admin/customize/layout-kibela-thumb.gif


BIN
public/images/admin/customize/layout-kibela.gif


+ 0 - 12
resource/locales/en_US/admin/admin.json

@@ -89,19 +89,7 @@
     }
     }
   },
   },
   "customize_setting": {
   "customize_setting": {
-    "recommended": "Recommended",
-    "layout": "Layout",
     "theme": "Theme",
     "theme": "Theme",
-    "layout_desc": {
-      "growi_title": "Simple and clear",
-      "growi_text1": "Full screen layout and thin margins/paddings",
-      "growi_text2": "Show and post comments at the bottom of the page",
-      "growi_text3": "Affix table-of-contents",
-      "kibela_title": "Easy viewing structure",
-      "kibela_text1": "Center aligned contents",
-      "kibela_text2": "Show and post comments at the bottom of the page",
-      "kibela_text3": "Affix Table-of-contents"
-    },
     "theme_desc": {
     "theme_desc": {
       "light_and_dark": "Light and dark modes",
       "light_and_dark": "Light and dark modes",
       "unique": "Only one mode"
       "unique": "Only one mode"

+ 0 - 12
resource/locales/ja_JP/admin/admin.json

@@ -89,19 +89,7 @@
     }
     }
   },
   },
   "customize_setting": {
   "customize_setting": {
-    "recommended": "おすすめ",
-    "layout": "レイアウト",
     "theme": "テーマ",
     "theme": "テーマ",
-    "layout_desc": {
-      "growi_title": "シンプル・明瞭",
-      "growi_text1": "全画面レイアウトで、余白は少なくなります。",
-      "growi_text2": "コメントはページの下部に表示されます。",
-      "growi_text3": "ページ情報は下部に表示されます。",
-      "kibela_title": "閲覧重視の構造",
-      "kibela_text1": "コンテンツが中心に表示されます。",
-      "kibela_text2": "コメントはページの下部に表示されます。",
-      "kibela_text3": "ページ情報は下部に表示されます。"
-    },
     "theme_desc" : {
     "theme_desc" : {
       "light_and_dark": "Light/Dark モード選択あり",
       "light_and_dark": "Light/Dark モード選択あり",
       "unique": "モード選択なし"
       "unique": "モード選択なし"

+ 0 - 16
resource/locales/zh_CN/admin/admin.json

@@ -89,23 +89,7 @@
 		}
 		}
 	},
 	},
 	"customize_setting": {
 	"customize_setting": {
-		"recommended": "推荐",
-		"layout": "布局",
 		"theme": "主体",
 		"theme": "主体",
-		"layout_desc": {
-			"growi_title": "简约",
-			"growi_text1": "全屏布局 窄边距/填充",
-			"growi_text2": "页面底部显示和发布评论",
-			"growi_text3": "附目录",
-			"kibela_title": "清晰",
-			"kibela_text1": "内容居中对齐",
-			"kibela_text2": "在页面底部显示和发布评论",
-			"kibela_text3": "附目录",
-			"crowi_title": "分栏",
-			"crowi_text1": "可折叠边栏",
-			"crowi_text2": "在侧边栏中显示和发布评论",
-			"crowi_text3": "可折叠目录"
-		},
 		"behavior": "行为",
 		"behavior": "行为",
 		"behavior_desc": {
 		"behavior_desc": {
 			"growi_text1": "<code>/page</code> and <code>/page/</code> 都显示同一页。",
 			"growi_text1": "<code>/page</code> and <code>/page/</code> 都显示同一页。",

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

@@ -10,7 +10,7 @@ import { toastError } from '../../../util/apiNotification';
 import toArrayIfNot from '../../../../../lib/util/toArrayIfNot';
 import toArrayIfNot from '../../../../../lib/util/toArrayIfNot';
 import { withLoadingSppiner } from '../../SuspenseUtils';
 import { withLoadingSppiner } from '../../SuspenseUtils';
 
 
-import CustomizeLayoutSetting from './CustomizeLayoutSetting';
+import CustomizeLayoutSetting from './CustomizeThemeSetting';
 import CustomizeFunctionSetting from './CustomizeFunctionSetting';
 import CustomizeFunctionSetting from './CustomizeFunctionSetting';
 import CustomizeHighlightSetting from './CustomizeHighlightSetting';
 import CustomizeHighlightSetting from './CustomizeHighlightSetting';
 import CustomizeCssSetting from './CustomizeCssSetting';
 import CustomizeCssSetting from './CustomizeCssSetting';

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

@@ -1,48 +0,0 @@
-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 (
-      <React.Fragment>
-        <h4>
-          <div className="custom-control custom-radio">
-            <input
-              type="radio"
-              className="custom-control-input"
-              id={`radio-layout-${layoutType}`}
-              checked={this.props.isSelected}
-              onChange={this.props.onSelected}
-            />
-            <label className="custom-control-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}
-      </React.Fragment>
-    );
-  }
-
-}
-
-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);

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

@@ -1,67 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { withTranslation } from 'react-i18next';
-
-import { withUnstatedContainers } from '../../UnstatedUtils';
-import AdminCustomizeContainer from '../../../services/AdminCustomizeContainer';
-import AppContainer from '../../../services/AppContainer';
-
-import CustomizeLayoutOption from './CustomizeLayoutOption';
-
-class CustomizeLayoutOptions extends React.Component {
-
-  render() {
-    const { t, adminCustomizeContainer } = this.props;
-
-    return (
-      <div className="row row-cols-1 row-cols-md-2">
-        <div className="col text-center">
-          <CustomizeLayoutOption
-            layoutType="crowi-plus"
-            isSelected={adminCustomizeContainer.state.currentLayout === 'growi'}
-            onSelected={() => adminCustomizeContainer.switchLayoutType('growi')}
-            labelHtml={`GROWI enhanced layout <small class="text-success">${t('admin:customize_setting.recommended')}</small>`}
-          >
-            <h4>{t('admin:customize_setting.layout_desc.growi_title')}</h4>
-            <div className="text-justify d-inline-block">
-              <ul>
-                <li>{t('admin:customize_setting.layout_desc.growi_text1')}</li>
-                <li>{t('admin:customize_setting.layout_desc.growi_text2')}</li>
-                <li>{t('admin:customize_setting.layout_desc.growi_text3')}</li>
-              </ul>
-            </div>
-          </CustomizeLayoutOption>
-        </div>
-
-        <div className="col text-center">
-          <CustomizeLayoutOption
-            layoutType="kibela"
-            isSelected={adminCustomizeContainer.state.currentLayout === 'kibela'}
-            onSelected={() => adminCustomizeContainer.switchLayoutType('kibela')}
-            labelHtml="Kibela like layout"
-          >
-            <h4>{t('admin:customize_setting.layout_desc.kibela_title')}</h4>
-            <div className="text-justify d-inline-block">
-              <ul>
-                <li>{t('admin:customize_setting.layout_desc.kibela_text1')}</li>
-                <li>{t('admin:customize_setting.layout_desc.kibela_text2')}</li>
-                <li>{t('admin:customize_setting.layout_desc.kibela_text3')}</li>
-              </ul>
-            </div>
-          </CustomizeLayoutOption>
-        </div>
-      </div>
-    );
-  }
-
-}
-
-const CustomizeLayoutOptionsWrapper = withUnstatedContainers(CustomizeLayoutOptions, [AppContainer, AdminCustomizeContainer]);
-
-CustomizeLayoutOptions.propTypes = {
-  t: PropTypes.func.isRequired, // i18next
-  appContainer: PropTypes.instanceOf(AppContainer).isRequired,
-  adminCustomizeContainer: PropTypes.instanceOf(AdminCustomizeContainer).isRequired,
-};
-
-export default withTranslation()(CustomizeLayoutOptionsWrapper);

+ 2 - 0
src/client/js/components/Admin/Customize/CustomizeThemeOptions.jsx

@@ -38,6 +38,8 @@ class CustomizeThemeOptions extends React.Component {
       name: 'future',     bg: '#16282d', topbar: '#2a2929', sidebar: '#00b5b7', theme: '#00b5b7',
       name: 'future',     bg: '#16282d', topbar: '#2a2929', sidebar: '#00b5b7', theme: '#00b5b7',
     }, {
     }, {
       name: 'halloween',  bg: '#030003', topbar: '#aa4a04', sidebar: '#162b33', theme: '#e9af2b',
       name: 'halloween',  bg: '#030003', topbar: '#aa4a04', sidebar: '#162b33', theme: '#e9af2b',
+    }, {
+      name: 'kibela',  bg: '#f4f5f6', topbar: '#1256a3', sidebar: '#5882fa', theme: '#b5cbf79c',
     }];
     }];
     /* eslint-enable no-multi-spaces */
     /* eslint-enable no-multi-spaces */
 
 

+ 6 - 13
src/client/js/components/Admin/Customize/CustomizeLayoutSetting.jsx → src/client/js/components/Admin/Customize/CustomizeThemeSetting.jsx

@@ -7,12 +7,11 @@ import { toastSuccess, toastError } from '../../../util/apiNotification';
 
 
 import AppContainer from '../../../services/AppContainer';
 import AppContainer from '../../../services/AppContainer';
 
 
-import CustomizeLayoutOptions from './CustomizeLayoutOptions';
 import CustomizeThemeOptions from './CustomizeThemeOptions';
 import CustomizeThemeOptions from './CustomizeThemeOptions';
 import AdminCustomizeContainer from '../../../services/AdminCustomizeContainer';
 import AdminCustomizeContainer from '../../../services/AdminCustomizeContainer';
 import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
 import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
 
 
-class CustomizeLayoutSetting extends React.Component {
+class CustomizeThemeSetting extends React.Component {
 
 
   constructor(props) {
   constructor(props) {
     super(props);
     super(props);
@@ -24,8 +23,8 @@ class CustomizeLayoutSetting extends React.Component {
     const { t, adminCustomizeContainer } = this.props;
     const { t, adminCustomizeContainer } = this.props;
 
 
     try {
     try {
-      await adminCustomizeContainer.updateCustomizeLayoutAndTheme();
-      toastSuccess(t('toaster.update_successed', { target: t('admin:customize_setting.layout') }));
+      await adminCustomizeContainer.updateCustomizeTheme();
+      toastSuccess(t('toaster.update_successed', { target: t('admin:customize_setting.theme') }));
     }
     }
     catch (err) {
     catch (err) {
       toastError(err);
       toastError(err);
@@ -48,12 +47,6 @@ class CustomizeLayoutSetting extends React.Component {
 
 
     return (
     return (
       <React.Fragment>
       <React.Fragment>
-        <div className="row">
-          <div className="col-12">
-            <h2 className="admin-setting-header">{t('admin:customize_setting.layout')}</h2>
-            <CustomizeLayoutOptions />
-          </div>
-        </div>
         <div className="row">
         <div className="row">
           <div className="col-12">
           <div className="col-12">
             <h2 className="admin-setting-header">{t('admin:customize_setting.theme')}</h2>
             <h2 className="admin-setting-header">{t('admin:customize_setting.theme')}</h2>
@@ -68,12 +61,12 @@ class CustomizeLayoutSetting extends React.Component {
 
 
 }
 }
 
 
-const CustomizeLayoutSettingWrapper = withUnstatedContainers(CustomizeLayoutSetting, [AppContainer, AdminCustomizeContainer]);
+const CustomizeThemeSettingWrapper = withUnstatedContainers(CustomizeThemeSetting, [AppContainer, AdminCustomizeContainer]);
 
 
-CustomizeLayoutSetting.propTypes = {
+CustomizeThemeSetting.propTypes = {
   t: PropTypes.func.isRequired, // i18next
   t: PropTypes.func.isRequired, // i18next
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   adminCustomizeContainer: PropTypes.instanceOf(AdminCustomizeContainer).isRequired,
   adminCustomizeContainer: PropTypes.instanceOf(AdminCustomizeContainer).isRequired,
 };
 };
 
 
-export default withTranslation()(CustomizeLayoutSettingWrapper);
+export default withTranslation()(CustomizeThemeSettingWrapper);

+ 4 - 19
src/client/js/services/AdminCustomizeContainer.js

@@ -24,7 +24,6 @@ export default class AdminCustomizeContainer extends Container {
       retrieveError: null,
       retrieveError: null,
       // set dummy value tile for using suspense
       // set dummy value tile for using suspense
       currentTheme: this.dummyCurrentTheme,
       currentTheme: this.dummyCurrentTheme,
-      currentLayout: '',
       isEnabledTimeline: false,
       isEnabledTimeline: false,
       isSavedStatesOfTabChanges: false,
       isSavedStatesOfTabChanges: false,
       isEnabledAttachTitleHeader: false,
       isEnabledAttachTitleHeader: false,
@@ -72,7 +71,6 @@ export default class AdminCustomizeContainer extends Container {
 
 
       this.setState({
       this.setState({
         currentTheme: customizeParams.themeType,
         currentTheme: customizeParams.themeType,
-        currentLayout: customizeParams.layoutType,
         isEnabledTimeline: customizeParams.isEnabledTimeline,
         isEnabledTimeline: customizeParams.isEnabledTimeline,
         isSavedStatesOfTabChanges: customizeParams.isSavedStatesOfTabChanges,
         isSavedStatesOfTabChanges: customizeParams.isSavedStatesOfTabChanges,
         isEnabledAttachTitleHeader: customizeParams.isEnabledAttachTitleHeader,
         isEnabledAttachTitleHeader: customizeParams.isEnabledAttachTitleHeader,
@@ -97,21 +95,10 @@ export default class AdminCustomizeContainer extends Container {
     }
     }
   }
   }
 
 
-  /**
-   * Switch layoutType
-   */
-  switchLayoutType(lauoutName) {
-    this.setState({ currentLayout: lauoutName });
-  }
-
   /**
   /**
    * Switch themeType
    * Switch themeType
    */
    */
   switchThemeType(themeName) {
   switchThemeType(themeName) {
-    // can't choose theme when kibela
-    if (this.state.currentLayout === 'kibela') {
-      return;
-    }
     this.setState({ currentTheme: themeName });
     this.setState({ currentTheme: themeName });
 
 
     // preview if production
     // preview if production
@@ -216,7 +203,7 @@ export default class AdminCustomizeContainer extends Container {
   async previewTheme(themeName) {
   async previewTheme(themeName) {
     try {
     try {
       // get theme asset path
       // get theme asset path
-      const response = await this.appContainer.apiv3.get('/customize-setting/layout-theme/asset-path', { themeName });
+      const response = await this.appContainer.apiv3.get('/customize-setting/theme/asset-path', { themeName });
       const { assetPath } = response.data;
       const { assetPath } = response.data;
 
 
       const themeLink = document.getElementById('grw-theme-link');
       const themeLink = document.getElementById('grw-theme-link');
@@ -239,18 +226,16 @@ export default class AdminCustomizeContainer extends Container {
   }
   }
 
 
   /**
   /**
-   * Update layout
+   * Update theme
    * @memberOf AdminCustomizeContainer
    * @memberOf AdminCustomizeContainer
    */
    */
-  async updateCustomizeLayoutAndTheme() {
+  async updateCustomizeTheme() {
     try {
     try {
-      const response = await this.appContainer.apiv3.put('/customize-setting/layout-theme', {
-        layoutType: this.state.currentLayout,
+      const response = await this.appContainer.apiv3.put('/customize-setting/theme', {
         themeType: this.state.currentTheme,
         themeType: this.state.currentTheme,
       });
       });
       const { customizedParams } = response.data;
       const { customizedParams } = response.data;
       this.setState({
       this.setState({
-        layoutType: customizedParams.layoutType,
         themeType: customizedParams.themeType,
         themeType: customizedParams.themeType,
       });
       });
     }
     }

+ 21 - 26
src/server/routes/apiv3/customize-setting.js

@@ -21,12 +21,10 @@ const ErrorV3 = require('../../models/vo/error-apiv3');
  *
  *
  *  components:
  *  components:
  *    schemas:
  *    schemas:
- *      CustomizeLayoutTheme:
- *        description: CustomizeLayoutTheme
+ *      CustomizeTheme:
+ *        description: CustomizeTheme
  *        type: object
  *        type: object
  *        properties:
  *        properties:
- *          layoutType:
- *            type: string
  *          themeType:
  *          themeType:
  *            type: string
  *            type: string
  *      CustomizeFunction:
  *      CustomizeFunction:
@@ -92,10 +90,9 @@ module.exports = (crowi) => {
         'default', 'nature', 'mono-blue', 'wood', 'island', 'christmas', 'antarctic', 'future', 'halloween', 'spring',
         'default', 'nature', 'mono-blue', 'wood', 'island', 'christmas', 'antarctic', 'future', 'halloween', 'spring',
       ]),
       ]),
     ],
     ],
-    layoutTheme: [
-      body('layoutType').isString().isIn(['growi', 'kibela']),
+    theme: [
       body('themeType').isString().isIn([
       body('themeType').isString().isIn([
-        'default', 'nature', 'mono-blue', 'wood', 'island', 'christmas', 'antarctic', 'future', 'halloween', 'spring',
+        'default', 'nature', 'mono-blue', 'wood', 'island', 'christmas', 'antarctic', 'future', 'halloween', 'spring', 'kibela',
       ]),
       ]),
     ],
     ],
     function: [
     function: [
@@ -171,12 +168,12 @@ module.exports = (crowi) => {
   /**
   /**
    * @swagger
    * @swagger
    *
    *
-   *    /customize-setting/layout-theme/asset-path:
+   *    /customize-setting/theme/asset-path:
    *      put:
    *      put:
    *        tags: [CustomizeSetting]
    *        tags: [CustomizeSetting]
-   *        operationId: getLayoutThemeAssetPath
-   *        summary: /customize-setting/layout-theme/asset-path
-   *        description: Get layout theme asset path
+   *        operationId: getThemeAssetPath
+   *        summary: /customize-setting/theme/asset-path
+   *        description: Get theme asset path
    *        parameters:
    *        parameters:
    *          - name: themeName
    *          - name: themeName
    *            in: query
    *            in: query
@@ -185,7 +182,7 @@ module.exports = (crowi) => {
    *              type: string
    *              type: string
    *        responses:
    *        responses:
    *          200:
    *          200:
-   *            description: Succeeded to update layout and theme
+   *            description: Succeeded to get theme asset path
    *            content:
    *            content:
    *              application/json:
    *              application/json:
    *                schema:
    *                schema:
@@ -193,8 +190,8 @@ module.exports = (crowi) => {
    *                    assetPath:
    *                    assetPath:
    *                      type: string
    *                      type: string
    */
    */
-  router.get('/layout-theme/asset-path', loginRequiredStrictly, adminRequired, validator.themeAssetPath, apiV3FormValidator, async(req, res) => {
-    const themeName = req.query.themeName;
+  router.get('/theme/asset-path', loginRequiredStrictly, adminRequired, validator.themeAssetPath, apiV3FormValidator, async(req, res) => {
+    const { themeName } = req.query;
 
 
     const webpackAssetKey = `styles/theme-${themeName}.css`;
     const webpackAssetKey = `styles/theme-${themeName}.css`;
     const assetPath = res.locals.webpack_asset(webpackAssetKey);
     const assetPath = res.locals.webpack_asset(webpackAssetKey);
@@ -209,44 +206,42 @@ module.exports = (crowi) => {
   /**
   /**
    * @swagger
    * @swagger
    *
    *
-   *    /customize-setting/layout-theme:
+   *    /customize-setting/theme:
    *      put:
    *      put:
    *        tags: [CustomizeSetting]
    *        tags: [CustomizeSetting]
-   *        operationId: updateLayoutThemeCustomizeSetting
-   *        summary: /customize-setting/layout-theme
-   *        description: Update layout and theme
+   *        operationId: updateThemeCustomizeSetting
+   *        summary: /customize-setting/theme
+   *        description: Update theme
    *        requestBody:
    *        requestBody:
    *          required: true
    *          required: true
    *          content:
    *          content:
    *            application/json:
    *            application/json:
    *              schema:
    *              schema:
-   *                $ref: '#/components/schemas/CustomizeLayoutTheme'
+   *                $ref: '#/components/schemas/CustomizeTheme'
    *        responses:
    *        responses:
    *          200:
    *          200:
-   *            description: Succeeded to update layout and theme
+   *            description: Succeeded to update theme
    *            content:
    *            content:
    *              application/json:
    *              application/json:
    *                schema:
    *                schema:
-   *                  $ref: '#/components/schemas/CustomizeLayoutTheme'
+   *                  $ref: '#/components/schemas/CustomizeTheme'
    */
    */
-  router.put('/layout-theme', loginRequiredStrictly, adminRequired, csrf, validator.layoutTheme, apiV3FormValidator, async(req, res) => {
+  router.put('/theme', loginRequiredStrictly, adminRequired, csrf, validator.theme, apiV3FormValidator, async(req, res) => {
     const requestParams = {
     const requestParams = {
-      'customize:layout': req.body.layoutType,
       'customize:theme': req.body.themeType,
       'customize:theme': req.body.themeType,
     };
     };
 
 
     try {
     try {
       await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
       await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
       const customizedParams = {
       const customizedParams = {
-        layoutType: await crowi.configManager.getConfig('crowi', 'customize:layout'),
         themeType: await crowi.configManager.getConfig('crowi', 'customize:theme'),
         themeType: await crowi.configManager.getConfig('crowi', 'customize:theme'),
       };
       };
       return res.apiv3({ customizedParams });
       return res.apiv3({ customizedParams });
     }
     }
     catch (err) {
     catch (err) {
-      const msg = 'Error occurred in updating layout and theme';
+      const msg = 'Error occurred in updating theme';
       logger.error('Error', err);
       logger.error('Error', err);
-      return res.apiv3Err(new ErrorV3(msg, 'update-layoutTheme-failed'));
+      return res.apiv3Err(new ErrorV3(msg, 'update-theme-failed'));
     }
     }
   });
   });