|
@@ -3,13 +3,15 @@ import React, { useCallback, useEffect, useState } from 'react';
|
|
|
import { useTranslation } from 'react-i18next';
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
|
|
|
|
import { useGenerateTransferKeyWithThrottle } from '~/client/services/g2g-transfer';
|
|
import { useGenerateTransferKeyWithThrottle } from '~/client/services/g2g-transfer';
|
|
|
-import { toastError } from '~/client/util/apiNotification';
|
|
|
|
|
|
|
+import { toastError, toastSuccess } from '~/client/util/apiNotification';
|
|
|
import { apiv3Get, apiv3Post } from '~/client/util/apiv3-client';
|
|
import { apiv3Get, apiv3Post } from '~/client/util/apiv3-client';
|
|
|
|
|
+import { G2G_PROGRESS_STATUS, type G2GProgress } from '~/interfaces/g2g-transfer';
|
|
|
import { useAdminSocket } from '~/stores/socket-io';
|
|
import { useAdminSocket } from '~/stores/socket-io';
|
|
|
|
|
|
|
|
import CustomCopyToClipBoard from '../Common/CustomCopyToClipBoard';
|
|
import CustomCopyToClipBoard from '../Common/CustomCopyToClipBoard';
|
|
|
|
|
|
|
|
import G2GDataTransferExportForm from './G2GDataTransferExportForm';
|
|
import G2GDataTransferExportForm from './G2GDataTransferExportForm';
|
|
|
|
|
+import G2GDataTransferStatusIcon from './G2GDataTransferStatusIcon';
|
|
|
|
|
|
|
|
const IGNORED_COLLECTION_NAMES = [
|
|
const IGNORED_COLLECTION_NAMES = [
|
|
|
'sessions', 'rlflx', 'activities', 'attachmentFiles.files', 'attachmentFiles.chunks',
|
|
'sessions', 'rlflx', 'activities', 'attachmentFiles.files', 'attachmentFiles.chunks',
|
|
@@ -25,7 +27,10 @@ const G2GDataTransfer = (): JSX.Element => {
|
|
|
const [optionsMap, setOptionsMap] = useState<any>({});
|
|
const [optionsMap, setOptionsMap] = useState<any>({});
|
|
|
const [isShowExportForm, setShowExportForm] = useState(false);
|
|
const [isShowExportForm, setShowExportForm] = useState(false);
|
|
|
const [isTransferring, setTransferring] = useState(false);
|
|
const [isTransferring, setTransferring] = useState(false);
|
|
|
- const [statusMessage, setStatusMessage] = useState<string | undefined>(undefined);
|
|
|
|
|
|
|
+ const [g2gProgress, setG2GProgress] = useState<G2GProgress>({
|
|
|
|
|
+ mongo: G2G_PROGRESS_STATUS.PENDING,
|
|
|
|
|
+ attachments: G2G_PROGRESS_STATUS.PENDING,
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
const updateSelectedCollections = (newSelectedCollections: Set<string>) => {
|
|
const updateSelectedCollections = (newSelectedCollections: Set<string>) => {
|
|
|
setSelectedCollections(newSelectedCollections);
|
|
setSelectedCollections(newSelectedCollections);
|
|
@@ -56,36 +61,25 @@ const G2GDataTransfer = (): JSX.Element => {
|
|
|
|
|
|
|
|
const setupWebsocketEventHandler = useCallback(() => {
|
|
const setupWebsocketEventHandler = useCallback(() => {
|
|
|
if (socket != null) {
|
|
if (socket != null) {
|
|
|
- socket.on('admin:onStartTransferMongoData', () => {
|
|
|
|
|
- setTransferring(true);
|
|
|
|
|
- setStatusMessage(t('Transferring DB data ...'));
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- socket.on('admin:onStartTransferAttachments', () => {
|
|
|
|
|
- setStatusMessage(t('Transferring attachment files ...'));
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ socket.on('admin:g2gProgress', (g2gProgress: G2GProgress) => {
|
|
|
|
|
+ setG2GProgress(g2gProgress);
|
|
|
|
|
|
|
|
- socket.on('admin:onFinishTransfer', () => {
|
|
|
|
|
- setTransferring(false);
|
|
|
|
|
- setStatusMessage(t('Successfully transferred GROWI. Now you can use new GROWI !'));
|
|
|
|
|
|
|
+ if (g2gProgress.mongo === G2G_PROGRESS_STATUS.COMPLETED && g2gProgress.attachments === G2G_PROGRESS_STATUS.COMPLETED) {
|
|
|
|
|
+ toastSuccess(t('admin:g2g:transfer_success'));
|
|
|
|
|
+ }
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- socket.on('admin:onG2gError', ({ key }) => {
|
|
|
|
|
|
|
+ socket.on('admin:g2gError', ({ key }) => {
|
|
|
setTransferring(false);
|
|
setTransferring(false);
|
|
|
- setStatusMessage(t(key));
|
|
|
|
|
|
|
+ toastError(t(key));
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
- }, [socket, t]);
|
|
|
|
|
|
|
+ }, [socket, t, setTransferring, setG2GProgress]);
|
|
|
|
|
|
|
|
const cleanUpWebsocketEventHandler = useCallback(() => {
|
|
const cleanUpWebsocketEventHandler = useCallback(() => {
|
|
|
if (socket != null) {
|
|
if (socket != null) {
|
|
|
- socket.off('admin:onStartTransferMongoData');
|
|
|
|
|
-
|
|
|
|
|
- socket.off('admin:onStartTransferAttachments');
|
|
|
|
|
-
|
|
|
|
|
- socket.off('admin:onFinishTransfer');
|
|
|
|
|
-
|
|
|
|
|
- socket.off('admin:onG2gError');
|
|
|
|
|
|
|
+ socket.off('admin:g2gProgress');
|
|
|
|
|
+ socket.off('admin:g2gError');
|
|
|
}
|
|
}
|
|
|
}, [socket]);
|
|
}, [socket]);
|
|
|
|
|
|
|
@@ -97,6 +91,7 @@ const G2GDataTransfer = (): JSX.Element => {
|
|
|
|
|
|
|
|
const startTransfer = useCallback(async(e) => {
|
|
const startTransfer = useCallback(async(e) => {
|
|
|
e.preventDefault();
|
|
e.preventDefault();
|
|
|
|
|
+ setTransferring(true);
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
await apiv3Post('/g2g-transfer/transfer', {
|
|
await apiv3Post('/g2g-transfer/transfer', {
|
|
@@ -108,13 +103,16 @@ const G2GDataTransfer = (): JSX.Element => {
|
|
|
catch (errs) {
|
|
catch (errs) {
|
|
|
toastError(errs);
|
|
toastError(errs);
|
|
|
}
|
|
}
|
|
|
- }, [startTransferKey, selectedCollections, optionsMap]);
|
|
|
|
|
|
|
+ }, [setTransferring, startTransferKey, selectedCollections, optionsMap]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
|
setCollectionsAndSelectedCollections();
|
|
setCollectionsAndSelectedCollections();
|
|
|
-
|
|
|
|
|
setupWebsocketEventHandler();
|
|
setupWebsocketEventHandler();
|
|
|
- }, [setCollectionsAndSelectedCollections, setupWebsocketEventHandler]);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ return () => {
|
|
|
|
|
+ cleanUpWebsocketEventHandler();
|
|
|
|
|
+ };
|
|
|
|
|
+ }, [setCollectionsAndSelectedCollections, setupWebsocketEventHandler, cleanUpWebsocketEventHandler]);
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
<div data-testid="admin-export-archive-data">
|
|
<div data-testid="admin-export-archive-data">
|
|
@@ -153,16 +151,15 @@ const G2GDataTransfer = (): JSX.Element => {
|
|
|
</div>
|
|
</div>
|
|
|
</form>
|
|
</form>
|
|
|
|
|
|
|
|
-
|
|
|
|
|
- {statusMessage != null && (
|
|
|
|
|
- <>
|
|
|
|
|
- <div className='alert alert-info d-flex align-items-center'>
|
|
|
|
|
- {isTransferring && (
|
|
|
|
|
- <i className="fa fa-2x fa-spinner fa-pulse mr-2"></i>
|
|
|
|
|
- )}
|
|
|
|
|
- <p className="mb-0">{statusMessage}</p>
|
|
|
|
|
|
|
+ {isTransferring && (
|
|
|
|
|
+ <div className='border rounded p-4'>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <G2GDataTransferStatusIcon className='mr-2 mb-2' status={g2gProgress.mongo} /> MongoDB
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <G2GDataTransferStatusIcon className='mr-2' status={g2gProgress.attachments} /> Attachments
|
|
|
</div>
|
|
</div>
|
|
|
- </>
|
|
|
|
|
|
|
+ </div>
|
|
|
)}
|
|
)}
|
|
|
|
|
|
|
|
<h2 className="border-bottom mt-5">{t('admin:g2g_data_transfer.transfer_data_to_this_growi')}</h2>
|
|
<h2 className="border-bottom mt-5">{t('admin:g2g_data_transfer.transfer_data_to_this_growi')}</h2>
|