Jelajahi Sumber

made ManageGlobalNotification FC

Shunm634-source 3 tahun lalu
induk
melakukan
7889a438ec

+ 258 - 257
packages/app/src/components/Admin/Notification/ManageGlobalNotification.jsx

@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useCallback, useState } from 'react';
 
 import { useTranslation } from 'next-i18next';
 import PropTypes from 'prop-types';
@@ -18,56 +18,64 @@ import TriggerEventCheckBox from './TriggerEventCheckBox';
 
 const logger = loggerFactory('growi:manageGlobalNotification');
 
-export default class ManageGlobalNotification extends React.Component {
-
-  constructor() {
-    super();
-
-    const globalNotification = null;
-    // try {
-    //   globalNotification = JSON.parse(document.getElementById('admin-global-notification-setting').getAttribute('data-global-notification'));
-    // }
-    // catch (err) {
-    //   // toastError(err);
-    //   logger.error(err);
-    // }
-
-    this.state = {
-      // globalNotificationId: globalNotification._id || null,
-      globalNotificationId: null,
-      // triggerPath: globalNotification.triggerPath || '',
-      triggerPath: '',
-      // notifyToType: globalNotification.__t || 'mail',
-      notifyToType: 'mail',
-      // emailToSend: globalNotification.toEmail || '',
-      emailToSend: '',
-      // slackChannelToSend: globalNotification.slackChannels || '',
-      slackChannelToSend: '',
-      // triggerEvents: new Set(globalNotification.triggerEvents),
-      triggerEvents: new Set(),
-    };
-
-    this.submitHandler = this.submitHandler.bind(this);
-  }
-
-  onChangeTriggerPath(inputValue) {
-    this.setState({ triggerPath: inputValue });
-  }
-
-  onChangeNotifyToType(notifyToType) {
-    this.setState({ notifyToType });
-  }
-
-  onChangeEmailToSend(inputValue) {
-    this.setState({ emailToSend: inputValue });
-  }
-
-  onChangeSlackChannelToSend(inputValue) {
-    this.setState({ slackChannelToSend: inputValue });
-  }
-
-  onChangeTriggerEvents(triggerEvent) {
-    const { triggerEvents } = this.state;
+const ManageGlobalNotification = (props) => {
+
+  // constructor() {
+  //   super();
+
+  //   const globalNotification = null;
+  //   // try {
+  //   //   globalNotification = JSON.parse(document.getElementById('admin-global-notification-setting').getAttribute('data-global-notification'));
+  //   // }
+  //   // catch (err) {
+  //   //   // toastError(err);
+  //   //   logger.error(err);
+  //   // }
+
+  //   this.state = {
+  //     // globalNotificationId: globalNotification._id || null,
+  //     globalNotificationId: null,
+  //     // triggerPath: globalNotification.triggerPath || '',
+  //     triggerPath: '',
+  //     // notifyToType: globalNotification.__t || 'mail',
+  //     notifyToType: 'mail',
+  //     // emailToSend: globalNotification.toEmail || '',
+  //     emailToSend: '',
+  //     // slackChannelToSend: globalNotification.slackChannels || '',
+  //     slackChannelToSend: '',
+  //     // triggerEvents: new Set(globalNotification.triggerEvents),
+  //     triggerEvents: new Set(),
+  //   };
+
+  //   this.submitHandler = this.submitHandler.bind(this);
+  // }
+
+  const [globalNotificationId, setGlobalNotificationId] = useState(null);
+  const [triggerPath, setTriggerPath] = useState('');
+  const [notifyToType, setNotifyToType] = useState('mail');
+  const [emailToSend, setEmailToSend] = useState('');
+  const [slacChannelToSend, setSlackChannelToSend] = useState('');
+  const [triggerEvents, setTriggerEvents] = useState(new Set());
+  const [retrieveError] = useState(null);
+
+
+  // onChangeTriggerPath(inputValue) {
+  //   this.setState({ triggerPath: inputValue });
+  // }
+
+  // onChangeNotifyToType(notifyToType) {
+  //   this.setState({ notifyToType });
+  // }
+
+  // onChangeEmailToSend(inputValue) {
+  //   this.setState({ emailToSend: inputValue });
+  // }
+
+  // onChangeSlackChannelToSend(inputValue) {
+  //   this.setState({ slackChannelToSend: inputValue });
+  // }
+
+  const onChangeTriggerEvents = (triggerEvent) => {
 
     if (triggerEvents.has(triggerEvent)) {
       triggerEvents.delete(triggerEvent);
@@ -77,21 +85,21 @@ export default class ManageGlobalNotification extends React.Component {
       triggerEvents.add(triggerEvent);
       this.setState({ triggerEvents });
     }
-  }
+  };
 
-  async submitHandler() {
+  const submitHandler = useCallback(async() => {
 
     const requestParams = {
-      triggerPath: this.state.triggerPath,
-      notifyToType: this.state.notifyToType,
-      toEmail: this.state.emailToSend,
-      slackChannels: this.state.slackChannelToSend,
-      triggerEvents: [...this.state.triggerEvents],
+      triggerPath,
+      notifyToType,
+      emailToSend,
+      slacChannelToSend,
+      triggerEvents,
     };
 
     try {
-      if (this.state.globalNotificationId != null) {
-        await apiv3Put(`/notification-setting/global-notification/${this.state.globalNotificationId}`, requestParams);
+      if (globalNotificationId != null) {
+        await apiv3Put(`/notification-setting/global-notification/${globalNotificationId}`, requestParams);
       }
       else {
         await apiv3Post('/notification-setting/global-notification', requestParams);
@@ -102,223 +110,216 @@ export default class ManageGlobalNotification extends React.Component {
       // toastError(err);
       logger.error(err);
     }
-  }
+  }, []);
 
+  const { isMailerSetup } = props;
+  const { t } = useTranslation('admin');
 
-  render() {
-    const { t, isMailerSetup } = this.props;
+  return (
+    <>
+      <div className="my-3">
+        <a href="/admin/notification#global-notification" className="btn btn-outline-secondary">
+          <i className="icon-fw ti-arrow-left" aria-hidden="true"></i>
+          {t('notification_settings.back_to_list')}
+        </a>
+      </div>
 
-    return (
-      <React.Fragment>
 
-        <div className="my-3">
-          <a href="/admin/notification#global-notification" className="btn btn-outline-secondary">
-            <i className="icon-fw ti-arrow-left" aria-hidden="true"></i>
-            {t('notification_settings.back_to_list')}
-          </a>
+      <div className="row">
+        <div className="form-box col-md-12">
+          <h2 className="border-bottom mb-5">{t('notification_settings.notification_detail')}</h2>
         </div>
 
-
-        <div className="row">
-          <div className="form-box col-md-12">
-            <h2 className="border-bottom mb-5">{t('notification_settings.notification_detail')}</h2>
+        <div className="col-sm-4">
+          <h3 htmlFor="triggerPath">{t('notification_settings.trigger_path')}
+            {/* eslint-disable-next-line react/no-danger */}
+            <small dangerouslySetInnerHTML={{ __html: t('notification_settings.trigger_path_help', '<code>*</code>') }} />
+          </h3>
+          <div className="form-group">
+            <input
+              className="form-control"
+              type="text"
+              name="triggerPath"
+              value={triggerPath}
+              onChange={(e) => { setTriggerPath(e.target.value) }}
+              required
+            />
           </div>
 
-          <div className="col-sm-4">
-            <h3 htmlFor="triggerPath">{t('notification_settings.trigger_path')}
-              {/* eslint-disable-next-line react/no-danger */}
-              <small dangerouslySetInnerHTML={{ __html: t('notification_settings.trigger_path_help', '<code>*</code>') }} />
-            </h3>
-            <div className="form-group">
+          <h3>{t('notification_settings.notify_to')}</h3>
+          <div className="form-group form-inline">
+            <div className="custom-control custom-radio">
               <input
-                className="form-control"
-                type="text"
-                name="triggerPath"
-                value={this.state.triggerPath}
-                onChange={(e) => { this.onChangeTriggerPath(e.target.value) }}
-                required
+                className="custom-control-input"
+                type="radio"
+                id="mail"
+                name="notifyToType"
+                value="mail"
+                checked={notifyToType === 'mail'}
+                onChange={() => { setNotifyToType('mail') }}
               />
+              <label className="custom-control-label" htmlFor="mail">
+                <p className="font-weight-bold">Email</p>
+              </label>
             </div>
-
-            <h3>{t('notification_settings.notify_to')}</h3>
-            <div className="form-group form-inline">
-              <div className="custom-control custom-radio">
-                <input
-                  className="custom-control-input"
-                  type="radio"
-                  id="mail"
-                  name="notifyToType"
-                  value="mail"
-                  checked={this.state.notifyToType === 'mail'}
-                  onChange={() => { this.onChangeNotifyToType('mail') }}
-                />
-                <label className="custom-control-label" htmlFor="mail">
-                  <p className="font-weight-bold">Email</p>
-                </label>
-              </div>
-              <div className="custom-control custom-radio ml-2">
-                <input
-                  className="custom-control-input"
-                  type="radio"
-                  id="slack"
-                  name="notifyToType"
-                  value="slack"
-                  checked={this.state.notifyToType === 'slack'}
-                  onChange={() => { this.onChangeNotifyToType('slack') }}
-                />
-                <label className="custom-control-label" htmlFor="slack">
-                  <p className="font-weight-bold">Slack</p>
-                </label>
-              </div>
+            <div className="custom-control custom-radio ml-2">
+              <input
+                className="custom-control-input"
+                type="radio"
+                id="slack"
+                name="notifyToType"
+                value="slack"
+                checked={notifyToType === 'slack'}
+                onChange={() => { this.onChangeNotifyToType('slack') }}
+              />
+              <label className="custom-control-label" htmlFor="slack">
+                <p className="font-weight-bold">Slack</p>
+              </label>
             </div>
+          </div>
 
-            {this.state.notifyToType === 'mail'
-              ? (
-                <>
-                  <div className="input-group notify-to-option" id="mail-input">
-                    <div className="input-group-prepend">
-                      <span className="input-group-text" id="mail-addon"><i className="ti ti-email" /></span>
-                    </div>
-                    <input
-                      className="form-control"
-                      type="text"
-                      aria-describedby="mail-addon"
-                      name="toEmail"
-                      placeholder="Email"
-                      value={this.state.emailToSend}
-                      onChange={(e) => { this.onChangeEmailToSend(e.target.value) }}
-                    />
-
+          {notifyToType === 'mail'
+            ? (
+              <>
+                <div className="input-group notify-to-option" id="mail-input">
+                  <div className="input-group-prepend">
+                    <span className="input-group-text" id="mail-addon"><i className="ti ti-email" /></span>
                   </div>
-
-                  <p className="p-2">
-                    {/* eslint-disable-next-line react/no-danger */}
-                    {!isMailerSetup && <span className="form-text text-muted" dangerouslySetInnerHTML={{ __html: t('admin:mailer_setup_required') }} />}
-                    <b>Hint: </b>
-                    <a href="https://ifttt.com/create" target="blank">{t('notification_settings.email.ifttt_link')}
-                      <i className="icon-share-alt" />
-                    </a>
-                  </p>
-                </>
-              )
-              : (
-                <>
-                  <div className="input-group notify-to-option" id="slack-input">
-                    <div className="input-group-prepend">
-                      <span className="input-group-text" id="slack-channel-addon"><i className="fa fa-hashtag" /></span>
-                    </div>
-                    <input
-                      className="form-control"
-                      type="text"
-                      aria-describedby="slack-channel-addon"
-                      name="notificationGlobal[slackChannels]"
-                      placeholder="Slack Channel"
-                      value={this.state.slackChannelToSend}
-                      onChange={(e) => { this.onChangeSlackChannelToSend(e.target.value) }}
-                    />
+                  <input
+                    className="form-control"
+                    type="text"
+                    aria-describedby="mail-addon"
+                    name="toEmail"
+                    placeholder="Email"
+                    value={emailToSend}
+                    onChange={(e) => { setEmailToSend(e.target.value) }}
+                  />
+
+                </div>
+
+                <p className="p-2">
+                  {/* eslint-disable-next-line react/no-danger */}
+                  {!isMailerSetup && <span className="form-text text-muted" dangerouslySetInnerHTML={{ __html: t('admin:mailer_setup_required') }} />}
+                  <b>Hint: </b>
+                  <a href="https://ifttt.com/create" target="blank">{t('notification_settings.email.ifttt_link')}
+                    <i className="icon-share-alt" />
+                  </a>
+                </p>
+              </>
+            )
+            : (
+              <>
+                <div className="input-group notify-to-option" id="slack-input">
+                  <div className="input-group-prepend">
+                    <span className="input-group-text" id="slack-channel-addon"><i className="fa fa-hashtag" /></span>
                   </div>
-                  <p className="p-2">
-                    {/* eslint-disable-next-line react/no-danger */}
-                    <span dangerouslySetInnerHTML={{ __html: t('notification_settings.channel_desc') }} />
-                  </p>
-                </>
-              )}
-          </div>
-
-          <div className="offset-1 col-sm-5">
-            <div className="form-group">
-              <h3>{t('notification_settings.trigger_events')}</h3>
-              <div className="my-1">
-                <TriggerEventCheckBox
-                  checkbox="success"
-                  event="pageCreate"
-                  checked={this.state.triggerEvents.has('pageCreate')}
-                  onChange={() => this.onChangeTriggerEvents('pageCreate')}
-                >
-                  <span className="badge badge-pill badge-success">
-                    <i className="icon-doc mr-1" /> CREATE
-                  </span>
-                </TriggerEventCheckBox>
-              </div>
-              <div className="my-1">
-                <TriggerEventCheckBox
-                  checkbox="warning"
-                  event="pageEdit"
-                  checked={this.state.triggerEvents.has('pageEdit')}
-                  onChange={() => this.onChangeTriggerEvents('pageEdit')}
-                >
-                  <span className="badge badge-pill badge-warning">
-                    <i className="icon-pencil mr-1" />EDIT
-                  </span>
-                </TriggerEventCheckBox>
-              </div>
-              <div className="my-1">
-                <TriggerEventCheckBox
-                  checkbox="pink"
-                  event="pageMove"
-                  checked={this.state.triggerEvents.has('pageMove')}
-                  onChange={() => this.onChangeTriggerEvents('pageMove')}
-                >
-                  <span className="badge badge-pill badge-pink">
-                    <i className="icon-action-redo mr-1" />MOVE
-                  </span>
-                </TriggerEventCheckBox>
-              </div>
-              <div className="my-1">
-                <TriggerEventCheckBox
-                  checkbox="danger"
-                  event="pageDelete"
-                  checked={this.state.triggerEvents.has('pageDelete')}
-                  onChange={() => this.onChangeTriggerEvents('pageDelete')}
-                >
-                  <span className="badge badge-pill badge-danger">
-                    <i className="icon-fire mr-1" />DELETE
-                  </span>
-                </TriggerEventCheckBox>
-              </div>
-              <div className="my-1">
-                <TriggerEventCheckBox
-                  checkbox="info"
-                  event="pageLike"
-                  checked={this.state.triggerEvents.has('pageLike')}
-                  onChange={() => this.onChangeTriggerEvents('pageLike')}
-                >
-                  <span className="badge badge-pill badge-info">
-                    <i className="fa fa-heart-o mr-1" />LIKE
-                  </span>
-                </TriggerEventCheckBox>
-              </div>
-              <div className="my-1">
-                <TriggerEventCheckBox
-                  checkbox="secondary"
-                  event="comment"
-                  checked={this.state.triggerEvents.has('comment')}
-                  onChange={() => this.onChangeTriggerEvents('comment')}
-                >
-                  <span className="badge badge-pill badge-secondary">
-                    <i className="icon-bubble mr-1" />POST
-                  </span>
-                </TriggerEventCheckBox>
-              </div>
+                  <input
+                    className="form-control"
+                    type="text"
+                    aria-describedby="slack-channel-addon"
+                    name="notificationGlobal[slackChannels]"
+                    placeholder="Slack Channel"
+                    value={slacChannelToSend}
+                    onChange={(e) => { setSlackChannelToSend(e.target.value) }}
+                  />
+                </div>
+                <p className="p-2">
+                  {/* eslint-disable-next-line react/no-danger */}
+                  <span dangerouslySetInnerHTML={{ __html: t('notification_settings.channel_desc') }} />
+                </p>
+              </>
+            )}
+        </div>
 
+        <div className="offset-1 col-sm-5">
+          <div className="form-group">
+            <h3>{t('notification_settings.trigger_events')}</h3>
+            <div className="my-1">
+              <TriggerEventCheckBox
+                checkbox="success"
+                event="pageCreate"
+                checked={triggerEvents.has('pageCreate')}
+                onChange={() => onChangeTriggerEvents('pageCreate')}
+              >
+                <span className="badge badge-pill badge-success">
+                  <i className="icon-doc mr-1" /> CREATE
+                </span>
+              </TriggerEventCheckBox>
+            </div>
+            <div className="my-1">
+              <TriggerEventCheckBox
+                checkbox="warning"
+                event="pageEdit"
+                checked={triggerEvents.has('pageEdit')}
+                onChange={() => this.onChangeTriggerEvents('pageEdit')}
+              >
+                <span className="badge badge-pill badge-warning">
+                  <i className="icon-pencil mr-1" />EDIT
+                </span>
+              </TriggerEventCheckBox>
+            </div>
+            <div className="my-1">
+              <TriggerEventCheckBox
+                checkbox="pink"
+                event="pageMove"
+                checked={triggerEvents.has('pageMove')}
+                onChange={() => this.onChangeTriggerEvents('pageMove')}
+              >
+                <span className="badge badge-pill badge-pink">
+                  <i className="icon-action-redo mr-1" />MOVE
+                </span>
+              </TriggerEventCheckBox>
+            </div>
+            <div className="my-1">
+              <TriggerEventCheckBox
+                checkbox="danger"
+                event="pageDelete"
+                checked={triggerEvents.has('pageDelete')}
+                onChange={() => this.onChangeTriggerEvents('pageDelete')}
+              >
+                <span className="badge badge-pill badge-danger">
+                  <i className="icon-fire mr-1" />DELETE
+                </span>
+              </TriggerEventCheckBox>
+            </div>
+            <div className="my-1">
+              <TriggerEventCheckBox
+                checkbox="info"
+                event="pageLike"
+                checked={triggerEvents.has('pageLike')}
+                onChange={() => this.onChangeTriggerEvents('pageLike')}
+              >
+                <span className="badge badge-pill badge-info">
+                  <i className="fa fa-heart-o mr-1" />LIKE
+                </span>
+              </TriggerEventCheckBox>
             </div>
+            <div className="my-1">
+              <TriggerEventCheckBox
+                checkbox="secondary"
+                event="comment"
+                checked={triggerEvents.has('comment')}
+                onChange={() => this.onChangeTriggerEvents('comment')}
+              >
+                <span className="badge badge-pill badge-secondary">
+                  <i className="icon-bubble mr-1" />POST
+                </span>
+              </TriggerEventCheckBox>
+            </div>
+
           </div>
         </div>
-
-        <AdminUpdateButtonRow
-          onClick={this.submitHandler}
-          disabled={this.state.retrieveError != null}
-        />
-
-      </React.Fragment>
-
-    );
-  }
-
-}
+      </div>
+
+      <AdminUpdateButtonRow
+        onClick={submitHandler}
+        disabled={retrieveError != null}
+      />
+    </>
+  );
+};
 
 ManageGlobalNotification.propTypes = {
-  t: PropTypes.func.isRequired, // i18next
   isMailerSetup: PropTypes.bool,
 };
 
@@ -331,4 +332,4 @@ ManageGlobalNotification.propTypes = {
 // const ManageGlobalNotificationWrapper = withUnstatedContainers(ManageGlobalNotificationWrapperFC, [AppContainer]);
 
 
-// export default ManageGlobalNotificationWrapper;
+export default ManageGlobalNotification;

+ 1 - 1
packages/app/src/pages/admin/[[...path]].page.tsx

@@ -143,7 +143,7 @@ const AdminMarkdownSettingsPage: NextPage<Props> = (props: Props) => {
     'global-notification': {
       new: {
         title: t('external_notification.external_notification'),
-        component: <ManageGlobalNotification isMailerSetup={props.isMailerSetup} t={t} />,
+        component: <ManageGlobalNotification isMailerSetup={props.isMailerSetup} />,
       },
     },
     'slack-integration': {