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

typescriptize ManageGlobalNotification

kaori 3 лет назад
Родитель
Сommit
d3897d64a3

+ 27 - 0
packages/app/src/client/interfaces/global-notification.ts

@@ -0,0 +1,27 @@
+export const NotifyType = {
+  Email: 'email',
+  SLACK: 'slack',
+} as const;
+
+export type NotifyType = typeof NotifyType[keyof typeof NotifyType]
+
+
+export const TriggerEventType = {
+  CREATE: 'pageCreate',
+  EDIT: 'pageEdit',
+  MOVE: 'pageMove',
+  DELETE: 'pageDelete',
+  LIKE: 'pageLike',
+  POST: 'comment',
+} as const;
+
+type TriggerEventType = typeof TriggerEventType[keyof typeof TriggerEventType]
+
+
+export type IGlobalNotification = {
+  triggerPath: string,
+  notifyType: NotifyType,
+  emailToSend: string,
+  slackChannelToSend: string,
+  triggerEvents: TriggerEventType[],
+};

+ 40 - 40
packages/app/src/components/Admin/Notification/ManageGlobalNotification.jsx → packages/app/src/components/Admin/Notification/ManageGlobalNotification.tsx

@@ -4,11 +4,11 @@ import React, {
 
 
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import { useRouter } from 'next/router';
 import { useRouter } from 'next/router';
-import PropTypes from 'prop-types';
 
 
+import { NotifyType, TriggerEventType } from '~/client/interfaces/global-notification';
 import AdminNotificationContainer from '~/client/services/AdminNotificationContainer';
 import AdminNotificationContainer from '~/client/services/AdminNotificationContainer';
 import { toastError } from '~/client/util/apiNotification';
 import { toastError } from '~/client/util/apiNotification';
-import { apiv3Post, apiv3Put } from '~/client/util/apiv3-client';
+import { apiv3Post } from '~/client/util/apiv3-client';
 import { useIsMailerSetup } from '~/stores/context';
 import { useIsMailerSetup } from '~/stores/context';
 import { useSWRxGlobalNotification } from '~/stores/global-notification';
 import { useSWRxGlobalNotification } from '~/stores/global-notification';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
@@ -23,14 +23,20 @@ import TriggerEventCheckBox from './TriggerEventCheckBox';
 const logger = loggerFactory('growi:manageGlobalNotification');
 const logger = loggerFactory('growi:manageGlobalNotification');
 
 
 
 
-const ManageGlobalNotification = (props) => {
+type Props = {
+  adminNotificationContainer: AdminNotificationContainer,
+  globalNotificationId?: string,
+}
+
+
+const ManageGlobalNotification = (props: Props): JSX.Element => {
 
 
   const [triggerPath, setTriggerPath] = useState('');
   const [triggerPath, setTriggerPath] = useState('');
-  const [notifyType, setNotifyType] = useState('mail');
+  const [notifyType, setNotifyType] = useState<NotifyType>(NotifyType.Email);
   const [emailToSend, setEmailToSend] = useState('');
   const [emailToSend, setEmailToSend] = useState('');
   const [slackChannelToSend, setSlackChannelToSend] = useState('');
   const [slackChannelToSend, setSlackChannelToSend] = useState('');
   const [triggerEvents, setTriggerEvents] = useState(new Set());
   const [triggerEvents, setTriggerEvents] = useState(new Set());
-  const { data: globalNotificationData, update: updateGlobalNotification } = useSWRxGlobalNotification(props.globalNotificationId);
+  const { data: globalNotificationData, update: updateGlobalNotification } = useSWRxGlobalNotification(props.globalNotificationId || '');
   const globalNotification = useMemo(() => globalNotificationData?.globalNotification, [globalNotificationData?.globalNotification]);
   const globalNotification = useMemo(() => globalNotificationData?.globalNotification, [globalNotificationData?.globalNotification]);
 
 
   const router = useRouter();
   const router = useRouter();
@@ -44,15 +50,13 @@ const ManageGlobalNotification = (props) => {
       setTriggerPath(globalNotification.triggerPath);
       setTriggerPath(globalNotification.triggerPath);
       setTriggerEvents(new Set(globalNotification.triggerEvents));
       setTriggerEvents(new Set(globalNotification.triggerEvents));
 
 
-      if (notifyType === 'mail') {
+      if (notifyType === NotifyType.Email) {
         setEmailToSend(globalNotification.toEmail);
         setEmailToSend(globalNotification.toEmail);
       }
       }
       else {
       else {
         setSlackChannelToSend(globalNotification.slackChannels);
         setSlackChannelToSend(globalNotification.slackChannels);
       }
       }
     }
     }
-
-
   }, [globalNotification]);
   }, [globalNotification]);
 
 
   const isLoading = globalNotificationData === undefined;
   const isLoading = globalNotificationData === undefined;
@@ -88,13 +92,12 @@ const ManageGlobalNotification = (props) => {
       triggerEvents: [...triggerEvents],
       triggerEvents: [...triggerEvents],
     };
     };
 
 
-    const { _id: globalNotificationId } = globalNotification;
+    const globalNotificationId = globalNotification?._id;
 
 
     try {
     try {
       if (globalNotificationId != null) {
       if (globalNotificationId != null) {
         await updateGlobalNotification(requestParams);
         await updateGlobalNotification(requestParams);
         router.push('/admin/notification');
         router.push('/admin/notification');
-        // await apiv3Put(`/notification-setting/global-notification/${globalNotificationId}`, requestParams);
       }
       }
       else {
       else {
         await apiv3Post('/notification-setting/global-notification', requestParams);
         await apiv3Post('/notification-setting/global-notification', requestParams);
@@ -128,9 +131,11 @@ const ManageGlobalNotification = (props) => {
         </div>
         </div>
 
 
         <div className="col-sm-4">
         <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>
+            <label 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>') }} />
+            </label>
           </h3>
           </h3>
           <div className="form-group">
           <div className="form-group">
             <input
             <input
@@ -152,8 +157,8 @@ const ManageGlobalNotification = (props) => {
                 id="mail"
                 id="mail"
                 name="notifyType"
                 name="notifyType"
                 value="mail"
                 value="mail"
-                checked={notifyType === 'mail'}
-                onChange={() => { setNotifyType('mail') }}
+                checked={notifyType === NotifyType.Email}
+                onChange={() => { setNotifyType(NotifyType.Email) }}
               />
               />
               <label className="custom-control-label" htmlFor="mail">
               <label className="custom-control-label" htmlFor="mail">
                 <p className="font-weight-bold">Email</p>
                 <p className="font-weight-bold">Email</p>
@@ -166,8 +171,8 @@ const ManageGlobalNotification = (props) => {
                 id="slack"
                 id="slack"
                 name="notifyType"
                 name="notifyType"
                 value="slack"
                 value="slack"
-                checked={notifyType === 'slack'}
-                onChange={() => { setNotifyType('slack') }}
+                checked={notifyType === NotifyType.SLACK}
+                onChange={() => { setNotifyType(NotifyType.SLACK) }}
               />
               />
               <label className="custom-control-label" htmlFor="slack">
               <label className="custom-control-label" htmlFor="slack">
                 <p className="font-weight-bold">Slack</p>
                 <p className="font-weight-bold">Slack</p>
@@ -175,7 +180,7 @@ const ManageGlobalNotification = (props) => {
             </div>
             </div>
           </div>
           </div>
 
 
-          {notifyType === 'mail'
+          {notifyType === NotifyType.Email
             ? (
             ? (
               <>
               <>
                 <div className="input-group notify-to-option" id="mail-input">
                 <div className="input-group notify-to-option" id="mail-input">
@@ -234,9 +239,9 @@ const ManageGlobalNotification = (props) => {
             <div className="my-1">
             <div className="my-1">
               <TriggerEventCheckBox
               <TriggerEventCheckBox
                 checkbox="success"
                 checkbox="success"
-                event="pageCreate"
-                checked={triggerEvents.has('pageCreate')}
-                onChange={() => onChangeTriggerEvents('pageCreate')}
+                event={TriggerEventType.CREATE}
+                checked={triggerEvents.has(TriggerEventType.CREATE)}
+                onChange={() => onChangeTriggerEvents(TriggerEventType.CREATE)}
               >
               >
                 <span className="badge badge-pill badge-success">
                 <span className="badge badge-pill badge-success">
                   <i className="icon-doc mr-1" /> CREATE
                   <i className="icon-doc mr-1" /> CREATE
@@ -246,9 +251,9 @@ const ManageGlobalNotification = (props) => {
             <div className="my-1">
             <div className="my-1">
               <TriggerEventCheckBox
               <TriggerEventCheckBox
                 checkbox="warning"
                 checkbox="warning"
-                event="pageEdit"
-                checked={triggerEvents.has('pageEdit')}
-                onChange={() => onChangeTriggerEvents('pageEdit')}
+                event={TriggerEventType.EDIT}
+                checked={triggerEvents.has(TriggerEventType.EDIT)}
+                onChange={() => onChangeTriggerEvents(TriggerEventType.EDIT)}
               >
               >
                 <span className="badge badge-pill badge-warning">
                 <span className="badge badge-pill badge-warning">
                   <i className="icon-pencil mr-1" />EDIT
                   <i className="icon-pencil mr-1" />EDIT
@@ -258,9 +263,9 @@ const ManageGlobalNotification = (props) => {
             <div className="my-1">
             <div className="my-1">
               <TriggerEventCheckBox
               <TriggerEventCheckBox
                 checkbox="pink"
                 checkbox="pink"
-                event="pageMove"
-                checked={triggerEvents.has('pageMove')}
-                onChange={() => onChangeTriggerEvents('pageMove')}
+                event={TriggerEventType.MOVE}
+                checked={triggerEvents.has(TriggerEventType.MOVE)}
+                onChange={() => onChangeTriggerEvents(TriggerEventType.MOVE)}
               >
               >
                 <span className="badge badge-pill badge-pink">
                 <span className="badge badge-pill badge-pink">
                   <i className="icon-action-redo mr-1" />MOVE
                   <i className="icon-action-redo mr-1" />MOVE
@@ -271,8 +276,8 @@ const ManageGlobalNotification = (props) => {
               <TriggerEventCheckBox
               <TriggerEventCheckBox
                 checkbox="danger"
                 checkbox="danger"
                 event="pageDelete"
                 event="pageDelete"
-                checked={triggerEvents.has('pageDelete')}
-                onChange={() => onChangeTriggerEvents('pageDelete')}
+                checked={triggerEvents.has(TriggerEventType.DELETE)}
+                onChange={() => onChangeTriggerEvents(TriggerEventType.DELETE)}
               >
               >
                 <span className="badge badge-pill badge-danger">
                 <span className="badge badge-pill badge-danger">
                   <i className="icon-fire mr-1" />DELETE
                   <i className="icon-fire mr-1" />DELETE
@@ -282,9 +287,9 @@ const ManageGlobalNotification = (props) => {
             <div className="my-1">
             <div className="my-1">
               <TriggerEventCheckBox
               <TriggerEventCheckBox
                 checkbox="info"
                 checkbox="info"
-                event="pageLike"
-                checked={triggerEvents.has('pageLike')}
-                onChange={() => onChangeTriggerEvents('pageLike')}
+                event={TriggerEventType.LIKE}
+                checked={triggerEvents.has(TriggerEventType.LIKE)}
+                onChange={() => onChangeTriggerEvents(TriggerEventType.LIKE)}
               >
               >
                 <span className="badge badge-pill badge-info">
                 <span className="badge badge-pill badge-info">
                   <i className="fa fa-heart-o mr-1" />LIKE
                   <i className="fa fa-heart-o mr-1" />LIKE
@@ -294,9 +299,9 @@ const ManageGlobalNotification = (props) => {
             <div className="my-1">
             <div className="my-1">
               <TriggerEventCheckBox
               <TriggerEventCheckBox
                 checkbox="secondary"
                 checkbox="secondary"
-                event="comment"
-                checked={triggerEvents.has('comment')}
-                onChange={() => onChangeTriggerEvents('comment')}
+                event={TriggerEventType.POST}
+                checked={triggerEvents.has(TriggerEventType.POST)}
+                onChange={() => onChangeTriggerEvents(TriggerEventType.POST)}
               >
               >
                 <span className="badge badge-pill badge-secondary">
                 <span className="badge badge-pill badge-secondary">
                   <i className="icon-bubble mr-1" />POST
                   <i className="icon-bubble mr-1" />POST
@@ -316,12 +321,7 @@ const ManageGlobalNotification = (props) => {
   );
   );
 };
 };
 
 
-ManageGlobalNotification.propTypes = {
-  adminNotificationContainer: PropTypes.instanceOf(AdminNotificationContainer).isRequired,
-  globalNotificationId: PropTypes.string,
-};
 
 
 const ManageGlobalNotificationWrapper = withUnstatedContainers(ManageGlobalNotification, [AdminNotificationContainer]);
 const ManageGlobalNotificationWrapper = withUnstatedContainers(ManageGlobalNotification, [AdminNotificationContainer]);
 
 
-
 export default ManageGlobalNotificationWrapper;
 export default ManageGlobalNotificationWrapper;

+ 2 - 2
packages/app/src/stores/global-notification.ts

@@ -1,6 +1,7 @@
 import { SWRResponseWithUtils, withUtils } from '@growi/core';
 import { SWRResponseWithUtils, withUtils } from '@growi/core';
 import useSWRImmutable from 'swr/immutable';
 import useSWRImmutable from 'swr/immutable';
 
 
+import { IGlobalNotification } from '~/client/interfaces/global-notification';
 
 
 import { apiv3Get, apiv3Put } from '../client/util/apiv3-client';
 import { apiv3Get, apiv3Put } from '../client/util/apiv3-client';
 
 
@@ -10,7 +11,6 @@ type Util = {
 };
 };
 
 
 
 
-// TODO: typescriptize
 export const useSWRxGlobalNotification = (globalNotificationId: string): SWRResponseWithUtils<Util, any, Error> => {
 export const useSWRxGlobalNotification = (globalNotificationId: string): SWRResponseWithUtils<Util, any, Error> => {
   const swrResult = useSWRImmutable(
   const swrResult = useSWRImmutable(
     globalNotificationId != null ? `/notification-setting/global-notification/${globalNotificationId}` : null,
     globalNotificationId != null ? `/notification-setting/global-notification/${globalNotificationId}` : null,
@@ -22,7 +22,7 @@ export const useSWRxGlobalNotification = (globalNotificationId: string): SWRResp
   );
   );
 
 
 
 
-  const update = async(updateData) => {
+  const update = async(updateData: IGlobalNotification) => {
     const { data } = swrResult;
     const { data } = swrResult;
 
 
     if (data == null) {
     if (data == null) {