From e749c936c989a9014599d7a1b4943a28dbaa9f4a Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Tue, 9 Sep 2025 13:07:26 +0530 Subject: [PATCH] (refactor:uploads) for new ui --- frontend/src/upload/Upload.tsx | 137 +++++++++++++++++++++----- frontend/src/upload/types/ingestor.ts | 33 ++++++- 2 files changed, 141 insertions(+), 29 deletions(-) diff --git a/frontend/src/upload/Upload.tsx b/frontend/src/upload/Upload.tsx index 76a6cd36..3c42eca0 100644 --- a/frontend/src/upload/Upload.tsx +++ b/frontend/src/upload/Upload.tsx @@ -51,15 +51,10 @@ function Upload({ const [activeTab, setActiveTab] = useState(renderTab); const [showAdvancedOptions, setShowAdvancedOptions] = useState(false); - // Connector state + // File picker state const [selectedFiles, setSelectedFiles] = useState([]); const [selectedFolders, setSelectedFolders] = useState([]); - // Helper function to check if ingestor type is a connector - const isConnectorType = (type: string) => { - return type === 'google_drive' || type === 'onedrive' || type === 'sharepoint'; - }; - @@ -189,6 +184,52 @@ function Upload({ className={`mt-2 text-base`} /> ); + case 'file_picker': + return ( + { + setSelectedFiles(selectedFileIds); + setSelectedFolders(selectedFolderIds); + }} + provider={ingestor.type} + token={token} + initialSelectedFiles={selectedFiles} + initialSelectedFolders={selectedFolders} + /> + ); + case 'local_file_picker': + return ( +
+
+ + + Choose Files + +
+
+

+ Selected Files +

+
+ {files.map((file) => ( +

+ {file.name} +

+ ))} + {files.length === 0 && ( +

+ No files selected +

+ )} +
+
+
+ ); default: return null; } @@ -221,6 +262,7 @@ function Upload({ { label: 'GitHub', value: 'github' }, { label: 'Reddit', value: 'reddit' }, { label: 'Google Drive', value: 'google_drive' }, + { label: 'Upload File', value: 'local_file' }, ]; const sourceDocs = useSelector(selectSourceDocs); @@ -409,7 +451,18 @@ function Upload({ const onDrop = useCallback((acceptedFiles: File[]) => { setfiles(acceptedFiles); setDocName(acceptedFiles[0]?.name || ''); - }, []); + + // If we're in local_file mode, update the ingestor config + if (ingestor.type === 'local_file') { + setIngestor((prevState) => ({ + ...prevState, + config: { + ...prevState.config, + files: acceptedFiles, + }, + })); + } + }, [ingestor.type]); const doNothing = () => undefined; @@ -446,7 +499,15 @@ function Upload({ let configData; - if (isConnectorType(ingestor.type)) { + const filePickerField = IngestorFormSchemas[ingestor.type].find( + (field) => field.type === 'file_picker' + ); + + const localFilePickerField = IngestorFormSchemas[ingestor.type].find( + (field) => field.type === 'local_file_picker' + ); + + if (filePickerField) { const sessionToken = getSessionToken(ingestor.type); configData = { @@ -455,6 +516,13 @@ function Upload({ file_ids: selectedFiles, folder_ids: selectedFolders, }; + } else if (localFilePickerField) { + // For local files, we need to handle them differently + // Instead of sending config data, we'll append the files directly to formData + files.forEach((file) => { + formData.append('file', file); + }); + configData = { ...ingestor.config }; } else { configData = { ...ingestor.config }; } @@ -482,7 +550,11 @@ function Upload({ }); }, 3000); }; - xhr.open('POST', `${apiHost}/api/remote`); + + // Use different endpoints based on ingestor type + const endpoint = ingestor.type === 'local_file' ? `${apiHost}/api/upload` : `${apiHost}/api/remote`; + + xhr.open('POST', endpoint); xhr.setRequestHeader('Authorization', `Bearer ${token}`); xhr.send(formData); }; @@ -542,8 +614,21 @@ function Upload({ if (!remoteName?.trim()) { return true; } - if (isConnectorType(ingestor.type)) { - return selectedFiles.length === 0; + const filePickerField = IngestorFormSchemas[ingestor.type].find( + (field) => field.type === 'file_picker' + ); + + if (filePickerField?.required && selectedFiles.length === 0 && selectedFolders.length === 0) { + return true; + } + + // Check for local file picker + const localFilePickerField = IngestorFormSchemas[ingestor.type].find( + (field) => field.type === 'local_file_picker' + ); + + if (localFilePickerField?.required && files.length === 0) { + return true; } const formFields: FormField[] = IngestorFormSchemas[ingestor.type]; @@ -594,6 +679,14 @@ function Upload({ name: defaultConfig.name, config: defaultConfig.config, }); + + // Sync remoteName with ingestor name + setRemoteName(defaultConfig.name); + + // Clear files if switching away from local_file + if (type !== 'local_file') { + setfiles([]); + } }; let view; @@ -704,25 +797,19 @@ function Upload({ type="text" colorVariant="silver" value={remoteName} - onChange={(e) => setRemoteName(e.target.value)} + onChange={(e) => { + setRemoteName(e.target.value); + // Also update the ingestor name + setIngestor((prevState) => ({ + ...prevState, + name: e.target.value, + })); + }} borderVariant="thin" placeholder="Name" required={true} labelBgClassName="bg-white dark:bg-charleston-green-2" /> - {isConnectorType(ingestor.type) && ( - { - setSelectedFiles(selectedFileIds); - setSelectedFolders(selectedFolderIds); - }} - provider={ingestor.type} - token={token} - initialSelectedFiles={selectedFiles} - initialSelectedFolders={selectedFolders} - /> - )} - {renderFormFields()} {IngestorFormSchemas[ingestor.type].some( (field) => field.advanced, diff --git a/frontend/src/upload/types/ingestor.ts b/frontend/src/upload/types/ingestor.ts index f5c29dee..ed129ad2 100644 --- a/frontend/src/upload/types/ingestor.ts +++ b/frontend/src/upload/types/ingestor.ts @@ -1,5 +1,5 @@ export interface BaseIngestorConfig { - [key: string]: string | number | boolean | undefined; + [key: string]: string | number | boolean | undefined | File[]; } export interface RedditIngestorConfig extends BaseIngestorConfig { @@ -29,7 +29,11 @@ export interface GoogleDriveIngestorConfig extends BaseIngestorConfig { token_info?: any; } -export type IngestorType = 'crawler' | 'github' | 'reddit' | 'url' | 'google_drive'; +export interface LocalFileIngestorConfig extends BaseIngestorConfig { + files: File[]; +} + +export type IngestorType = 'crawler' | 'github' | 'reddit' | 'url' | 'google_drive' | 'local_file'; export interface IngestorConfig { type: IngestorType; @@ -39,7 +43,8 @@ export interface IngestorConfig { | GithubIngestorConfig | CrawlerIngestorConfig | UrlIngestorConfig - | GoogleDriveIngestorConfig; + | GoogleDriveIngestorConfig + | LocalFileIngestorConfig; } export type IngestorFormData = { @@ -49,7 +54,7 @@ export type IngestorFormData = { data: string; }; -export type FieldType = 'string' | 'number' | 'enum' | 'boolean'; +export type FieldType = 'string' | 'number' | 'enum' | 'boolean' | 'file_picker' | 'local_file_picker'; export interface FormField { name: string; @@ -118,6 +123,12 @@ export const IngestorFormSchemas: Record = { }, ], google_drive: [ + { + name: 'file_picker', + label: 'Select files', + type: 'file_picker', + required: true, + }, { name: 'recursive', label: 'Include subfolders', @@ -125,6 +136,14 @@ export const IngestorFormSchemas: Record = { required: false, }, ], + local_file: [ + { + name: 'files', + label: 'Select files', + type: 'local_file_picker', + required: true, + }, + ], }; export const IngestorDefaultConfigs: Record< @@ -167,4 +186,10 @@ export const IngestorDefaultConfigs: Record< recursive: true, } as GoogleDriveIngestorConfig, }, + local_file: { + name: '', + config: { + files: [], + } as LocalFileIngestorConfig, + }, };