Ver Fonte

Implement logo source on navbar

https://youtrack.weseek.co.jp/issue/GW-7772
- Add component for navbar logo
- Add uploadedLogoSrc to config
- Force default logo if uploaded logo is empty
- Adjust translation for customize logo component
I Komang Mudana há 4 anos atrás
pai
commit
b391e2a2d0

+ 2 - 1
packages/app/resource/locales/en_US/admin/admin.json

@@ -200,7 +200,8 @@
     "ctrl_space": "Ctrl+Space to autocomplete",
     "ctrl_space": "Ctrl+Space to autocomplete",
     "custom_script": "Custom script",
     "custom_script": "Custom script",
     "write_java": "You can write Javascript that is applied to whole system.",
     "write_java": "You can write Javascript that is applied to whole system.",
-    "reflect_change": "You need to reload the page to reflect the change."
+    "reflect_change": "You need to reload the page to reflect the change.",
+    "custom_logo" : "Custom Logo"
   },
   },
   "importer_management": {
   "importer_management": {
     "beta_warning": "This function is Beta.",
     "beta_warning": "This function is Beta.",

+ 2 - 1
packages/app/resource/locales/ja_JP/admin/admin.json

@@ -200,7 +200,8 @@
     "ctrl_space": "Ctrl+Space でコード補完",
     "ctrl_space": "Ctrl+Space でコード補完",
     "custom_script": "カスタムスクリプト",
     "custom_script": "カスタムスクリプト",
     "write_java": "システム全体に適用されるJavaScriptを記述できます。",
     "write_java": "システム全体に適用されるJavaScriptを記述できます。",
-    "reflect_change": "変更の反映はページの更新が必要です。"
+    "reflect_change": "変更の反映はページの更新が必要です。",
+    "custom_logo": "カスタムロゴ"
   },
   },
   "export_management": {
   "export_management": {
     "exporting_collection_list": "エクスポート中のコレクション",
     "exporting_collection_list": "エクスポート中のコレクション",

+ 2 - 1
packages/app/resource/locales/zh_CN/admin/admin.json

@@ -210,7 +210,8 @@
     "ctrl_space": "Ctrl+Space 自动完成",
     "ctrl_space": "Ctrl+Space 自动完成",
     "custom_script": "定制纸条",
     "custom_script": "定制纸条",
     "write_java": "您可以编写应用于整个系统的Javascript。",
     "write_java": "您可以编写应用于整个系统的Javascript。",
-    "reflect_change": "您需要重新加载页面以反映更改。"
+    "reflect_change": "您需要重新加载页面以反映更改。",
+    "custom_logo": "自定义徽标"
   },
   },
   "importer_management": {
   "importer_management": {
     "beta_warning": "这个函数是Beta。",
     "beta_warning": "这个函数是Beta。",

+ 7 - 2
packages/app/src/client/services/AdminCustomizeContainer.js

@@ -458,8 +458,13 @@ export default class AdminCustomizeContainer extends Container {
         attachmentId: this.state.attachmentId,
         attachmentId: this.state.attachmentId,
       };
       };
       await this.appContainer.apiPost('/attachments.removeBrandLogo', formData);
       await this.appContainer.apiPost('/attachments.removeBrandLogo', formData);
-      this.setState({ isUploadedLogo: false, uploadedLogoSrc: DEFAULT_LOGO });
-      this.setState({ attachmentId: null });
+      this.setState({
+        isUploadedLogo: false,
+        uploadedLogoSrc: DEFAULT_LOGO,
+        attachmentId: null,
+        isDefaultLogo: true,
+      });
+
     }
     }
     catch (err) {
     catch (err) {
       this.setState({ retrieveError: err });
       this.setState({ retrieveError: err });

+ 2 - 2
packages/app/src/components/Admin/Customize/CustomizeLogoSetting.jsx

@@ -44,7 +44,7 @@ class CustomizeLogoSetting extends React.Component {
 
 
     try {
     try {
       await adminCustomizeContainer.updateCustomizeLogo();
       await adminCustomizeContainer.updateCustomizeLogo();
-      toastSuccess(t('toaster.update_successed', { target: t('admin:customize_setting.custom_script') }));
+      toastSuccess(t('toaster.update_successed', { target: t('admin:customize_setting.custom_logo') }));
     }
     }
     catch (err) {
     catch (err) {
       toastError(err);
       toastError(err);
@@ -93,7 +93,7 @@ class CustomizeLogoSetting extends React.Component {
       <React.Fragment>
       <React.Fragment>
         <div className="row">
         <div className="row">
           <div className="col-12">
           <div className="col-12">
-            <h2 className="admin-setting-header">{t('admin:customize_setting.custom_script')}</h2>
+            <h2 className="admin-setting-header">{t('admin:customize_setting.custom_logo')}</h2>
             <div className="row">
             <div className="row">
               <div className="col-md-6 col-12">
               <div className="col-md-6 col-12">
                 <h4>
                 <h4>

+ 17 - 4
packages/app/src/components/Navbar/GrowiNavbar.tsx

@@ -14,6 +14,7 @@ import { useIsSearchPage, useCurrentPagePath } from '~/stores/context';
 import { withUnstatedContainers } from '../UnstatedUtils';
 import { withUnstatedContainers } from '../UnstatedUtils';
 import GrowiLogo from '../Icons/GrowiLogo';
 import GrowiLogo from '../Icons/GrowiLogo';
 
 
+
 import PersonalDropdown from './PersonalDropdown';
 import PersonalDropdown from './PersonalDropdown';
 import GlobalSearch from './GlobalSearch';
 import GlobalSearch from './GlobalSearch';
 import InAppNotificationDropdown from '../InAppNotification/InAppNotificationDropdown';
 import InAppNotificationDropdown from '../InAppNotification/InAppNotificationDropdown';
@@ -86,22 +87,34 @@ const Confidential: FC<ConfidentialProps> = memo((props: ConfidentialProps) => {
   );
   );
 });
 });
 
 
+interface NavbarLogoProps {
+  logoSrc?: string,
+}
+const GrowiNavbarLogo: FC<NavbarLogoProps> = memo((props: NavbarLogoProps) => {
+
+  const { logoSrc } = props;
+  return logoSrc
+    ? (<img src={logoSrc} className="picture picture-lg " id="settingBrandLogo" width="32" />)
+    : <GrowiLogo />;
+
+});
 
 
 const GrowiNavbar = (props) => {
 const GrowiNavbar = (props) => {
 
 
   const { appContainer } = props;
   const { appContainer } = props;
   const { currentUser } = appContainer;
   const { currentUser } = appContainer;
-  const { crowi, isSearchServiceConfigured } = appContainer.config;
-
+  const {
+    crowi, isSearchServiceConfigured, isDefaultLogo, uploadedLogoSrc,
+  } = appContainer.config;
   const { data: isDeviceSmallerThanMd } = useIsDeviceSmallerThanMd();
   const { data: isDeviceSmallerThanMd } = useIsDeviceSmallerThanMd();
   const { data: isSearchPage } = useIsSearchPage();
   const { data: isSearchPage } = useIsSearchPage();
-
+  const logoSrc = !isDefaultLogo ? uploadedLogoSrc : null;
   return (
   return (
     <>
     <>
       {/* Brand Logo  */}
       {/* Brand Logo  */}
       <div className="navbar-brand mr-0">
       <div className="navbar-brand mr-0">
         <a className="grw-logo d-block" href="/">
         <a className="grw-logo d-block" href="/">
-          <GrowiLogo />
+          <GrowiNavbarLogo logoSrc={...logoSrc} />
         </a>
         </a>
       </div>
       </div>
 
 

+ 2 - 0
packages/app/src/server/models/config.ts

@@ -137,6 +137,7 @@ export const defaultCrowiConfigs: { [key: string]: any } = {
   'customize:isSearchScopeChildrenAsDefault': false,
   'customize:isSearchScopeChildrenAsDefault': false,
   'customize:attachmentLogoId' : undefined,
   'customize:attachmentLogoId' : undefined,
   'customize:isDefaultLogo': true,
   'customize:isDefaultLogo': true,
+  'customize:uploadedLogoSrc': undefined,
 
 
   'notification:owner-page:isEnabled': false,
   'notification:owner-page:isEnabled': false,
   'notification:group-page:isEnabled': false,
   'notification:group-page:isEnabled': false,
@@ -246,6 +247,7 @@ schema.statics.getLocalconfig = function(crowi) {
     pageLimitationXL: crowi.configManager.getConfig('crowi', 'customize:showPageLimitationXL'),
     pageLimitationXL: crowi.configManager.getConfig('crowi', 'customize:showPageLimitationXL'),
     isDefaultLogo:  crowi.configManager.getConfig('crowi', 'customize:isDefaultLogo'),
     isDefaultLogo:  crowi.configManager.getConfig('crowi', 'customize:isDefaultLogo'),
     attachmentLogoId: crowi.configManager.getConfig('crowi', 'customize:attachmentLogoId'),
     attachmentLogoId: crowi.configManager.getConfig('crowi', 'customize:attachmentLogoId'),
+    uploadedLogoSrc: crowi.configManager.getConfig('crowi', 'customize:uploadedLogoSrc'),
   };
   };
 
 
   return localConfig;
   return localConfig;

+ 4 - 1
packages/app/src/server/routes/apiv3/customize-setting.js

@@ -616,9 +616,12 @@ module.exports = (crowi) => {
   });
   });
 
 
   router.put('/customize-logo', loginRequiredStrictly, adminRequired, csrf, validator.logo, apiV3FormValidator, async(req, res) => {
   router.put('/customize-logo', loginRequiredStrictly, adminRequired, csrf, validator.logo, apiV3FormValidator, async(req, res) => {
+
+    // Set default logo when uploaded logo is empty
+    const isDefaultLogo = req.body.attachmentId ? req.body.isDefaultLogo : true;
     const requestParams = {
     const requestParams = {
       'customize:attachmentLogoId': req.body.attachmentId,
       'customize:attachmentLogoId': req.body.attachmentId,
-      'customize:isDefaultLogo': req.body.isDefaultLogo,
+      'customize:isDefaultLogo': isDefaultLogo,
     };
     };
     try {
     try {
       await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
       await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);

+ 10 - 1
packages/app/src/server/routes/attachment.js

@@ -725,6 +725,11 @@ module.exports = function(crowi, app) {
     let attachment;
     let attachment;
     try {
     try {
       attachment = await attachmentService.createAttachment(file, req.user, null, attachmentType);
       attachment = await attachmentService.createAttachment(file, req.user, null, attachmentType);
+      const attachmentConfigParams = {
+        'customize:attachmentLogoId': attachment.id,
+        'customize:uploadedLogoSrc': attachment.filePathProxied,
+      };
+      await crowi.configManager.updateConfigsInTheSameNamespace('crowi', attachmentConfigParams);
     }
     }
     catch (err) {
     catch (err) {
       logger.error(err);
       logger.error(err);
@@ -749,7 +754,11 @@ module.exports = function(crowi, app) {
     try {
     try {
       await attachmentService.removeAttachment(attachmentId);
       await attachmentService.removeAttachment(attachmentId);
       // update attachmentLogoId immediately
       // update attachmentLogoId immediately
-      await crowi.configManager.updateConfigsInTheSameNamespace('crowi', { 'customize:attachmentLogoId': null });
+      const attachmentConfigParams = {
+        'customize:attachmentLogoId': null,
+        'customize:isDefaultLogo': true,
+      };
+      await crowi.configManager.updateConfigsInTheSameNamespace('crowi', attachmentConfigParams);
     }
     }
     catch (err) {
     catch (err) {
       logger.error(err);
       logger.error(err);