feat(ui): support multiple folder selection in Google Drive indexing

- Update manage page to handle array of selected folders
- Add info icon with clear description about folder-level indexing
- Display list of all selected folders before indexing
- Remove unnecessary file type details section
- Pass comma-separated folder IDs and names to backend
This commit is contained in:
CREDO23 2025-12-28 16:48:56 +02:00
parent e0edfef5fc
commit 27a4bcdfc2

View file

@ -7,6 +7,7 @@ import {
Edit, Edit,
Folder, Folder,
HardDrive, HardDrive,
Info,
Loader2, Loader2,
Plus, Plus,
RefreshCw, RefreshCw,
@ -117,8 +118,7 @@ export default function ConnectorsPage() {
// Google Drive folder selection state // Google Drive folder selection state
const [driveFolderDialogOpen, setDriveFolderDialogOpen] = useState(false); const [driveFolderDialogOpen, setDriveFolderDialogOpen] = useState(false);
const [driveFolders, setDriveFolders] = useState<DriveFolder[]>([]); const [driveFolders, setDriveFolders] = useState<DriveFolder[]>([]);
const [selectedFolderId, setSelectedFolderId] = useState<string>(""); const [selectedFolders, setSelectedFolders] = useState<Array<{ id: string; name: string }>>([]);
const [selectedFolderName, setSelectedFolderName] = useState<string>("");
const [isLoadingFolders, setIsLoadingFolders] = useState(false); const [isLoadingFolders, setIsLoadingFolders] = useState(false);
useEffect(() => { useEffect(() => {
@ -186,8 +186,8 @@ export default function ConnectorsPage() {
// Handle Google Drive folder indexing // Handle Google Drive folder indexing
const handleIndexDriveFolder = async () => { const handleIndexDriveFolder = async () => {
if (selectedConnectorForIndexing === null || !selectedFolderId) { if (selectedConnectorForIndexing === null || selectedFolders.length === 0) {
toast.error("Please select a folder"); toast.error("Please select at least one folder");
return; return;
} }
@ -195,28 +195,26 @@ export default function ConnectorsPage() {
try { try {
setIndexingConnectorId(selectedConnectorForIndexing); setIndexingConnectorId(selectedConnectorForIndexing);
const selectedFolder = driveFolders.find((f) => f.id === selectedFolderId);
const folderName = selectedFolder?.name || "Selected Folder";
// Call indexConnector with folder_id and folder_name as query params // Call indexConnector with folder_ids and folder_names as query params
await indexConnector( await indexConnector(
selectedConnectorForIndexing, selectedConnectorForIndexing,
searchSpaceId, searchSpaceId,
undefined, undefined,
undefined, undefined,
selectedFolderId, selectedFolders.map((f) => f.id).join(","),
folderName selectedFolders.map((f) => f.name).join(", ")
); );
toast.success(t("indexing_started")); toast.success(t("indexing_started"));
} catch (error) { } catch (error) {
console.error("Error indexing connector content:", error); console.error("Error indexing connector content:", error);
toast.error(error instanceof Error ? error.message : t("indexing_failed")); toast.error(error instanceof Error ? error.message : t("indexing_failed"));
} finally { } finally {
setIndexingConnectorId(null); setIndexingConnectorId(null);
setSelectedConnectorForIndexing(null); setSelectedConnectorForIndexing(null);
setSelectedFolderId(""); setSelectedFolders([]);
setDriveFolders([]); setDriveFolders([]);
} }
}; };
// Handle connector indexing with dates // Handle connector indexing with dates
@ -683,66 +681,62 @@ export default function ConnectorsPage() {
{/* Google Drive Folder Selection Dialog */} {/* Google Drive Folder Selection Dialog */}
<Dialog open={driveFolderDialogOpen} onOpenChange={setDriveFolderDialogOpen}> <Dialog open={driveFolderDialogOpen} onOpenChange={setDriveFolderDialogOpen}>
<DialogContent className="w-auto max-w-full"> <DialogContent className="w-auto max-w-full">
<DialogHeader> <DialogHeader>
<DialogTitle>Select Google Drive Folder</DialogTitle> <DialogTitle>Select Google Drive Folders</DialogTitle>
<DialogDescription className="text-sm"> <DialogDescription className="flex items-start gap-2 text-sm p-2 border mt-1 rounded ">
Browse and select a folder to index. Click folders to expand and see subfolders. <Info className="h-4 w-4 shrink-0 text-blue-500" />
</DialogDescription> <span>
</DialogHeader> Select folders to index. Only files <strong>directly in each folder</strong> will be
<div className="grid gap-4 py-4 overflow-hidden w-full"> processedsubfolders must be selected separately.
</span>
</DialogDescription>
</DialogHeader>
<div className="grid gap-4 overflow-hidden w-full">
<div className="space-y-3 w-full overflow-hidden"> <div className="space-y-3 w-full overflow-hidden">
<Label>Browse Folders</Label> <Label>Browse Folders</Label>
{selectedConnectorForIndexing && ( {selectedConnectorForIndexing && (
<GoogleDriveFolderTree <GoogleDriveFolderTree
connectorId={selectedConnectorForIndexing} connectorId={selectedConnectorForIndexing}
selectedFolderId={selectedFolderId} selectedFolders={selectedFolders}
onSelectFolder={(folderId, folderName) => { onSelectFolders={(folders) => {
setSelectedFolderId(folderId); setSelectedFolders(folders);
setSelectedFolderName(folderName); }}
}} />
/>
)}
<p className="text-xs text-muted-foreground">
Changes to files in this folder will be automatically detected and re-indexed.
</p>
</div>
{selectedFolderId && selectedFolderName && (
<div className="p-3 bg-muted rounded-lg text-sm space-y-2">
<div>
<p className="font-medium mb-1">Selected folder:</p>
<p className="text-sm text-muted-foreground truncate" title={selectedFolderName}>
{selectedFolderName}
</p>
</div>
<div>
<p className="font-medium mb-1">What will be indexed:</p>
<ul className="list-disc list-inside space-y-1 text-muted-foreground text-xs">
<li>Google Docs, Sheets, Slides (as PDFs)</li>
<li>PDFs, Word, Excel, PowerPoint files</li>
<li>Text files, markdown, code files</li>
<li>Images (with OCR if enabled)</li>
</ul>
</div>
</div>
)} )}
</div> </div>
{selectedFolders.length > 0 && (
<div className="p-3 bg-muted rounded-lg text-sm space-y-2">
<div>
<p className="font-medium mb-1">
Selected {selectedFolders.length} folder{selectedFolders.length > 1 ? "s" : ""}:
</p>
<div className="max-h-24 overflow-y-auto">
{selectedFolders.map((folder) => (
<p key={folder.id} className="text-sm text-muted-foreground truncate" title={folder.name}>
{folder.name}
</p>
))}
</div>
</div>
</div>
)}
</div>
<DialogFooter> <DialogFooter>
<Button <Button
variant="outline" variant="outline"
onClick={() => { onClick={() => {
setDriveFolderDialogOpen(false); setDriveFolderDialogOpen(false);
setSelectedConnectorForIndexing(null); setSelectedConnectorForIndexing(null);
setSelectedFolderId(""); setSelectedFolders([]);
setSelectedFolderName(""); setDriveFolders([]);
setDriveFolders([]); }}
}} >
> {tCommon("cancel")}
{tCommon("cancel")} </Button>
</Button> <Button onClick={handleIndexDriveFolder} disabled={selectedFolders.length === 0}>
<Button onClick={handleIndexDriveFolder} disabled={!selectedFolderId}> {t("start_indexing")}
{t("start_indexing")} </Button>
</Button> </DialogFooter>
</DialogFooter>
</DialogContent> </DialogContent>
</Dialog> </Dialog>