wip commit

This commit is contained in:
Brent O'Neill 2025-10-03 15:30:45 -06:00
parent 1eb0fb3593
commit 01084d2a89
5 changed files with 55 additions and 28 deletions

View file

@ -328,7 +328,7 @@ export default function UploadProviderPage() {
return ( return (
<div className="container mx-auto max-w-3xl p-6"> <div className="container mx-auto max-w-3xl p-6">
<div className="mb-8 flex gap-2 items-center"> <div className="mb- flex gap-2 items-center">
<Button variant="ghost" onClick={() => router.back()} size="icon"> <Button variant="ghost" onClick={() => router.back()} size="icon">
<ArrowLeft size={18} /> <ArrowLeft size={18} />
</Button> </Button>
@ -366,12 +366,9 @@ export default function UploadProviderPage() {
disabled={selectedFiles.length === 0 || isIngesting} disabled={selectedFiles.length === 0 || isIngesting}
> >
{isIngesting ? ( {isIngesting ? (
<> <>Ingesting {selectedFiles.length} Files...</>
Ingesting {selectedFiles.length} file
{selectedFiles.length > 1 ? "s" : ""}...
</>
) : ( ) : (
<>Ingest files</> <>Start ingest</>
)} )}
</Button> </Button>
</div> </div>

View file

@ -1,10 +1,15 @@
"use client"; "use client";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { FileText, Folder, Trash } from "lucide-react"; import { FileText, Folder, Trash, Trash2 } from "lucide-react";
import { CloudFile } from "./types"; import { CloudFile } from "./types";
import GoogleDriveIcon from "@/app/settings/icons/google-drive-icon";
import SharePointIcon from "@/app/settings/icons/share-point-icon";
import OneDriveIcon from "@/app/settings/icons/one-drive-icon";
import { Button } from "@/components/ui/button";
interface FileItemProps { interface FileItemProps {
provider: string;
file: CloudFile; file: CloudFile;
onRemove: (fileId: string) => void; onRemove: (fileId: string) => void;
} }
@ -41,27 +46,43 @@ const formatFileSize = (bytes?: number) => {
return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${sizes[i]}`; return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${sizes[i]}`;
}; };
export const FileItem = ({ file, onRemove }: FileItemProps) => ( const getProviderIcon = (provider: string) => {
switch (provider) {
case "google_drive":
return <GoogleDriveIcon />;
case "onedrive":
return <OneDriveIcon />;
case "sharepoint":
return <SharePointIcon />;
default:
return <FileText className="h-6 w-6" />;
}
};
export const FileItem = ({ file, onRemove, provider }: FileItemProps) => (
<div <div
key={file.id} key={file.id}
className="flex items-center justify-between p-2 rounded-md text-xs" className="flex items-center justify-between p-2 rounded-md text-xs"
> >
<div className="flex items-center gap-2 flex-1 min-w-0"> <div className="flex items-center gap-2 flex-1 min-w-0">
{getFileIcon(file.mimeType)} {provider ? getProviderIcon(provider) : getFileIcon(file.mimeType)}
<span className="truncate font-medium text-sm mr-2">{file.name}</span> <span className="truncate font-medium text-sm mr-2">{file.name}</span>
<Badge variant="secondary" className="text-xs px-1 py-0.5 h-auto"> <Badge variant="secondary" className="text-xs px-1 py-0.5 h-auto">
{getMimeTypeLabel(file.mimeType)} {getMimeTypeLabel(file.mimeType)}
</Badge> </Badge>
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-1">
<span className="text-xs text-muted-foreground mr-4" title="file size"> <span className="text-xs text-muted-foreground mr-4" title="file size">
{formatFileSize(file.size) || "—"} {formatFileSize(file.size) || "—"}
</span> </span>
<Button
<Trash className="text-muted-foreground hover:text-destructive"
className="text-muted-foreground w-5 h-5 cursor-pointer hover:text-destructive" size="icon"
variant="ghost"
onClick={() => onRemove(file.id)} onClick={() => onRemove(file.id)}
/> >
<Trash2 size={16} />
</Button>
</div> </div>
</div> </div>
); );

View file

@ -5,12 +5,14 @@ import { CloudFile } from "./types";
import { FileItem } from "./file-item"; import { FileItem } from "./file-item";
interface FileListProps { interface FileListProps {
provider: string;
files: CloudFile[]; files: CloudFile[];
onClearAll: () => void; onClearAll: () => void;
onRemoveFile: (fileId: string) => void; onRemoveFile: (fileId: string) => void;
} }
export const FileList = ({ export const FileList = ({
provider,
files, files,
onClearAll, onClearAll,
onRemoveFile, onRemoveFile,
@ -22,19 +24,25 @@ export const FileList = ({
return ( return (
<div className="space-y-2"> <div className="space-y-2">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<p className="text-sm font-medium">Added files</p> <p className="text-sm font-medium">Added files ({files.length})</p>
<Button <Button
ignoreTitleCase={true}
onClick={onClearAll} onClick={onClearAll}
size="sm" size="sm"
variant="ghost" variant="ghost"
className="text-sm text-muted-foreground" className="text-sm text-muted-foreground"
> >
Clear all Remove all
</Button> </Button>
</div> </div>
<div className="max-h-64 overflow-y-auto space-y-1"> <div className="max-h-64 overflow-y-auto space-y-1">
{files.map(file => ( {files.map((file) => (
<FileItem key={file.id} file={file} onRemove={onRemoveFile} /> <FileItem
key={file.id}
file={file}
onRemove={onRemoveFile}
provider={provider}
/>
))} ))}
</div> </div>
</div> </div>

View file

@ -44,7 +44,7 @@ export const IngestSettings = ({
<Collapsible <Collapsible
open={isOpen} open={isOpen}
onOpenChange={onOpenChange} onOpenChange={onOpenChange}
className="border rounded-md p-4 border-muted-foreground/20" className="border rounded-xl p-4 border-border"
> >
<CollapsibleTrigger className="flex items-center gap-2 justify-between w-full -m-4 p-4 rounded-md transition-colors"> <CollapsibleTrigger className="flex items-center gap-2 justify-between w-full -m-4 p-4 rounded-md transition-colors">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@ -65,7 +65,7 @@ export const IngestSettings = ({
<Input <Input
type="number" type="number"
value={currentSettings.chunkSize} value={currentSettings.chunkSize}
onChange={e => onChange={(e) =>
handleSettingsChange({ handleSettingsChange({
chunkSize: parseInt(e.target.value) || 0, chunkSize: parseInt(e.target.value) || 0,
}) })
@ -77,7 +77,7 @@ export const IngestSettings = ({
<Input <Input
type="number" type="number"
value={currentSettings.chunkOverlap} value={currentSettings.chunkOverlap}
onChange={e => onChange={(e) =>
handleSettingsChange({ handleSettingsChange({
chunkOverlap: parseInt(e.target.value) || 0, chunkOverlap: parseInt(e.target.value) || 0,
}) })
@ -95,7 +95,7 @@ export const IngestSettings = ({
</div> </div>
<Switch <Switch
checked={currentSettings.ocr} checked={currentSettings.ocr}
onCheckedChange={checked => onCheckedChange={(checked) =>
handleSettingsChange({ ocr: checked }) handleSettingsChange({ ocr: checked })
} }
/> />
@ -112,7 +112,7 @@ export const IngestSettings = ({
</div> </div>
<Switch <Switch
checked={currentSettings.pictureDescriptions} checked={currentSettings.pictureDescriptions}
onCheckedChange={checked => onCheckedChange={(checked) =>
handleSettingsChange({ pictureDescriptions: checked }) handleSettingsChange({ pictureDescriptions: checked })
} }
/> />
@ -126,7 +126,7 @@ export const IngestSettings = ({
<Input <Input
disabled disabled
value={currentSettings.embeddingModel} value={currentSettings.embeddingModel}
onChange={e => onChange={(e) =>
handleSettingsChange({ embeddingModel: e.target.value }) handleSettingsChange({ embeddingModel: e.target.value })
} }
placeholder="text-embedding-3-small" placeholder="text-embedding-3-small"

View file

@ -116,7 +116,7 @@ export const UnifiedCloudPicker = ({
const handler = createProviderHandler( const handler = createProviderHandler(
provider, provider,
accessToken, accessToken,
isOpen => { (isOpen) => {
setIsPickerOpen(isOpen); setIsPickerOpen(isOpen);
onPickerStateChange?.(isOpen); onPickerStateChange?.(isOpen);
}, },
@ -126,8 +126,8 @@ export const UnifiedCloudPicker = ({
handler.openPicker((files: CloudFile[]) => { handler.openPicker((files: CloudFile[]) => {
// Merge new files with existing ones, avoiding duplicates // Merge new files with existing ones, avoiding duplicates
const existingIds = new Set(selectedFiles.map(f => f.id)); const existingIds = new Set(selectedFiles.map((f) => f.id));
const newFiles = files.filter(f => !existingIds.has(f.id)); const newFiles = files.filter((f) => !existingIds.has(f.id));
onFileSelected([...selectedFiles, ...newFiles]); onFileSelected([...selectedFiles, ...newFiles]);
}); });
} catch (error) { } catch (error) {
@ -138,7 +138,7 @@ export const UnifiedCloudPicker = ({
}; };
const handleRemoveFile = (fileId: string) => { const handleRemoveFile = (fileId: string) => {
const updatedFiles = selectedFiles.filter(file => file.id !== fileId); const updatedFiles = selectedFiles.filter((file) => file.id !== fileId);
onFileSelected(updatedFiles); onFileSelected(updatedFiles);
}; };
@ -179,6 +179,7 @@ export const UnifiedCloudPicker = ({
/> />
<FileList <FileList
provider={provider}
files={selectedFiles} files={selectedFiles}
onClearAll={handleClearAll} onClearAll={handleClearAll}
onRemoveFile={handleRemoveFile} onRemoveFile={handleRemoveFile}