diff --git a/frontend/src/components/sharepoint-picker.tsx b/frontend/src/components/sharepoint-picker.tsx deleted file mode 100644 index 0ca82646..00000000 --- a/frontend/src/components/sharepoint-picker.tsx +++ /dev/null @@ -1,455 +0,0 @@ -"use client" - -import { useState, useEffect } from "react" -import { Button } from "@/components/ui/button" -import { Badge } from "@/components/ui/badge" -import { Card, CardContent } from "@/components/ui/card" -import { FileText, Folder, Plus, Trash2, ArrowLeft, Building2 } from "lucide-react" - -interface SharePointPickerProps { - onFileSelected: (files: SharePointFile[]) => void - selectedFiles?: SharePointFile[] - isAuthenticated: boolean - accessToken?: string - onPickerStateChange?: (isOpen: boolean) => void -} - -interface SharePointFile { - id: string - name: string - mimeType?: string - webUrl?: string - driveItem?: { - file?: { mimeType: string } - folder?: unknown - } - parentReference?: { - siteId?: string - driveId?: string - } -} - -interface SharePointSite { - id: string - displayName: string - name: string - webUrl: string -} - -interface GraphResponse { - value: SharePointFile[] | SharePointSite[] -} - -export function SharePointPicker({ - onFileSelected, - selectedFiles = [], - isAuthenticated, - accessToken, - onPickerStateChange -}: SharePointPickerProps) { - const [isLoading, setIsLoading] = useState(false) - const [files, setFiles] = useState([]) - const [sites, setSites] = useState([]) - const [isPickerOpen, setIsPickerOpen] = useState(false) - const [currentView, setCurrentView] = useState<'sites' | 'drives' | 'files'>('sites') - const [currentSite, setCurrentSite] = useState(null) - const [currentDrive, setCurrentDrive] = useState(null) - const [currentPath, setCurrentPath] = useState('') - const [breadcrumbs, setBreadcrumbs] = useState<{id: string, name: string, type: 'site' | 'drive' | 'folder'}[]>([ - {id: 'root', name: 'SharePoint Sites', type: 'site'} - ]) - - const fetchSites = async () => { - if (!accessToken) return - - setIsLoading(true) - try { - const response = await fetch('https://graph.microsoft.com/v1.0/sites?search=*', { - headers: { - 'Authorization': `Bearer ${accessToken}`, - 'Content-Type': 'application/json' - } - }) - - if (response.ok) { - const data: { value: SharePointSite[] } = await response.json() - setSites(data.value || []) - } else { - console.error('Failed to fetch SharePoint sites:', response.statusText) - } - } catch (error) { - console.error('Error fetching SharePoint sites:', error) - } finally { - setIsLoading(false) - } - } - - const fetchDrives = async (siteId: string) => { - if (!accessToken) return - - setIsLoading(true) - try { - const response = await fetch(`https://graph.microsoft.com/v1.0/sites/${siteId}/drives`, { - headers: { - 'Authorization': `Bearer ${accessToken}`, - 'Content-Type': 'application/json' - } - }) - - if (response.ok) { - const data: GraphResponse = await response.json() - // Convert drives to file-like objects for display - const driveFiles: SharePointFile[] = (data.value as any[]).map(drive => ({ - id: drive.id, - name: drive.name || 'Document Library', - driveItem: { folder: {} }, // Mark as folder - webUrl: drive.webUrl - })) - setFiles(driveFiles) - } else { - console.error('Failed to fetch drives:', response.statusText) - } - } catch (error) { - console.error('Error fetching drives:', error) - } finally { - setIsLoading(false) - } - } - - const fetchFiles = async (path: string) => { - if (!accessToken || !currentSite || !currentDrive) return - - setIsLoading(true) - try { - const url = path || `https://graph.microsoft.com/v1.0/sites/${currentSite.id}/drives/${currentDrive}/root/children` - const response = await fetch(url, { - headers: { - 'Authorization': `Bearer ${accessToken}`, - 'Content-Type': 'application/json' - } - }) - - if (response.ok) { - const data: GraphResponse = await response.json() - setFiles(data.value as SharePointFile[] || []) - } else { - console.error('Failed to fetch SharePoint files:', response.statusText) - } - } catch (error) { - console.error('Error fetching SharePoint files:', error) - } finally { - setIsLoading(false) - } - } - - const openPicker = () => { - if (!accessToken) return - - setIsPickerOpen(true) - onPickerStateChange?.(true) - setCurrentView('sites') - fetchSites() - } - - const closePicker = () => { - setIsPickerOpen(false) - onPickerStateChange?.(false) - setFiles([]) - setSites([]) - setCurrentView('sites') - setCurrentSite(null) - setCurrentDrive(null) - setCurrentPath('') - setBreadcrumbs([{id: 'root', name: 'SharePoint Sites', type: 'site'}]) - } - - const handleSiteClick = (site: SharePointSite) => { - setCurrentSite(site) - setCurrentView('drives') - setBreadcrumbs([ - {id: 'root', name: 'SharePoint Sites', type: 'site'}, - {id: site.id, name: site.displayName, type: 'site'} - ]) - fetchDrives(site.id) - } - - const handleDriveClick = (drive: SharePointFile) => { - setCurrentDrive(drive.id) - setCurrentView('files') - setBreadcrumbs([ - {id: 'root', name: 'SharePoint Sites', type: 'site'}, - {id: currentSite!.id, name: currentSite!.displayName, type: 'site'}, - {id: drive.id, name: drive.name, type: 'drive'} - ]) - fetchFiles('') - } - - const handleFileClick = (file: SharePointFile) => { - if (file.driveItem?.folder) { - // Navigate to folder - const newPath = `https://graph.microsoft.com/v1.0/sites/${currentSite!.id}/drives/${currentDrive}/items/${file.id}/children` - setCurrentPath(newPath) - setBreadcrumbs([...breadcrumbs, {id: file.id, name: file.name, type: 'folder'}]) - fetchFiles(newPath) - } else { - // Select file - allow multiple selections - const isAlreadySelected = selectedFiles.some(f => f.id === file.id) - if (isAlreadySelected) { - // Deselect if already selected - const updatedFiles = selectedFiles.filter(f => f.id !== file.id) - onFileSelected(updatedFiles) - } else { - // Add to selection - onFileSelected([...selectedFiles, file]) - } - } - } - - const navigateBack = () => { - if (breadcrumbs.length > 1) { - const newBreadcrumbs = breadcrumbs.slice(0, -1) - setBreadcrumbs(newBreadcrumbs) - const lastCrumb = newBreadcrumbs[newBreadcrumbs.length - 1] - - if (lastCrumb.type === 'site' && lastCrumb.id === 'root') { - // Back to sites - setCurrentView('sites') - setCurrentSite(null) - setCurrentDrive(null) - fetchSites() - } else if (lastCrumb.type === 'site') { - // Back to drives - setCurrentView('drives') - setCurrentDrive(null) - fetchDrives(lastCrumb.id) - } else if (lastCrumb.type === 'drive') { - // Back to root of drive - setCurrentView('files') - setCurrentPath('') - fetchFiles('') - } else { - // Back to parent folder - const parentCrumb = newBreadcrumbs[newBreadcrumbs.length - 2] - if (parentCrumb.type === 'drive') { - setCurrentPath('') - fetchFiles('') - } else { - const newPath = `https://graph.microsoft.com/v1.0/sites/${currentSite!.id}/drives/${currentDrive}/items/${lastCrumb.id}/children` - setCurrentPath(newPath) - fetchFiles(newPath) - } - } - } - } - - const removeFile = (fileId: string) => { - const updatedFiles = selectedFiles.filter(file => file.id !== fileId) - onFileSelected(updatedFiles) - } - - const getFileIcon = (item: SharePointFile | SharePointSite) => { - if ('displayName' in item) { - return - } - if (item.driveItem?.folder) { - return - } - return - } - - const getMimeTypeLabel = (file: SharePointFile) => { - const mimeType = file.driveItem?.file?.mimeType || file.mimeType || '' - const typeMap: { [key: string]: string } = { - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'Word Doc', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'Excel', - 'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'PowerPoint', - 'application/pdf': 'PDF', - 'text/plain': 'Text', - 'image/jpeg': 'Image', - 'image/png': 'Image', - } - - if (file.driveItem?.folder) return 'Folder' - return typeMap[mimeType] || 'Document' - } - - if (!isAuthenticated) { - return ( - - -

- Please connect to SharePoint first to select specific files. -

-
-
- ) - } - - if (!accessToken) { - return ( - - -

- Access token unavailable -

-

- Try disconnecting and reconnecting your SharePoint account. -

-
-
- ) - } - - return ( -
- {!isPickerOpen ? ( - - -

- Select files from SharePoint to ingest. -

- -
-
- ) : ( - - -
-

Select Files from SharePoint

- -
- - {/* Navigation */} -
- {breadcrumbs.length > 1 && ( - - )} -
- {breadcrumbs.map((crumb, index) => ( - - {index > 0 && /} - {crumb.name} - - ))} -
-
- - {/* Content List */} -
- {isLoading ? ( -
Loading...
- ) : currentView === 'sites' ? ( - sites.length === 0 ? ( -
No sites found
- ) : ( -
- {sites.map((site) => ( -
handleSiteClick(site)} - > -
- {getFileIcon(site)} - {site.displayName} - - Site - -
- Click to open -
- ))} -
- ) - ) : files.length === 0 ? ( -
No files found
- ) : ( -
- {files.map((file) => ( -
currentView === 'drives' ? handleDriveClick(file) : handleFileClick(file)} - > -
- {getFileIcon(file)} - {file.name} - - {currentView === 'drives' ? 'Library' : getMimeTypeLabel(file)} - -
- {currentView === 'files' && selectedFiles.some(f => f.id === file.id) ? ( - Selected - ) : file.driveItem?.folder || currentView === 'drives' ? ( - Click to open - ) : ( - Click to select - )} -
- ))} -
- )} -
-
-
- )} - - {selectedFiles.length > 0 && ( -
-
-

- Added files -

- -
-
- {selectedFiles.map((file) => ( -
-
- {getFileIcon(file)} - {file.name} - - {getMimeTypeLabel(file)} - -
- -
- ))} -
-
- )} -
- ) -}