diff --git a/frontend/src/upload/Upload.tsx b/frontend/src/upload/Upload.tsx index 75749f29..f17c7c95 100644 --- a/frontend/src/upload/Upload.tsx +++ b/frontend/src/upload/Upload.tsx @@ -58,6 +58,8 @@ function Upload({ const [isAuthenticating, setIsAuthenticating] = useState(false); const [userEmail, setUserEmail] = useState(''); const [authError, setAuthError] = useState(''); + const [currentFolderId, setCurrentFolderId] = useState(null); + const [folderPath, setFolderPath] = useState>([{id: null, name: 'My Drive'}]); const renderFormFields = () => { const schema = IngestorFormSchemas[ingestor.type]; @@ -540,7 +542,7 @@ function Upload({ if (validateData.success) { setUserEmail(validateData.user_email || 'Connected User'); - loadGoogleDriveFiles(sessionToken); + loadGoogleDriveFiles(sessionToken, null); } else { localStorage.removeItem('google_drive_session_token'); setIsGoogleDriveConnected(false); @@ -612,7 +614,7 @@ function Upload({ window.removeEventListener('message', handleAuthMessage); - loadGoogleDriveFiles(event.data.session_token); + loadGoogleDriveFiles(event.data.session_token, null); } else if (event.data.type === 'google_drive_auth_error') { console.error('OAuth error received:', event.data); setAuthError(event.data.error || 'Authentication failed. Please make sure to grant all requested permissions, including offline access. You may need to revoke previous access and re-authorize.'); @@ -641,21 +643,26 @@ function Upload({ } }; - const loadGoogleDriveFiles = async (sessionToken: string) => { + const loadGoogleDriveFiles = async (sessionToken: string, folderId?: string | null) => { setIsLoadingFiles(true); try { const apiHost = import.meta.env.VITE_API_HOST; + const requestBody: any = { + session_token: sessionToken, + limit: 50 + }; + if (folderId) { + requestBody.folder_id = folderId; + } + const filesResponse = await fetch(`${apiHost}/api/google-drive/files`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, - body: JSON.stringify({ - session_token: sessionToken, - limit: 50 - }) + body: JSON.stringify(requestBody) }); if (!filesResponse.ok) { @@ -700,6 +707,15 @@ function Upload({ size: '5.8 MB', modifiedTime: '2024-01-13', iconUrl: '�' + }, + { + id: 'folder1', + name: 'Documents', + type: 'application/vnd.google-apps.folder', + size: '0 bytes', + modifiedTime: '2024-01-13', + iconUrl: '📁', + isFolder: true } ]; setGoogleDriveFiles(mockFiles); @@ -719,6 +735,27 @@ function Upload({ }); }; + const handleFolderClick = (folderId: string, folderName: string) => { + const sessionToken = localStorage.getItem('google_drive_session_token'); + if (sessionToken) { + setCurrentFolderId(folderId); + setFolderPath(prev => [...prev, {id: folderId, name: folderName}]); + loadGoogleDriveFiles(sessionToken, folderId); + } + }; + + const navigateBack = (index: number) => { + const sessionToken = localStorage.getItem('google_drive_session_token'); + if (sessionToken) { + const newPath = folderPath.slice(0, index + 1); + const targetFolderId = newPath[newPath.length - 1]?.id; + + setCurrentFolderId(targetFolderId); + setFolderPath(newPath); + loadGoogleDriveFiles(sessionToken, targetFolderId); + } + }; + const handleSelectAll = () => { if (selectedFiles.length === googleDriveFiles.length) { setSelectedFiles([]); @@ -1002,6 +1039,22 @@ function Upload({ {/* File Browser */}
+ {/* Breadcrumb navigation */} +
+ {folderPath.map((path, index) => ( +
+ {index > 0 && /} + +
+ ))} +
+

Select Files from Google Drive @@ -1039,10 +1092,9 @@ function Upload({ {googleDriveFiles.map((file) => (
handleFileSelect(file.id)} >
@@ -1053,9 +1105,31 @@ function Upload({ className="h-4 w-4 text-blue-600 rounded border-gray-300 focus:ring-blue-500" />
-
{file.iconUrl}
+ {file.type === 'application/vnd.google-apps.folder' || file.isFolder ? ( +
handleFolderClick(file.id, file.name)} + > + Folder +
+ ) : ( +
+ File +
+ )}
-

+

{ + if (file.type === 'application/vnd.google-apps.folder' || file.isFolder) { + handleFolderClick(file.id, file.name); + } + }} + > {file.name}