yuken 4 лет назад
Родитель
Сommit
c6bb86eb58

+ 39 - 13
packages/app/src/components/PrivateLegacyPages.tsx

@@ -1,32 +1,33 @@
 import React, {
-  useCallback, useMemo, useRef, useState,
+  useCallback, useMemo, useRef, useState, useEffect,
 } from 'react';
-import { useTranslation } from 'react-i18next';
 
+import { useTranslation } from 'react-i18next';
 import {
   UncontrolledButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem,
 } from 'reactstrap';
 
-import { IFormattedSearchResult } from '~/interfaces/search';
-import AppContainer from '~/client/services/AppContainer';
 import { ISelectableAll, ISelectableAndIndeterminatable } from '~/client/interfaces/selectable-all';
+import AppContainer from '~/client/services/AppContainer';
 import { toastSuccess } from '~/client/util/apiNotification';
-import {
-  useSWRxSearch,
-} from '~/stores/search';
+import { V5MigrationStatus } from '~/interfaces/page-listing-results';
+import { IFormattedSearchResult } from '~/interfaces/search';
+import { SocketEventName } from '~/interfaces/websocket';
 import {
   ILegacyPrivatePage, useLegacyPrivatePagesMigrationModal,
 } from '~/stores/modal';
+import { useSWRxV5MigrationStatus } from '~/stores/page-listing';
+import {
+  useSWRxSearch,
+} from '~/stores/search';
+import { useGlobalSocket } from '~/stores/websocket';
 
-import PaginationWrapper from './PaginationWrapper';
-import { OperateAllControl } from './SearchPage/OperateAllControl';
-
-import { IReturnSelectedPageIds, SearchPageBase, usePageDeleteModalForBulkDeletion } from './SearchPage2/SearchPageBase';
 import { MenuItemType } from './Common/Dropdown/PageItemControl';
 import { LegacyPrivatePagesMigrationModal } from './LegacyPrivatePagesMigrationModal';
+import PaginationWrapper from './PaginationWrapper';
+import { OperateAllControl } from './SearchPage/OperateAllControl';
 import SearchControl from './SearchPage/SearchControl';
-import { useSWRxV5MigrationStatus } from '~/stores/page-listing';
-import { V5MigrationStatus } from '~/interfaces/page-listing-results';
+import { IReturnSelectedPageIds, SearchPageBase, usePageDeleteModalForBulkDeletion } from './SearchPage2/SearchPageBase';
 
 
 // TODO: replace with "customize:showPageLimitationS"
@@ -166,6 +167,31 @@ export const PrivateLegacyPages = (props: Props): JSX.Element => {
   }, []);
 
   const { open: openModal, close: closeModal } = useLegacyPrivatePagesMigrationModal();
+  const { data: socket } = useGlobalSocket();
+
+  useEffect(() => {
+
+    socket?.on(SocketEventName.PageMigrationStarted, () => {
+      // page migration started
+      console.log('page migration started');
+    });
+
+    socket?.on(SocketEventName.PageMigrationEnded, () => {
+      // page migration ended
+      console.log('page migration ended');
+    });
+
+    socket?.on(SocketEventName.PageMigrationError, () => {
+      // page migration error
+      console.log('page migration error');
+    });
+
+    return () => {
+      socket?.off(SocketEventName.PageMigrationStarted);
+      socket?.off(SocketEventName.PageMigrationEnded);
+      socket?.off(SocketEventName.PageMigrationError);
+    };
+  }, [socket]);
 
   const selectAllCheckboxChangedHandler = useCallback((isChecked: boolean) => {
     const instance = searchPageBaseRef.current;

+ 5 - 0
packages/app/src/interfaces/websocket.ts

@@ -7,6 +7,11 @@ export const SocketEventName = {
   PMMigrating: 'PublicMigrationMigrating',
   PMErrorCount: 'PublicMigrationErrorCount',
   PMEnded: 'PublicMigrationEnded',
+
+  // Page migration
+  PageMigrationStarted: 'PageMigrationStarted',
+  PageMigrationEnded: 'PageMigrationEnded',
+  PageMigrationError: 'PageMigrationError',
 } as const;
 export type SocketEventName = typeof SocketEventName[keyof typeof SocketEventName];
 

+ 24 - 2
packages/app/src/server/service/page.ts

@@ -2254,11 +2254,26 @@ class PageService {
   async normalizeParentByPageIds(pageIds: ObjectIdLike[], user, isRecursively: boolean): Promise<void> {
     const Page = mongoose.model('Page') as unknown as PageModel;
 
+    const socket = this.crowi.socketIoService.getDefaultSocket();
+
+    // accept page migration --- 1
+    socket.emit(SocketEventName.PageMigrationStarted);
+
     if (isRecursively) {
       const pages = await Page.findByIdsAndViewer(pageIds, user, null);
 
       // DO NOT await !!
-      this.normalizeParentRecursivelyByPages(pages, user);
+      (async() => {
+        try {
+          await this.normalizeParentRecursivelyByPages(pages, user);
+          // page migration ended --- 2
+          socket.emit(SocketEventName.PageMigrationEnded);
+        }
+        catch {
+          // fail page migration --- 3
+          socket.emit(SocketEventName.PageMigrationError);
+        }
+      })();
 
       return;
     }
@@ -2279,11 +2294,18 @@ class PageService {
 
         if (normalizedPage == null) {
           logger.error(`Failed to update descendantCount of page of id: "${pageId}"`);
+          // fail page migrate --- 3
+          socket.emit(SocketEventName.PageMigrationError);
+        }
+        else {
+          // page migrate ended --- 2
+          socket.emit(SocketEventName.PageMigrationEnded);
         }
       }
       catch (err) {
         logger.error('Something went wrong while normalizing parent.', err);
-        // socket.emit('normalizeParentByPageIds', { error: err.message }); TODO: use socket to tell user
+        // fail page migrate --- 3
+        socket.emit(SocketEventName.PageMigrationError);
       }
     }
   }