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

store and retrieve attachment in logo setting

https://youtrack.weseek.co.jp/issue/GW-7772
- Add attachment type in attachment model
- Define attachment id key in config
- Modify  upload attachment function
- Add upload attachment api route
- Modify create attachment function
- Modify onChange handler on update button
I Komang Mudana 4 лет назад
Родитель
Сommit
dd2e10fb0f

+ 17 - 10
packages/app/src/client/services/AdminCustomizeContainer.js

@@ -59,8 +59,8 @@ export default class AdminCustomizeContainer extends Container {
       uploadedLogoSrc: this.getUploadedLogoSrc(),
       isUploadedLogo: false,
       defaultLogoSrc: DEFAULT_LOGO,
-      currentLogo: '',
       isDefaultLogo: false,
+      attachmentId: '',
       /* eslint-enable quote-props, no-multi-spaces */
     };
     this.switchPageListLimitationS = this.switchPageListLimitationS.bind(this);
@@ -106,10 +106,10 @@ export default class AdminCustomizeContainer extends Container {
         currentCustomizeHeader: customizeParams.customizeHeader,
         currentCustomizeCss: customizeParams.customizeCss,
         currentCustomizeScript: customizeParams.customizeScript,
-        currentLogo: customizeParams.currentLogo,
+        attachmentId: customizeParams.attachmentId,
         isDefaultLogo: customizeParams.isDefaultLogo,
       });
-
+      console.log(this.state);
       // search style name from object for display
       this.setState({ currentHighlightJsStyleName: this.state.highlightJsCssSelectorOptions[customizeParams.styleName].name });
     }
@@ -462,30 +462,37 @@ export default class AdminCustomizeContainer extends Container {
       const formData = new FormData();
       formData.append('file', file);
       formData.append('_csrf', this.appContainer.csrfToken);
-      // const response = await this.appContainer.apiPost('/attachments.uploadProfileImage', formData);
-      // this.setState({ isUploadedLogo: true, uploadedLogoSrc: response.attachment.filePathProxied });
+      formData.append('attachmentType', 'BRAND_LOGO');
+      formData.append('attachmentId', this.state.attachmentId);
+      const response = await this.appContainer.apiPost('/attachments.uploadBrandLogo', formData);
+
+      this.setState({
+        isUploadedLogo: true,
+        uploadedLogoSrc: response.attachment.filePathProxied,
+        attachmentId: response.attachment.id,
+      });
     }
     catch (err) {
       this.setState({ retrieveError: err });
       logger.error(err);
-      throw new Error('Failed to upload profile image');
+      throw new Error('Failed to upload brand logo');
     }
   }
 
-  async changeIsDefaultLogoEnabled(boolean) {
-    this.setState({ isDefaultLogo: boolean });
+  switchDefaultLogo() {
+    this.setState({ isDefaultLogo: !this.state.isDefaultLogo });
   }
 
   async updateCustomizeLogo() {
     try {
       const response = await this.appContainer.apiv3.put('/customize-setting/customize-logo', {
         isDefaultLogo: this.state.isDefaultLogo,
-        currentLogo: this.state.currentLogo,
+        attachmentId: this.state.attachmentId,
       });
       const { customizedParams } = response.data;
       this.setState({
         isDefaultLogo: customizedParams.isDefaultLogo,
-        currentLogo: customizedParams.currentLogo,
+        attachmentId:  customizedParams.attachmentId,
       });
     }
     catch (err) {

+ 1 - 0
packages/app/src/client/services/PersonalContainer.js

@@ -204,6 +204,7 @@ export default class PersonalContainer extends Container {
       const formData = new FormData();
       formData.append('file', file);
       formData.append('_csrf', this.appContainer.csrfToken);
+      formData.append('attachmentType', 'PROFILE_IMAGE');
       const response = await this.appContainer.apiPost('/attachments.uploadProfileImage', formData);
       this.setState({ isUploadedPicture: true, uploadedPictureSrc: response.attachment.filePathProxied });
     }

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

@@ -99,7 +99,7 @@ class CustomizeLogoSetting extends React.Component {
                       form="formImageType"
                       name="imagetypeForm[isDefaultLogo]"
                       checked={isDefaultLogo}
-                      onChange={() => { adminCustomizeContainer.changeIsDefaultLogoEnabled(true) }}
+                      onChange={() => { adminCustomizeContainer.switchDefaultLogo() }}
                     />
                     <label className="custom-control-label" htmlFor="radioDefaultLogo">
                       Default Logo
@@ -118,7 +118,7 @@ class CustomizeLogoSetting extends React.Component {
                       form="formImageType"
                       name="imagetypeForm[isDefaultLogo]"
                       checked={!isDefaultLogo}
-                      onChange={() => { adminCustomizeContainer.changeIsDefaultLogoEnabled(false) }}
+                      onChange={() => { adminCustomizeContainer.switchDefaultLogo() }}
                     />
                     <label className="custom-control-label" htmlFor="radioUploadLogo">
                       { t('Upload Logo') }

+ 7 - 2
packages/app/src/server/models/attachment.js

@@ -35,6 +35,11 @@ module.exports = function(crowi) {
     createdAt: { type: Date, default: Date.now },
     temporaryUrlCached: { type: String },
     temporaryUrlExpiredAt: { type: Date },
+    attachmentType: {
+      type: String,
+      enum: ['BRAND_LOGO', 'WIKI_PAGE', 'USER_PAGE', 'PROFILE_IMAGE', null],
+      default: null,
+    },
   });
   attachmentSchema.plugin(uniqueValidator);
   attachmentSchema.plugin(mongoosePaginate);
@@ -51,7 +56,7 @@ module.exports = function(crowi) {
   attachmentSchema.set('toJSON', { virtuals: true });
 
 
-  attachmentSchema.statics.createWithoutSave = function(pageId, user, fileStream, originalName, fileFormat, fileSize) {
+  attachmentSchema.statics.createWithoutSave = function(pageId, user, fileStream, originalName, fileFormat, fileSize, attachmentType = null) {
     const Attachment = this;
 
     const extname = path.extname(originalName);
@@ -68,7 +73,7 @@ module.exports = function(crowi) {
     attachment.fileFormat = fileFormat;
     attachment.fileSize = fileSize;
     attachment.createdAt = Date.now();
-
+    attachment.attachmentType = attachmentType;
     return attachment;
   };
 

+ 3 - 1
packages/app/src/server/models/config.ts

@@ -135,7 +135,7 @@ export const defaultCrowiConfigs: { [key: string]: any } = {
   'customize:isEnabledStaleNotification': false,
   'customize:isAllReplyShown': false,
   'customize:isSearchScopeChildrenAsDefault': false,
-  'customize:currentLogo': '/images/logo.svg',
+  'customize:attachmentId' : '',
   'customize:isDefaultLogo': true,
 
   'notification:owner-page:isEnabled': false,
@@ -244,6 +244,8 @@ schema.statics.getLocalconfig = function(crowi) {
     globalLang: crowi.configManager.getConfig('crowi', 'app:globalLang'),
     pageLimitationL: crowi.configManager.getConfig('crowi', 'customize:showPageLimitationL'),
     pageLimitationXL: crowi.configManager.getConfig('crowi', 'customize:showPageLimitationXL'),
+    isDefaultLogo:  crowi.configManager.getConfig('crowi', 'customize:isDefaultLogo'),
+    attachmentId: crowi.configManager.getConfig('crowi', 'customize:attachmentId'),
   };
 
   return localConfig;

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

@@ -136,7 +136,7 @@ module.exports = (crowi) => {
       body('customizeScript').isString(),
     ],
     logo: [
-      body('currentLogo').isString(),
+      body('attachmentId').isString(),
       body('isDefaultLogo').isBoolean(),
     ],
   };
@@ -181,7 +181,7 @@ module.exports = (crowi) => {
       customizeHeader: await crowi.configManager.getConfig('crowi', 'customize:header'),
       customizeCss: await crowi.configManager.getConfig('crowi', 'customize:css'),
       customizeScript: await crowi.configManager.getConfig('crowi', 'customize:script'),
-      currentLogo: await crowi.configManager.getConfig('crowi', 'customize:currentLogo'),
+      attachmentId: await crowi.configManager.getConfig('crowi', 'customize:attachmentId'),
       isDefaultLogo: await crowi.configManager.getConfig('crowi', 'customize:isDefaultLogo'),
     };
 
@@ -617,13 +617,13 @@ module.exports = (crowi) => {
 
   router.put('/customize-logo', loginRequiredStrictly, adminRequired, csrf, validator.logo, apiV3FormValidator, async(req, res) => {
     const requestParams = {
-      'customize:currentLogo': req.body.currentLogo,
+      'customize:attachmentId': req.body.attachmentId,
       'customize:isDefaultLogo': req.body.isDefaultLogo,
     };
     try {
       await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
       const customizedParams = {
-        currentLogo: await crowi.configManager.getConfig('crowi', 'customize:currentLogo'),
+        attachmentId: await crowi.configManager.getConfig('crowi', 'customize:attachmentId'),
         isDefaultLogo: await crowi.configManager.getConfig('crowi', 'customize:isDefaultLogo'),
       };
       return res.apiv3({ customizedParams });

+ 37 - 2
packages/app/src/server/routes/attachment.js

@@ -550,7 +550,7 @@ module.exports = function(crowi, app) {
     }
 
     const file = req.file;
-
+    const attachmentType = req.body.attachmentType;
     // check type
     const acceptableFileType = /image\/.+/;
     if (!file.mimetype.match(acceptableFileType)) {
@@ -560,7 +560,7 @@ module.exports = function(crowi, app) {
     let attachment;
     try {
       req.user.deleteImage();
-      attachment = await attachmentService.createAttachment(file, req.user);
+      attachment = await attachmentService.createAttachment(file, req.user, null, attachmentType);
       await req.user.updateImage(attachment);
     }
     catch (err) {
@@ -699,5 +699,40 @@ module.exports = function(crowi, app) {
     return res.json(ApiResponse.success({}));
   };
 
+  api.uploadBrandLogo = async function(req, res) {
+    // check params
+    if (!req.file) {
+      return res.json(ApiResponse.error('File error.'));
+    }
+    if (!req.user) {
+      return res.json(ApiResponse.error('param "user" must be set.'));
+    }
+
+    const file = req.file;
+    const attachmentType = req.body.attachmentType;
+    const attachmentId = req.body.attachmentId;
+    console.log(attachmentId);
+    // check type
+    const acceptableFileType = /image\/.+/;
+    if (!file.mimetype.match(acceptableFileType)) {
+      return res.json(ApiResponse.error('File type error. Only image files is allowed to set as user picture.'));
+    }
+
+    let attachment;
+    try {
+      attachment = await attachmentService.createAttachment(file, req.user, null, attachmentType);
+    }
+    catch (err) {
+      logger.error(err);
+      return res.json(ApiResponse.error(err.message));
+    }
+
+    const result = {
+      attachment: attachment.toObject({ virtuals: true }),
+    };
+
+    return res.json(ApiResponse.success(result));
+  };
+
   return actions;
 };

+ 1 - 0
packages/app/src/server/routes/index.js

@@ -188,6 +188,7 @@ module.exports = function(crowi, app) {
   apiV1Router.post('/attachments.remove'               , accessTokenParser , loginRequiredStrictly , csrf, attachment.api.remove);
   apiV1Router.post('/attachments.removeProfileImage'   , accessTokenParser , loginRequiredStrictly , csrf, attachment.api.removeProfileImage);
   apiV1Router.get('/attachments.limit'   , accessTokenParser , loginRequiredStrictly, attachment.api.limit);
+  apiV1Router.post('/attachments.uploadBrandLogo'   , uploads.single('file'), autoReap, accessTokenParser, loginRequiredStrictly ,csrf, attachment.api.uploadBrandLogo);
 
   // API v1
   app.use('/_api', unavailableWhenMaintenanceModeForApi, apiV1Router);

+ 2 - 2
packages/app/src/server/service/attachment.js

@@ -15,7 +15,7 @@ class AttachmentService {
     this.crowi = crowi;
   }
 
-  async createAttachment(file, user, pageId = null) {
+  async createAttachment(file, user, pageId = null, attachmentType = null) {
     const { fileUploadService } = this.crowi;
 
     // check limit
@@ -33,7 +33,7 @@ class AttachmentService {
     // create an Attachment document and upload file
     let attachment;
     try {
-      attachment = Attachment.createWithoutSave(pageId, user, fileStream, file.originalname, file.mimetype, file.size);
+      attachment = Attachment.createWithoutSave(pageId, user, fileStream, file.originalname, file.mimetype, file.size, attachmentType);
       await fileUploadService.uploadFile(fileStream, attachment);
       await attachment.save();
     }