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

Merge pull request #1711 from weseek/feat/create-apiV3-update-notification-config

Feat/create api v3 update notification config
itizawa 6 лет назад
Родитель
Сommit
0f06042f18

+ 43 - 0
src/client/js/components/Admin/Notification/GlobalNotification.jsx

@@ -2,20 +2,63 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { withTranslation } from 'react-i18next';
 
+import loggerFactory from '@alias/logger';
+
 import { createSubscribedElement } from '../../UnstatedUtils';
+import { toastSuccess, toastError } from '../../../util/apiNotification';
 
 import AppContainer from '../../../services/AppContainer';
 import AdminNotificationContainer from '../../../services/AdminNotificationContainer';
 import GlobalNotificationList from './GlobalNotificationList';
 
+const logger = loggerFactory('growi:GlobalNotification');
+
 class GlobalNotification extends React.Component {
 
+  constructor() {
+    super();
+
+    this.onClickSubmit = this.onClickSubmit.bind(this);
+  }
+
+  async onClickSubmit() {
+    const { t, adminNotificationContainer } = this.props;
+
+    try {
+      await adminNotificationContainer.updateGlobalNotificationForPages();
+      toastSuccess(t('toaster.update_successed', { target: t('Notification Settings') }));
+    }
+    catch (err) {
+      toastError(err);
+      logger.error(err);
+    }
+  }
+
   render() {
     const { t, adminNotificationContainer } = this.props;
     const { globalNotifications } = adminNotificationContainer.state;
     return (
       <React.Fragment>
 
+        {/* TODO GW-1279 i18n */}
+        <h2 className="border-bottom mb-5">通知が有効になるページ</h2>
+
+        {/* TODO GW-1279 add checkbox for display isNotificationForOwnerPageEnabled */}
+
+        {/* TODO GW-1279 add checkbox for display isNotificationForGroupPageEnabled */}
+
+        <div className="row my-3">
+          <div className="col-xs-offset-4 col-xs-5">
+            <button
+              type="button"
+              className="btn btn-primary"
+              onClick={this.onClickSubmit}
+              disabled={adminNotificationContainer.state.retrieveError}
+            >{t('Update')}
+            </button>
+          </div>
+        </div>
+
         <a href="/admin/global-notification/new">
           <p className="btn btn-default">{t('notification_setting.add_notification')}</p>
         </a>

+ 3 - 3
src/client/js/components/Admin/Notification/SlackAppConfiguration.jsx

@@ -72,7 +72,7 @@ class SlackAppConfiguration extends React.Component {
                 <input
                   className="form-control"
                   type="text"
-                  defaultValue={adminNotificationContainer.state.webhookUrl}
+                  defaultValue={adminNotificationContainer.state.webhookUrl || ''}
                   onChange={e => adminNotificationContainer.changeWebhookUrl(e.target.value)}
                 />
               </div>
@@ -84,7 +84,7 @@ class SlackAppConfiguration extends React.Component {
                   <input
                     id="cbPrioritizeIWH"
                     type="checkbox"
-                    checked={adminNotificationContainer.state.isIncomingWebhookPrioritized}
+                    checked={adminNotificationContainer.state.isIncomingWebhookPrioritized || false}
                     onChange={() => { adminNotificationContainer.switchIsIncomingWebhookPrioritized() }}
                   />
                   <label htmlFor="cbPrioritizeIWH">
@@ -123,7 +123,7 @@ class SlackAppConfiguration extends React.Component {
                   <input
                     className="form-control"
                     type="text"
-                    defaultValue={adminNotificationContainer.state.slackToken}
+                    defaultValue={adminNotificationContainer.state.slackToken || ''}
                     onChange={e => adminNotificationContainer.changeSlackToken(e.target.value)}
                   />
                 </div>

+ 3 - 3
src/client/js/components/Admin/Notification/UserTriggerNotification.jsx

@@ -78,6 +78,7 @@ class UserTriggerNotification extends React.Component {
 
   render() {
     const { t, adminNotificationContainer } = this.props;
+    const userNotifications = adminNotificationContainer.state.userNotifications || [];
 
     return (
       <React.Fragment>
@@ -123,10 +124,9 @@ class UserTriggerNotification extends React.Component {
                 <button type="button" className="btn btn-primary" disabled={!this.validateForm()} onClick={this.onClickSubmit}>{t('add')}</button>
               </td>
             </tr>
-            {adminNotificationContainer.state.userNotifications.map((notification) => {
+            {userNotifications.length > 0 && userNotifications.map((notification) => {
               return <UserNotificationRow notification={notification} onClickDeleteBtn={this.onClickDeleteBtn} key={notification._id} />;
-            })
-            }
+            })}
           </tbody>
         </table>
       </React.Fragment>

+ 36 - 5
src/client/js/services/AdminNotificationContainer.js

@@ -24,6 +24,8 @@ export default class AdminNotificationContainer extends Container {
       isIncomingWebhookPrioritized: false,
       slackToken: '',
       userNotifications: [],
+      isNotificationForOwnerPageEnabled: false,
+      isNotificationForGroupPageEnabled: false,
       globalNotifications: [],
     };
 
@@ -45,11 +47,13 @@ export default class AdminNotificationContainer extends Container {
       const { notificationParams } = response.data;
 
       this.setState({
-        webhookUrl: notificationParams.webhookUrl || '',
-        isIncomingWebhookPrioritized: notificationParams.isIncomingWebhookPrioritized || false,
-        slackToken: notificationParams.slackToken || '',
-        userNotifications: notificationParams.userNotifications || [],
-        globalNotifications: notificationParams.globalNotifications || [],
+        webhookUrl: notificationParams.webhookUrl,
+        isIncomingWebhookPrioritized: notificationParams.isIncomingWebhookPrioritized,
+        slackToken: notificationParams.slackToken,
+        userNotifications: notificationParams.userNotifications,
+        isNotificationForOwnerPageEnabled: notificationParams.isNotificationForOwnerPageEnabled,
+        isNotificationForGroupPageEnabled: notificationParams.isNotificationForGroupPageEnabled,
+        globalNotifications: notificationParams.globalNotifications,
       });
 
     }
@@ -124,6 +128,33 @@ export default class AdminNotificationContainer extends Container {
     return deletedNotificaton;
   }
 
+  /**
+   * Switch isNotificationForOwnerPageEnabled
+   */
+  switchIsNotificationOwnerPageEnabled() {
+    this.setState({ isNotificationForOwnerPageEnabled: !this.state.isNotificationForOwnerPageEnabled });
+  }
+
+  /**
+   * Switch isNotificationForGroupPageEnabled
+   */
+  switchIsNotificationGroupPageEnabled() {
+    this.setState({ isNotificationForGroupPageEnabled: !this.state.isNotificationForGroupPageEnabled });
+  }
+
+  /**
+   * Update globalNotificationForPages
+   * @memberOf SlackAppConfiguration
+   */
+  async updateGlobalNotificationForPages() {
+    const response = await this.appContainer.apiv3.put('/notification-setting/notify-for-page-grant/', {
+      isNotificationForOwnerPageEnabled: this.state.isNotificationForOwnerPageEnabled,
+      isNotificationForGroupPageEnabled: this.state.isNotificationForGroupPageEnabled,
+    });
+
+    return response;
+  }
+
   /**
    * Delete global notification pattern
    */

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

@@ -117,6 +117,9 @@ module.exports = function(crowi) {
       'customize:isEnabledStaleNotification': false,
       'customize:isAllReplyShown': false,
 
+      'notification:owner-page:isEnabled': false,
+      'notification:group-page:isEnabled': false,
+
       'importer:esa:team_name': undefined,
       'importer:esa:access_token': undefined,
       'importer:qiita:team_name': undefined,

+ 57 - 0
src/server/routes/apiv3/notification-setting.js

@@ -32,6 +32,10 @@ const validator = {
       return (req.body.notifyToType === 'slack') ? !!value : true;
     }),
   ],
+  notifyForPageGrant: [
+    body('isNotificationForOwnerPageEnabled').isBoolean(),
+    body('isNotificationForGroupPageEnabled').isBoolean(),
+  ],
 };
 
 /**
@@ -66,6 +70,15 @@ const validator = {
  *          channel:
  *            type: string
  *            description: slack channel name without '#'
+ *      NotifyForPageGrant:
+ *        type: object
+ *        properties:
+ *          isNotificationForOwnerPageEnabled:
+ *            type: string
+ *            description: Whether to notify on owner page
+ *          isNotificationForGroupPageEnabled:
+ *            type: string
+ *            description: Whether to notify on group page
  *      GlobalNotificationParams:
  *        type: object
  *        properties:
@@ -125,6 +138,8 @@ module.exports = (crowi) => {
       isIncomingWebhookPrioritized: await crowi.configManager.getConfig('notification', 'slack:isIncomingWebhookPrioritized'),
       slackToken: await crowi.configManager.getConfig('notification', 'slack:token'),
       userNotifications: await UpdatePost.findAll(),
+      isNotificationForOwnerPageEnabled: await crowi.configManager.getConfig('notification', 'notification:owner-page:isEnabled'),
+      isNotificationForGroupPageEnabled: await crowi.configManager.getConfig('notification', 'notification:group-page:isEnabled'),
       globalNotifications: await GlobalNotificationSetting.findAll(),
     };
     return res.apiv3({ notificationParams });
@@ -401,6 +416,48 @@ module.exports = (crowi) => {
 
   });
 
+
+  /**
+   * @swagger
+   *
+   *    /notification-setting/notify-for-page-grant:
+   *      put:
+   *        tags: [NotificationSetting]
+   *        description: Update settings for notify for page grant
+   *        requestBody:
+   *          required: true
+   *          content:
+   *            application/json:
+   *              schema:
+   *                $ref: '#/components/schemas/NotifyForPageGrant'
+   *        responses:
+   *          200:
+   *            description: Succeeded to settings for notify for page grant
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  $ref: '#/components/schemas/NotifyForPageGrant'
+   */
+  router.put('/notify-for-page-grant', loginRequiredStrictly, adminRequired, csrf, validator.notifyForPageGrant, ApiV3FormValidator, async(req, res) => {
+
+    const requestParams = {
+      'notification:owner-page:isEnabled': req.body.isNotificationForOwnerPageEnabled,
+      'notification:group-page:isEnabled': req.body.isNotificationForGroupPageEnabled,
+    };
+    try {
+      await crowi.configManager.updateConfigsInTheSameNamespace('notification', requestParams);
+      const responseParams = {
+        isNotificationForOwnerPageEnabled: await crowi.configManager.getConfig('notification', 'notification:owner-page:isEnabled'),
+        isNotificationForGroupPageEnabled: await crowi.configManager.getConfig('notification', 'notification:group-page:isEnabled'),
+      };
+      return res.apiv3({ responseParams });
+    }
+    catch (err) {
+      const msg = 'Error occurred in updating notify for page grant';
+      logger.error('Error', err);
+      return res.apiv3Err(new ErrorV3(msg, 'update-notify-for-page-grant-failed'));
+    }
+  });
   /**
    * @swagger
    *

+ 0 - 2
src/server/service/global-notification/index.js

@@ -65,10 +65,8 @@ class GlobalNotificationService {
       case this.Page.GRANT_SPECIFIED:
         return false;
       case this.Page.GRANT_OWNER:
-        // TODO GW 1271 switch isEnabled
         return (this.crowi.configManager.getConfig('crowi', 'notification:owner-page:isEnabled') || false);
       case this.Page.GRANT_USER_GROUP:
-        // TODO GW 1271 switch isEnabled
         return (this.crowi.configManager.getConfig('crowi', 'notification:group-page:isEnabled') || false);
     }
   }