Przeglądaj źródła

Merge pull request #4715 from weseek/imprv/81945-show-unopened-notification-list

Imprv/81945 show unopened notification list
Yuki Takei 4 lat temu
rodzic
commit
f2a39480bb

+ 46 - 26
packages/app/src/components/InAppNotification/InAppNotificationPage.tsx

@@ -8,6 +8,7 @@ import InAppNotificationList from './InAppNotificationList';
 import { useSWRxInAppNotifications } from '../../stores/in-app-notification';
 import PaginationWrapper from '../PaginationWrapper';
 import CustomNavAndContents from '../CustomNavigation/CustomNavAndContents';
+import { InAppNotificationStatuses } from '~/interfaces/in-app-notification';
 
 
 type Props = {
@@ -16,37 +17,45 @@ type Props = {
 
 const InAppNotificationPageBody: FC<Props> = (props) => {
   const { appContainer } = props;
-  const limit = appContainer.config.pageLimitationXL;
-  const [activePage, setActivePage] = useState(1);
-  const offset = (activePage - 1) * limit;
-  const { data: inAppNotificationData } = useSWRxInAppNotifications(limit, offset);
   const { t } = useTranslation();
 
-  if (inAppNotificationData == null) {
-    return (
-      <div className="wiki">
-        <div className="text-muted text-center">
-          <i className="fa fa-2x fa-spinner fa-pulse mr-1"></i>
-        </div>
-      </div>
-    );
-  }
+  const limit = appContainer.config.pageLimitationXL;
+  const [activePageOfAllNotificationCat, setActivePage] = useState(1);
+  const [activePageOfUnopenedNotificationCat, setActiveUnopenedNotificationPage] = useState(1);
 
 
-  const setPageNumber = (selectedPageNumber): void => {
+  const setAllNotificationPageNumber = (selectedPageNumber): void => {
     setActivePage(selectedPageNumber);
   };
 
+  const setUnopenedPageNumber = (selectedPageNumber): void => {
+    setActiveUnopenedNotificationPage(selectedPageNumber);
+  };
+
   // commonize notification lists by 81953
   const AllInAppNotificationList = () => {
+    const offsetOfAllNotificationCat = (activePageOfAllNotificationCat - 1) * limit;
+    const { data: allNotificationData } = useSWRxInAppNotifications(limit, offsetOfAllNotificationCat);
+
+    if (allNotificationData == null) {
+      return (
+        <div className="wiki">
+          <div className="text-muted text-center">
+            <i className="fa fa-2x fa-spinner fa-pulse mr-1"></i>
+          </div>
+        </div>
+      );
+    }
+
+
     return (
       <>
-        <InAppNotificationList inAppNotificationData={inAppNotificationData} />
+        <InAppNotificationList inAppNotificationData={allNotificationData} />
         <PaginationWrapper
-          activePage={activePage}
-          changePage={setPageNumber}
-          totalItemsCount={inAppNotificationData.totalDocs}
-          pagingLimit={inAppNotificationData.limit}
+          activePage={activePageOfAllNotificationCat}
+          changePage={setAllNotificationPageNumber}
+          totalItemsCount={allNotificationData.totalDocs}
+          pagingLimit={allNotificationData.limit}
           align="center"
           size="sm"
         />
@@ -56,6 +65,19 @@ const InAppNotificationPageBody: FC<Props> = (props) => {
 
   // commonize notification lists by 81953
   const UnopenedInAppNotificationList = () => {
+    const offsetOfUnopenedNotificationCat = (activePageOfUnopenedNotificationCat - 1) * limit;
+    const { data: unopendNotificationData } = useSWRxInAppNotifications(limit, offsetOfUnopenedNotificationCat, InAppNotificationStatuses.STATUS_UNOPENED);
+
+    if (unopendNotificationData == null) {
+      return (
+        <div className="wiki">
+          <div className="text-muted text-center">
+            <i className="fa fa-2x fa-spinner fa-pulse mr-1"></i>
+          </div>
+        </div>
+      );
+    }
+
     return (
       <>
         <div className="mb-2 d-flex justify-content-end">
@@ -68,13 +90,12 @@ const InAppNotificationPageBody: FC<Props> = (props) => {
             {t('in_app_notification.mark_all_as_read')}
           </button>
         </div>
-        {/*  TODO: show only unopened notifications by 81945 */}
-        <InAppNotificationList inAppNotificationData={inAppNotificationData} />
+        <InAppNotificationList inAppNotificationData={unopendNotificationData} />
         <PaginationWrapper
-          activePage={activePage}
-          changePage={setPageNumber}
-          totalItemsCount={inAppNotificationData.totalDocs}
-          pagingLimit={inAppNotificationData.limit}
+          activePage={activePageOfUnopenedNotificationCat}
+          changePage={setUnopenedPageNumber}
+          totalItemsCount={unopendNotificationData.totalDocs}
+          pagingLimit={unopendNotificationData.limit}
           align="center"
           size="sm"
         />
@@ -89,7 +110,6 @@ const InAppNotificationPageBody: FC<Props> = (props) => {
       i18n: t('in_app_notification.all'),
       index: 0,
     },
-    // TODO: show unopend notification list by 81945
     external_accounts: {
       Icon: () => <></>,
       Content: UnopenedInAppNotificationList,

+ 4 - 0
packages/app/src/server/routes/apiv3/in-app-notification.ts

@@ -29,6 +29,10 @@ module.exports = (crowi) => {
       limit,
     };
 
+    // set in-app-notification status to categorize
+    if (req.query.status != null) {
+      Object.assign(queryOptions, { status: req.query.status });
+    }
 
     const paginationResult = await inAppNotificationService.getLatestNotificationsByUser(user._id, queryOptions);
 

+ 8 - 4
packages/app/src/server/service/in-app-notification.ts

@@ -1,11 +1,11 @@
 import { Types } from 'mongoose';
 import { subDays } from 'date-fns';
+import { InAppNotificationStatuses, PaginateResult } from '~/interfaces/in-app-notification';
 import Crowi from '../crowi';
 import {
   InAppNotification,
   InAppNotificationDocument,
 } from '~/server/models/in-app-notification';
-import { PaginateResult, InAppNotificationStatuses } from '../../interfaces/in-app-notification';
 
 import { ActivityDocument } from '~/server/models/activity';
 import InAppNotificationSettings from '~/server/models/in-app-notification-settings';
@@ -88,15 +88,19 @@ export default class InAppNotificationService {
 
   getLatestNotificationsByUser = async(
       userId: Types.ObjectId,
-      queryOptions: {offset: number, limit: number},
+      queryOptions: {offset: number, limit: number, status?: InAppNotificationStatuses},
   ): Promise<PaginateResult<InAppNotificationDocument>> => {
-    const { limit, offset } = queryOptions;
+    const { limit, offset, status } = queryOptions;
 
     try {
+      const pagenateOptions = { user: userId };
+      if (status != null) {
+        Object.assign(pagenateOptions, { status });
+      }
       // TODO: import @types/mongoose-paginate-v2 and use PaginateResult as a type after upgrading mongoose v6.0.0
       // eslint-disable-next-line @typescript-eslint/no-explicit-any
       const paginationResult = await (InAppNotification as any).paginate(
-        { user: userId },
+        pagenateOptions,
         {
           sort: { createdAt: -1 },
           limit,

+ 4 - 4
packages/app/src/stores/in-app-notification.ts

@@ -1,15 +1,15 @@
 import useSWR, { SWRResponse } from 'swr';
-
+import { InAppNotificationStatuses, IInAppNotification, PaginateResult } from '~/interfaces/in-app-notification';
 import { apiv3Get } from '../client/util/apiv3-client';
-import { IInAppNotification, PaginateResult } from '../interfaces/in-app-notification';
 
 // eslint-disable-next-line @typescript-eslint/no-unused-vars
 export const useSWRxInAppNotifications = <Data, Error>(
   limit: number,
   offset?: number,
+  status?: InAppNotificationStatuses,
 ): SWRResponse<PaginateResult<IInAppNotification>, Error> => {
   return useSWR(
-    ['/in-app-notification/list', limit, offset],
-    endpoint => apiv3Get(endpoint, { limit, offset }).then(response => response.data),
+    ['/in-app-notification/list', limit, offset, status],
+    endpoint => apiv3Get(endpoint, { limit, offset, status }).then(response => response.data),
   );
 };