File size: 4,087 Bytes
f0743f4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | import { useCallback, useState } from 'react';
import { useToastContext } from '@librechat/client';
import type { SharePointFile, SharePointBatchProgress } from '~/data-provider/Files';
import { useSharePointBatchDownload } from '~/data-provider/Files';
import useSharePointToken from './useSharePointToken';
interface UseSharePointDownloadProps {
onFilesDownloaded?: (files: File[]) => void | Promise<void>;
onError?: (error: Error) => void;
}
interface UseSharePointDownloadReturn {
downloadSharePointFiles: (files: SharePointFile[]) => Promise<File[]>;
isDownloading: boolean;
downloadProgress: SharePointBatchProgress | null;
error: string | null;
}
export default function useSharePointDownload({
onFilesDownloaded,
onError,
}: UseSharePointDownloadProps = {}): UseSharePointDownloadReturn {
const { showToast } = useToastContext();
const [downloadProgress, setDownloadProgress] = useState<SharePointBatchProgress | null>(null);
const [error, setError] = useState<string | null>(null);
const { token, refetch: refetchToken } = useSharePointToken({
enabled: false,
purpose: 'Download',
});
const batchDownloadMutation = useSharePointBatchDownload();
const downloadSharePointFiles = useCallback(
async (files: SharePointFile[]): Promise<File[]> => {
if (!files || files.length === 0) {
throw new Error('No files provided for download');
}
setError(null);
setDownloadProgress({ completed: 0, total: files.length, failed: [] });
try {
let accessToken = token?.access_token;
if (!accessToken) {
showToast({
message: 'Getting SharePoint access token...',
status: 'info',
duration: 2000,
});
const tokenResult = await refetchToken();
accessToken = tokenResult.data?.access_token;
if (!accessToken) {
throw new Error('Failed to obtain SharePoint access token');
}
}
showToast({
message: `Downloading ${files.length} file(s) from SharePoint...`,
status: 'info',
duration: 3000,
});
const downloadedFiles = await batchDownloadMutation.mutateAsync({
files,
accessToken,
onProgress: (progress) => {
setDownloadProgress(progress);
if (files.length > 5 && progress.completed % 3 === 0) {
showToast({
message: `Downloaded ${progress.completed}/${progress.total} files...`,
status: 'info',
duration: 1000,
});
}
},
});
if (downloadedFiles.length > 0) {
const failedCount = files.length - downloadedFiles.length;
const successMessage =
failedCount > 0
? `Downloaded ${downloadedFiles.length}/${files.length} files from SharePoint (${failedCount} failed)`
: `Successfully downloaded ${downloadedFiles.length} file(s) from SharePoint`;
showToast({
message: successMessage,
status: failedCount > 0 ? 'warning' : 'success',
duration: 4000,
});
if (onFilesDownloaded) {
await onFilesDownloaded(downloadedFiles);
}
}
setDownloadProgress(null);
return downloadedFiles;
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown download error';
setError(errorMessage);
showToast({
message: `SharePoint download failed: ${errorMessage}`,
status: 'error',
duration: 5000,
});
if (onError) {
onError(error instanceof Error ? error : new Error(errorMessage));
}
setDownloadProgress(null);
throw error;
}
},
[token, showToast, batchDownloadMutation, onFilesDownloaded, onError, refetchToken],
);
return {
downloadSharePointFiles,
isDownloading: batchDownloadMutation.isLoading,
downloadProgress,
error,
};
}
|