Browse Source

Merge branch 'reactify-admin/notification-setting' into reactify-admin/create-apiV3-update-slack-app-config

# Conflicts:
#	src/client/js/components/Admin/Notification/NotificationSetting.jsx
itizawa 6 years ago
parent
commit
6ee845ba8e

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

@@ -649,7 +649,8 @@
     "email": {
       "ifttt_link": "Create a new IFTTT applet with Email trigger"
     },
-    "updated_slackApp": "Succeeded to update Slack App Configuration setting"
+    "updated_slackApp": "Succeeded to update Slack App Configuration setting",
+    "add_notification_pattern": "Add user trigger notification patterns"
   },
 
   "customize_page": {

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

@@ -633,7 +633,8 @@
     "email": {
       "ifttt_link": "IFTTT でメールトリガの新しいアプレットを作る"
     },
-    "updated_slackApp": "SlackApp設定を更新しました"
+    "updated_slackApp": "SlackApp設定を更新しました",
+    "add_notification_pattern": "通知パターンを追加しました。"
   },
 
   "customize_page": {

+ 25 - 22
src/client/js/components/Admin/Notification/NotificationSetting.jsx

@@ -8,9 +8,11 @@ import { createSubscribedElement } from '../../UnstatedUtils';
 import { toastError } from '../../../util/apiNotification';
 
 import AppContainer from '../../../services/AppContainer';
-import SlackAppConfiguration from './SlackAppConfiguration';
 import AdminNotificationContainer from '../../../services/AdminNotificationContainer';
 
+import SlackAppConfiguration from './SlackAppConfiguration';
+import UserTriggerNotification from './UserTriggerNotification';
+
 const logger = loggerFactory('growi:NotificationSetting');
 
 class NotificationSetting extends React.Component {
@@ -33,27 +35,28 @@ class NotificationSetting extends React.Component {
 
     return (
       <React.Fragment>
-        <ul className="nav nav-tabs" role="tablist">
-          <li role="tab" className="active">
-            <a href="#slack-configuration" data-toggle="tab" role="tab"><i className="icon-settings"></i> Slack Configuration</a>
-          </li>
-          <li role="tab">
-            <a href="#user-trigger-notification" data-toggle="tab" role="tab"><i className="icon-settings"></i> User Trigger Notification</a>
-          </li>
-          <li role="tab">
-            <a href="#global-notification" data-toggle="tab" role="tab"><i className="icon-settings"></i> Global Notification</a>
-          </li>
-        </ul>
-
-        <div className="tab-content m-t-15">
-          <div id="slack-configuration" className="tab-pane active" role="tabpanel">
-            <SlackAppConfiguration />
-          </div>
-          <div id="user-trigger-notification" className="tab-pane" role="tabpanel">
-            {/* TODO GW-775 user trigger notification component */}
-          </div>
-          <div id="global-notification" className="tab-pane" role="tabpanel">
-            {/* TODO GE-776 global notification component */}
+        <div className="notification-settings">
+          <ul className="nav nav-tabs" role="tablist">
+            <li className="active">
+              <a href="#slack-configuration" data-toggle="tab" role="tab"><i className="icon-settings"></i> Slack Configuration</a>
+            </li>
+            <li>
+              <a href="#user-trigger-notification" data-toggle="tab" role="tab"><i className="icon-settings"></i> User Trigger Notification</a>
+            </li>
+            <li>
+              <a href="#global-notification" data-toggle="tab" role="tab"><i className="icon-settings"></i> Global Notification</a>
+            </li>
+          </ul>
+          <div className="tab-content m-t-15">
+            <div id="slack-configuration" className="tab-pane active" role="tabpanel">
+              <SlackAppConfiguration />
+            </div>
+            <div id="user-trigger-notification" className="tab-pane" role="tabpanel">
+              <UserTriggerNotification />
+            </div>
+            <div id="global-notification" className="tab-pane" role="tabpanel">
+              {/* TODO GE-776 global notification component */}
+            </div>
           </div>
         </div>
       </React.Fragment>

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

@@ -0,0 +1,133 @@
+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';
+
+const logger = loggerFactory('growi:slackAppConfiguration');
+
+class UserTriggerNotification extends React.Component {
+
+  constructor(props) {
+    super(props);
+
+    this.state = {
+      pathPattern: '',
+      channel: '',
+    };
+
+    this.changePathPattern = this.changePathPattern.bind(this);
+    this.changeChannel = this.changeChannel.bind(this);
+    this.validateForm = this.validateForm.bind(this);
+    this.onClickSubmit = this.onClickSubmit.bind(this);
+
+  }
+
+  /**
+   * Change pathPattern
+   */
+  changePathPattern(pathPattern) {
+    this.setState({ pathPattern });
+  }
+
+  /**
+   * Change channel
+   */
+  changeChannel(channel) {
+    this.setState({ channel });
+  }
+
+  validateForm() {
+    return this.state.pathPattern !== '' && this.state.channel !== '';
+  }
+
+  async onClickSubmit() {
+    const { t, adminNotificationContainer } = this.props;
+
+    try {
+      await adminNotificationContainer.addNotificationPattern(this.state.pathPattern, this.state.channel);
+      toastSuccess(t('notification_setting.add_notification_pattern'));
+      this.setState({ pathPattern: '', channel: '' });
+    }
+    catch (err) {
+      toastError(err);
+      logger.error(err);
+    }
+  }
+
+  // TODO GW-788 i18n
+  render() {
+    const { t } = this.props;
+
+    return (
+      <React.Fragment>
+        <h2 className="border-bottom mb-5">Default Notification Settings for Patterns</h2>
+
+        <table className="table table-bordered">
+          <thead>
+            <tr>
+              <th>Pattern</th>
+              <th>Channel</th>
+              <th>Operation</th>
+            </tr>
+          </thead>
+          <tbody className="admin-notif-list">
+            <tr>
+              <td>
+                <input
+                  className="form-control"
+                  type="text"
+                  name="pathPattern"
+                  value={this.state.pathPattern}
+                  placeholder="e.g. /projects/xxx/MTG/*"
+                  onChange={(e) => { this.changePathPattern(e.target.value) }}
+                />
+                <p className="help-block">
+                  Path name of wiki. Pattern expression with <code>*</code> can be used.
+                </p>
+              </td>
+              <td>
+                <input
+                  className="form-control form-inline"
+                  type="text"
+                  name="channel"
+                  value={this.state.channel}
+                  placeholder="e.g. project-xxx"
+                  onChange={(e) => { this.changeChannel(e.target.value) }}
+                />
+                <p className="help-block">
+                  Slack channel name. Without <code>#</code>.
+                </p>
+              </td>
+              <td>
+                <button type="button" className="btn btn-primary" disabled={!this.validateForm()} onClick={this.onClickSubmit}>{t('add')}</button>
+              </td>
+            </tr>
+          </tbody>
+        </table>
+      </React.Fragment>
+    );
+  }
+
+
+}
+
+
+const UserTriggerNotificationWrapper = (props) => {
+  return createSubscribedElement(UserTriggerNotification, props, [AppContainer, AdminNotificationContainer]);
+};
+
+UserTriggerNotification.propTypes = {
+  t: PropTypes.func.isRequired, // i18next
+  appContainer: PropTypes.instanceOf(AppContainer).isRequired,
+  adminNotificationContainer: PropTypes.instanceOf(AdminNotificationContainer).isRequired,
+
+};
+
+export default withTranslation()(UserTriggerNotificationWrapper);

+ 9 - 0
src/client/js/services/AdminNotificationContainer.js

@@ -17,6 +17,7 @@ export default class AdminNotificationContainer extends Container {
       webhookUrl: '',
       isIncomingWebhookPrioritized: false,
       slackToken: '',
+      userNotifications: [],
     };
 
   }
@@ -77,4 +78,12 @@ export default class AdminNotificationContainer extends Container {
     return response;
   }
 
+  /**
+   * Add notificationPattern
+   * @memberOf SlackAppConfiguration
+   */
+  async addNotificationPattern(pathPattern, channel) {
+    // TODO GW-802 create apiV3 addNotificationPattern
+  }
+
 }