Procházet zdrojové kódy

Merge pull request #6872 from weseek/imprv/108054-typescriptize-ManageGlobalNotification

imprv: TypeScriptize ManageGlobalNotification
Kaori Tokashiki před 3 roky
rodič
revize
04ed24396d

+ 2 - 1
packages/app/public/static/locales/en_US/admin.json

@@ -276,7 +276,8 @@
     "delete_notification_pattern": "Delete notification pattern",
     "delete_notification_pattern_desc1": "Delete Path: {{path}}",
     "delete_notification_pattern_desc2": "Once deleted, it cannot be recovered",
-    "toggle_notification": "Updated setting of {{path}}"
+    "toggle_notification": "Updated setting of {{path}}",
+    "not_found_global_notification_triggerid": "Not found the global notification id"
   },
   "mailer_setup_required":"<a href='/admin/app'>Email settings</a> are required to send.",
   "admin_top": {

+ 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[],
+};

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

@@ -4,17 +4,15 @@ import React, {
 
 import { useTranslation } from 'next-i18next';
 import { useRouter } from 'next/router';
-import PropTypes from 'prop-types';
 
-import AdminNotificationContainer from '~/client/services/AdminNotificationContainer';
+import { NotifyType, TriggerEventType } from '~/client/interfaces/global-notification';
 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 { useSWRxGlobalNotification } from '~/stores/global-notification';
 import loggerFactory from '~/utils/logger';
 
 
-import { withUnstatedContainers } from '../../UnstatedUtils';
 import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
 
 import TriggerEventCheckBox from './TriggerEventCheckBox';
@@ -23,14 +21,18 @@ import TriggerEventCheckBox from './TriggerEventCheckBox';
 const logger = loggerFactory('growi:manageGlobalNotification');
 
 
-const ManageGlobalNotification = (props) => {
+type Props = {
+  globalNotificationId?: string,
+}
+
+const ManageGlobalNotification = (props: Props): JSX.Element => {
 
   const [triggerPath, setTriggerPath] = useState('');
-  const [notifyType, setNotifyType] = useState('mail');
+  const [notifyType, setNotifyType] = useState<NotifyType>(NotifyType.Email);
   const [emailToSend, setEmailToSend] = useState('');
   const [slackChannelToSend, setSlackChannelToSend] = useState('');
   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 router = useRouter();
@@ -44,15 +46,13 @@ const ManageGlobalNotification = (props) => {
       setTriggerPath(globalNotification.triggerPath);
       setTriggerEvents(new Set(globalNotification.triggerEvents));
 
-      if (notifyType === 'mail') {
+      if (notifyType === NotifyType.Email) {
         setEmailToSend(globalNotification.toEmail);
       }
       else {
         setSlackChannelToSend(globalNotification.slackChannels);
       }
     }
-
-
   }, [globalNotification]);
 
   const isLoading = globalNotificationData === undefined;
@@ -88,13 +88,10 @@ const ManageGlobalNotification = (props) => {
       triggerEvents: [...triggerEvents],
     };
 
-    const { _id: globalNotificationId } = globalNotification;
-
     try {
-      if (globalNotificationId != null) {
+      if (props.globalNotificationId != null) {
         await updateGlobalNotification(requestParams);
         router.push('/admin/notification');
-        // await apiv3Put(`/notification-setting/global-notification/${globalNotificationId}`, requestParams);
       }
       else {
         await apiv3Post('/notification-setting/global-notification', requestParams);
@@ -105,11 +102,10 @@ const ManageGlobalNotification = (props) => {
       toastError(err);
       logger.error(err);
     }
-  }, [emailToSend, globalNotification, notifyType, router, slackChannelToSend, triggerEvents, triggerPath, updateGlobalNotification]);
+  }, [emailToSend, notifyType, props.globalNotificationId, router, slackChannelToSend, triggerEvents, triggerPath, updateGlobalNotification]);
 
 
   const { data: isMailerSetup } = useIsMailerSetup();
-  const { adminNotificationContainer } = props;
   const { t } = useTranslation('admin');
 
   return (
@@ -128,9 +124,11 @@ const ManageGlobalNotification = (props) => {
         </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>
+            <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>
           <div className="form-group">
             <input
@@ -152,8 +150,8 @@ const ManageGlobalNotification = (props) => {
                 id="mail"
                 name="notifyType"
                 value="mail"
-                checked={notifyType === 'mail'}
-                onChange={() => { setNotifyType('mail') }}
+                checked={notifyType === NotifyType.Email}
+                onChange={() => { setNotifyType(NotifyType.Email) }}
               />
               <label className="custom-control-label" htmlFor="mail">
                 <p className="font-weight-bold">Email</p>
@@ -166,8 +164,8 @@ const ManageGlobalNotification = (props) => {
                 id="slack"
                 name="notifyType"
                 value="slack"
-                checked={notifyType === 'slack'}
-                onChange={() => { setNotifyType('slack') }}
+                checked={notifyType === NotifyType.SLACK}
+                onChange={() => { setNotifyType(NotifyType.SLACK) }}
               />
               <label className="custom-control-label" htmlFor="slack">
                 <p className="font-weight-bold">Slack</p>
@@ -175,7 +173,7 @@ const ManageGlobalNotification = (props) => {
             </div>
           </div>
 
-          {notifyType === 'mail'
+          {notifyType === NotifyType.Email
             ? (
               <>
                 <div className="input-group notify-to-option" id="mail-input">
@@ -234,9 +232,9 @@ const ManageGlobalNotification = (props) => {
             <div className="my-1">
               <TriggerEventCheckBox
                 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">
                   <i className="icon-doc mr-1" /> CREATE
@@ -246,9 +244,9 @@ const ManageGlobalNotification = (props) => {
             <div className="my-1">
               <TriggerEventCheckBox
                 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">
                   <i className="icon-pencil mr-1" />EDIT
@@ -258,9 +256,9 @@ const ManageGlobalNotification = (props) => {
             <div className="my-1">
               <TriggerEventCheckBox
                 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">
                   <i className="icon-action-redo mr-1" />MOVE
@@ -271,8 +269,8 @@ const ManageGlobalNotification = (props) => {
               <TriggerEventCheckBox
                 checkbox="danger"
                 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">
                   <i className="icon-fire mr-1" />DELETE
@@ -282,9 +280,9 @@ const ManageGlobalNotification = (props) => {
             <div className="my-1">
               <TriggerEventCheckBox
                 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">
                   <i className="fa fa-heart-o mr-1" />LIKE
@@ -294,9 +292,9 @@ const ManageGlobalNotification = (props) => {
             <div className="my-1">
               <TriggerEventCheckBox
                 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">
                   <i className="icon-bubble mr-1" />POST
@@ -310,18 +308,10 @@ const ManageGlobalNotification = (props) => {
 
       <AdminUpdateButtonRow
         onClick={updateButtonClickedHandler}
-        disabled={adminNotificationContainer.state.retrieveError != null}
+        disabled={false}
       />
     </>
   );
 };
 
-ManageGlobalNotification.propTypes = {
-  adminNotificationContainer: PropTypes.instanceOf(AdminNotificationContainer).isRequired,
-  globalNotificationId: PropTypes.string,
-};
-
-const ManageGlobalNotificationWrapper = withUnstatedContainers(ManageGlobalNotification, [AdminNotificationContainer]);
-
-
-export default ManageGlobalNotificationWrapper;
+export default ManageGlobalNotification;

+ 1 - 0
packages/app/src/pages/admin/global-notification/[globalNotificationId].page.tsx

@@ -15,6 +15,7 @@ import { CommonProps, useCustomTitle } from '~/pages/utils/commons';
 
 import { retrieveServerSideProps } from '../../../utils/admin-page-util';
 
+
 const AdminLayout = dynamic(() => import('~/components/Layout/AdminLayout'), { ssr: false });
 const ManageGlobalNotification = dynamic(() => import('~/components/Admin/Notification/ManageGlobalNotification'), { ssr: false });
 

+ 1 - 0
packages/app/src/pages/admin/global-notification/new.page.tsx

@@ -8,6 +8,7 @@ import { Container, Provider } from 'unstated';
 
 import AdminNotificationContainer from '~/client/services/AdminNotificationContainer';
 import { CommonProps, useCustomTitle } from '~/pages/utils/commons';
+
 import { retrieveServerSideProps } from '../../../utils/admin-page-util';
 
 const AdminLayout = dynamic(() => import('~/components/Layout/AdminLayout'), { ssr: false });

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

@@ -1,6 +1,7 @@
 import { SWRResponseWithUtils, withUtils } from '@growi/core';
 import useSWRImmutable from 'swr/immutable';
 
+import { IGlobalNotification } from '~/client/interfaces/global-notification';
 
 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> => {
   const swrResult = useSWRImmutable(
     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;
 
     if (data == null) {