import React, { useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useGenerateTransferKeyWithThrottle } from '~/client/services/g2g-transfer'; import { toastError } from '~/client/util/apiNotification'; import { apiv3Get } from '~/client/util/apiv3-client'; import { useAdminSocket } from '~/stores/socket-io'; import customAxios from '~/utils/axios'; import CustomCopyToClipBoard from '../Common/CustomCopyToClipBoard'; import G2GDataTransferExportForm from './G2GDataTransferExportForm'; const IGNORED_COLLECTION_NAMES = [ 'sessions', 'rlflx', 'activities', 'attachmentFiles.files', 'attachmentFiles.chunks', ]; const G2GDataTransfer = (): JSX.Element => { const { data: socket } = useAdminSocket(); const { t } = useTranslation(); const [startTransferKey, setStartTransferKey] = useState(''); const [collections, setCollections] = useState([]); const [selectedCollections, setSelectedCollections] = useState>(new Set()); const [optionsMap, setOptionsMap] = useState({}); const [isShowExportForm, setShowExportForm] = useState(false); const [isTransferring, setTransferring] = useState(false); const [statusMessage, setStatusMessage] = useState(''); const updateSelectedCollections = (newSelectedCollections: Set) => { setSelectedCollections(newSelectedCollections); }; const updateOptionsMap = (newOptionsMap: any) => { setOptionsMap(newOptionsMap); }; const onChangeTransferKeyHandler = useCallback((e) => { setStartTransferKey(e.target.value); }, []); const setCollectionsAndSelectedCollections = useCallback(async() => { const [{ data: collectionsData }, { data: statusData }] = await Promise.all([ apiv3Get<{collections: any[]}>('/mongo/collections', {}), apiv3Get<{status: { zipFileStats: any[], isExporting: boolean, progressList: any[] }}>('/export/status', {}), ]); // filter only not ignored collection names const filteredCollections = collectionsData.collections.filter((collectionName) => { return !IGNORED_COLLECTION_NAMES.includes(collectionName); }); setCollections(filteredCollections); setSelectedCollections(new Set(filteredCollections)); }, []); const setupWebsocketEventHandler = useCallback(() => { 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:onFinishTransfer', () => { setTransferring(false); setStatusMessage(t('Successfully transferred GROWI. Now you can use new GROWI !')); }); } }, [socket, t]); const cleanUpWebsocketEventHandler = useCallback(() => { if (socket != null) { socket.off('admin:onStartTransferMongoData'); socket.off('admin:onStartTransferAttachments'); socket.off('admin:onFinishTransfer'); } }, [socket]); const { transferKey, generateTransferKeyWithThrottle } = useGenerateTransferKeyWithThrottle(); const onClickHandler = useCallback(() => { generateTransferKeyWithThrottle(); }, [generateTransferKeyWithThrottle]); const startTransfer = useCallback(async(e) => { e.preventDefault(); try { await customAxios.post('/_api/v3/g2g-transfer/transfer', { transferKey: startTransferKey, collections: Array.from(selectedCollections), optionsMap, }); } catch (errs) { toastError('Failed to transfer'); } }, [startTransferKey, selectedCollections, optionsMap]); useEffect(() => { setCollectionsAndSelectedCollections(); setupWebsocketEventHandler(); return cleanUpWebsocketEventHandler(); }, [setCollectionsAndSelectedCollections, setupWebsocketEventHandler, cleanUpWebsocketEventHandler]); return (

{t('admin:g2g_data_transfer.transfer_data_to_another_growi')}

{collections.length !== 0 && (
)}
{statusMessage != null && ( <>
{statusMessage}
{isTransferring && (
)} )}

{t('admin:g2g_data_transfer.transfer_data_to_this_growi')}

{t('admin:g2g_data_transfer.transfer_key_limit')}

{t('admin:g2g_data_transfer.once_transfer_key_used')}

{t('admin:g2g_data_transfer.transfer_to_growi_cloud')}

); }; export default G2GDataTransfer;