From b57d418b987767a2a98585df0b8ca3a4293c2c80 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Thu, 6 Feb 2025 04:04:18 +0530 Subject: [PATCH] (refactor:upload) remove redundant types --- frontend/package-lock.json | 4 +- frontend/src/upload/Upload.tsx | 269 ++++++++++++++------------ frontend/src/upload/types/ingestor.ts | 4 +- 3 files changed, 146 insertions(+), 131 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 84ba0eb0..d70a202f 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1635,7 +1635,7 @@ "version": "18.3.0", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", - "devOptional": true, + "dev": true, "dependencies": { "@types/react": "*" } @@ -9376,7 +9376,7 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", - "devOptional": true, + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/frontend/src/upload/Upload.tsx b/frontend/src/upload/Upload.tsx index 725ecdb1..78e9a321 100644 --- a/frontend/src/upload/Upload.tsx +++ b/frontend/src/upload/Upload.tsx @@ -29,16 +29,6 @@ import { } from './types/ingestor'; import { IngestorDefaultConfigs } from '../upload/types/ingestor'; -type IngestorState = { - type: IngestorType; - name: string; - config: - | RedditIngestorConfig - | GithubIngestorConfig - | CrawlerIngestorConfig - | UrlIngestorConfig; -}; - function Upload({ receivedFile = [], setModalState, @@ -55,88 +45,102 @@ function Upload({ onSuccessfulUpload?: () => void; }) { const [docName, setDocName] = useState(receivedFile[0]?.name); + const [remoteName, setRemoteName] = useState(''); const [files, setfiles] = useState(receivedFile); const [activeTab, setActiveTab] = useState(renderTab); const renderFormFields = () => { const schema = IngestorFormSchemas[ingestor.type]; - return schema.map((field: FormField) => { switch (field.type) { case 'string': return ( -
- - handleIngestorChange(field.name, e.target.value) - } - borderVariant="thin" - label={field.label} - colorVariant="gray" - /> -
+ , + ) => + handleIngestorChange( + field.name as keyof IngestorConfig['config'], + e.target.value, + ) + } + borderVariant="thin" + label={field.label} + colorVariant="gray" + /> ); case 'number': return ( -
- - handleIngestorChange(field.name, parseInt(e.target.value)) - } - borderVariant="thin" - label={field.label} - colorVariant="gray" - /> -
+ , + ) => + handleIngestorChange( + field.name as typeof ingestor.config & + keyof typeof ingestor.config, + Number(e.target.value), + ) + } + borderVariant="thin" + label={field.label} + colorVariant="gray" + /> ); case 'enum': return ( -
- { - const value = - typeof selected === 'string' ? selected : selected.value; - handleIngestorChange(field.name, value); - }} - size="w-full" - rounded="3xl" - placeholder={field.label} - border="border" - borderColor="gray-5000" - /> -
+ { + const value = + typeof selected === 'string' ? selected : selected.value; + handleIngestorChange( + field.name as keyof IngestorConfig['config'], + value, + ); + }} + size="w-full" + rounded="3xl" + placeholder={field.label} + border="border" + borderColor="gray-5000" + /> ); case 'boolean': return ( -
- { - const syntheticEvent = { - target: { - name: field.name, - value: checked, - }, - } as unknown as React.ChangeEvent; - handleIngestorChange(field.name, syntheticEvent.target.value); - }} - className="mt-2" - /> -
+ { + handleIngestorChange( + field.name as keyof IngestorConfig['config'], + checked, + ); + }} + className="mt-2" + /> ); default: return null; @@ -172,11 +176,6 @@ function Upload({ { label: 'Reddit', value: 'reddit' }, ]; - const [urlType, setUrlType] = useState<{ label: string; value: string }>({ - label: 'Crawler', - value: 'crawler', - }); - const sourceDocs = useSelector(selectSourceDocs); useEffect(() => { if (setTimeoutRef.current) { @@ -363,7 +362,7 @@ function Upload({ const onDrop = useCallback((acceptedFiles: File[]) => { setfiles(acceptedFiles); - setDocName(acceptedFiles[0]?.name); + setDocName(acceptedFiles[0]?.name || ''); }, []); const doNothing = () => undefined; @@ -374,7 +373,7 @@ function Upload({ formData.append('file', file); }); - formData.append('name', activeTab === 'file' ? docName : ingestor.name); + formData.append('name', docName); formData.append('user', 'local'); const apiHost = import.meta.env.VITE_API_HOST; const xhr = new XMLHttpRequest(); @@ -394,40 +393,47 @@ function Upload({ const uploadRemote = () => { const formData = new FormData(); - formData.append('name', ingestor.name); + formData.append('name', remoteName); formData.append('user', 'local'); formData.append('source', ingestor.type); if (ingestor.type === 'reddit') { const redditConfig = ingestor.config as RedditIngestorConfig; - redditConfig.name = ingestor.name; + formData.set('data', JSON.stringify(redditConfig)); } else if (ingestor.type === 'github') { const githubConfig = ingestor.config as GithubIngestorConfig; - githubConfig.name = ingestor.name; formData.append('repo_url', githubConfig.repo_url); formData.append('data', githubConfig.repo_url); } else { const urlBasedConfig = ingestor.config as | CrawlerIngestorConfig | UrlIngestorConfig; - urlBasedConfig.name = ingestor.name; formData.append('data', urlBasedConfig.url); } - const apiHost = import.meta.env.VITE_API_HOST; + const apiHost: string = import.meta.env.VITE_API_HOST; const xhr = new XMLHttpRequest(); - xhr.upload.addEventListener('progress', (event) => { - const progress = +((event.loaded / event.total) * 100).toFixed(2); - setProgress({ type: 'UPLOAD', percentage: progress }); + xhr.upload.addEventListener('progress', (event: ProgressEvent) => { + if (event.lengthComputable) { + const progressPercentage = +( + (event.loaded / event.total) * + 100 + ).toFixed(2); + setProgress({ type: 'UPLOAD', percentage: progressPercentage }); + } }); xhr.onload = () => { - const { task_id } = JSON.parse(xhr.responseText); - setTimeoutRef.current = setTimeout(() => { - setProgress({ type: 'TRAINING', percentage: 0, taskId: task_id }); + const response = JSON.parse(xhr.responseText) as { task_id: string }; + setTimeoutRef.current = window.setTimeout(() => { + setProgress({ + type: 'TRAINING', + percentage: 0, + taskId: response.task_id, + }); }, 3000); }; - xhr.open('POST', `${apiHost + '/api/remote'}`); + xhr.open('POST', `${apiHost}/api/remote`); xhr.send(formData); }; @@ -461,43 +467,53 @@ function Upload({ }, }); - const isUploadDisabled = () => { + const isUploadDisabled = (): boolean => { if (activeTab === 'file') { - return !docName || files.length === 0; + return !docName?.trim() || files.length === 0; } - - if (activeTab !== 'remote') return false; - - if (!ingestor.name) return true; - - return Object.values(ingestor.config).some((value) => { - if (Array.isArray(value)) { - return value.length === 0; + if (activeTab === 'remote') { + if (!remoteName?.trim()) { + return true; } - return !value; - }); + const formFields: FormField[] = IngestorFormSchemas[ingestor.type]; + for (const field of formFields) { + const value = + ingestor.config[field.name as keyof typeof ingestor.config]; + + if (typeof value === 'string' && !value.trim()) { + return true; + } + + if ( + typeof value === 'number' && + (value === null || value === undefined || value <= 0) + ) { + return true; + } + + if (typeof value === 'boolean' && value === undefined) { + return true; + } + } + return false; + } + return true; }; - const handleIngestorChange = (key: string, value: any) => { - setIngestor((prevState: IngestorConfig): IngestorConfig => { - if (key === 'name') { - return { - ...prevState, - name: value, - }; - } - - return { - ...prevState, - config: { - ...(prevState.config as any), - [key]: value, - }, - }; - }); + const handleIngestorChange = ( + key: keyof IngestorConfig['config'], + value: string | number | boolean, + ) => { + setIngestor((prevState) => ({ + ...prevState, + config: { + ...prevState.config, + [key]: value, + }, + })); }; - const handleIngestorTypeChange = (type: IngestorType) => { + //Updates the ingestor seleced in dropdown and resets the config to the default config for that type const defaultConfig = IngestorDefaultConfigs[type]; setIngestor({ @@ -614,10 +630,8 @@ function Upload({ - setIngestor({ ...ingestor, name: e.target.value }) - } + value={remoteName} + onChange={(e) => setRemoteName(e.target.value)} borderVariant="thin" placeholder="Name" label="Name" @@ -643,6 +657,7 @@ function Upload({ uploadRemote(); } }} + disabled={isUploadDisabled()} className={`rounded-3xl px-4 py-2 font-medium ${ isUploadDisabled() ? 'cursor-not-allowed bg-gray-300 text-gray-500' diff --git a/frontend/src/upload/types/ingestor.ts b/frontend/src/upload/types/ingestor.ts index 83c74bfd..3b410484 100644 --- a/frontend/src/upload/types/ingestor.ts +++ b/frontend/src/upload/types/ingestor.ts @@ -1,5 +1,5 @@ export interface BaseIngestorConfig { - name: string; + [key: string]: string | number | boolean; } export interface RedditIngestorConfig extends BaseIngestorConfig { @@ -44,7 +44,7 @@ export type IngestorFormData = { export type FieldType = 'string' | 'number' | 'enum' | 'boolean'; export interface FormField { - name: keyof BaseIngestorConfig | string; + name: string; label: string; type: FieldType; options?: { label: string; value: string }[];