From 1ffe0ad85c7220d54c43ce7dc48ccd8a7dccd07b Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Wed, 5 Feb 2025 03:31:17 +0530 Subject: [PATCH 1/8] (fix): date formatting --- frontend/src/utils/dateTimeUtils.ts | 49 +++++++++-------------------- 1 file changed, 15 insertions(+), 34 deletions(-) diff --git a/frontend/src/utils/dateTimeUtils.ts b/frontend/src/utils/dateTimeUtils.ts index 7815f123..7f89007c 100644 --- a/frontend/src/utils/dateTimeUtils.ts +++ b/frontend/src/utils/dateTimeUtils.ts @@ -1,39 +1,20 @@ export function formatDate(dateString: string): string { - try { + if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(dateString)) { + const dateTime = new Date(dateString); + return dateTime.toLocaleTimeString([], { + hour: '2-digit', + minute: '2-digit', + }); + } else if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/.test(dateString)) { + const dateTime = new Date(dateString); + return dateTime.toLocaleTimeString([], { + hour: '2-digit', + minute: '2-digit', + }); + } else if (/^\d{4}-\d{2}-\d{2}$/.test(dateString)) { const date = new Date(dateString); - - if (isNaN(date.getTime())) { - throw new Error('Invalid date'); - } - - const userLocale = navigator.language || 'en-US'; - const userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; - - const weekday = date.toLocaleDateString(userLocale, { - weekday: 'short', - timeZone: userTimezone, - }); - - const monthDay = date.toLocaleDateString(userLocale, { - day: '2-digit', - month: 'short', - year: 'numeric', - timeZone: userTimezone, - }); - - const time = date - .toLocaleTimeString(userLocale, { - hour: 'numeric', - minute: '2-digit', - second: '2-digit', - hour12: true, - timeZone: userTimezone, - }) - .replace(/am|pm/i, (match) => match.toUpperCase()); - - return `${weekday}, ${monthDay} ${time}`; - } catch (error) { - console.error('Error formatting date:', error); + return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }); + } else { return dateString; } } From b57d418b987767a2a98585df0b8ca3a4293c2c80 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Thu, 6 Feb 2025 04:04:18 +0530 Subject: [PATCH 2/8] (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 }[]; From 72556b37f5881d279e6d637ab5c6960f37188447 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Thu, 6 Feb 2025 20:16:07 +0530 Subject: [PATCH 3/8] (refactor:upload) simplify call to /api/remote --- application/api/user/routes.py | 21 +++++++++++++-------- frontend/src/upload/Upload.tsx | 19 +------------------ 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/application/api/user/routes.py b/application/api/user/routes.py index 10b141c0..6c18a680 100644 --- a/application/api/user/routes.py +++ b/application/api/user/routes.py @@ -3,6 +3,7 @@ import math import os import shutil import uuid +import json from bson.binary import Binary, UuidRepresentation from bson.dbref import DBRef @@ -420,18 +421,22 @@ class UploadRemote(Resource): return missing_fields try: - if "repo_url" in data: - source_data = data["repo_url"] - loader = "github" - else: - source_data = data["data"] - loader = data["source"] + config = json.loads(data["data"]) + source_data = None - task = ingest_remote.delay( + if data["source"] == "github": + source_data = config.get("repo_url") + elif data["source"] in ["crawler", "url"]: + source_data = config.get("url") + elif data["source"] == "reddit": + source_data = config + + + task = ingest_remote.delay( source_data=source_data, job_name=data["name"], user=data["user"], - loader=loader, + loader=data["source"] ) except Exception as err: return make_response(jsonify({"success": False, "error": str(err)}), 400) diff --git a/frontend/src/upload/Upload.tsx b/frontend/src/upload/Upload.tsx index 78e9a321..7eb569ef 100644 --- a/frontend/src/upload/Upload.tsx +++ b/frontend/src/upload/Upload.tsx @@ -20,10 +20,6 @@ import WrapperModal from '../modals/WrapperModal'; import { IngestorType, IngestorConfig, - RedditIngestorConfig, - GithubIngestorConfig, - CrawlerIngestorConfig, - UrlIngestorConfig, IngestorFormSchemas, FormField, } from './types/ingestor'; @@ -397,20 +393,7 @@ function Upload({ formData.append('user', 'local'); formData.append('source', ingestor.type); - if (ingestor.type === 'reddit') { - const redditConfig = ingestor.config as RedditIngestorConfig; - - formData.set('data', JSON.stringify(redditConfig)); - } else if (ingestor.type === 'github') { - const githubConfig = ingestor.config as GithubIngestorConfig; - formData.append('repo_url', githubConfig.repo_url); - formData.append('data', githubConfig.repo_url); - } else { - const urlBasedConfig = ingestor.config as - | CrawlerIngestorConfig - | UrlIngestorConfig; - formData.append('data', urlBasedConfig.url); - } + formData.append('data', JSON.stringify(ingestor.config)); const apiHost: string = import.meta.env.VITE_API_HOST; const xhr = new XMLHttpRequest(); From 114c8d3c2249cbcc6104445b7569702263a7bdd3 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Fri, 7 Feb 2025 17:59:28 +0530 Subject: [PATCH 4/8] (feat:Input) required prop --- frontend/src/components/Input.tsx | 9 ++++++++- frontend/src/components/types/index.ts | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/Input.tsx b/frontend/src/components/Input.tsx index f7b1765e..f224e2ba 100644 --- a/frontend/src/components/Input.tsx +++ b/frontend/src/components/Input.tsx @@ -8,6 +8,7 @@ const Input = ({ isAutoFocused = false, placeholder, label, + required = false, maxLength, className, colorVariant = 'silver', @@ -40,13 +41,19 @@ const Input = ({ onChange={onChange} onPaste={onPaste} onKeyDown={onKeyDown} + required={required} > {children} {label && (
- + {label} + {required && ( + + * + + )}
)} diff --git a/frontend/src/components/types/index.ts b/frontend/src/components/types/index.ts index a7ff5405..1d4b3a61 100644 --- a/frontend/src/components/types/index.ts +++ b/frontend/src/components/types/index.ts @@ -9,6 +9,7 @@ export type InputProps = { name?: string; placeholder?: string; label?: string; + required?: boolean; className?: string; children?: React.ReactElement; onChange: ( From 93f84662303ca44e370163383ee5f8cda541a758 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Fri, 7 Feb 2025 19:36:02 +0530 Subject: [PATCH 5/8] (feat:Upload): required form fields --- frontend/src/upload/Upload.tsx | 61 +++++++++++++++++++-------- frontend/src/upload/types/ingestor.ts | 9 ++++ 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/frontend/src/upload/Upload.tsx b/frontend/src/upload/Upload.tsx index 7eb569ef..e7635f3e 100644 --- a/frontend/src/upload/Upload.tsx +++ b/frontend/src/upload/Upload.tsx @@ -48,6 +48,7 @@ function Upload({ const renderFormFields = () => { const schema = IngestorFormSchemas[ingestor.type]; return schema.map((field: FormField) => { + const isRequired = field.required ?? false; switch (field.type) { case 'string': return ( @@ -69,6 +70,7 @@ function Upload({ } borderVariant="thin" label={field.label} + required={field.required} colorVariant="gray" /> ); @@ -86,13 +88,13 @@ function Upload({ e: React.ChangeEvent, ) => handleIngestorChange( - field.name as typeof ingestor.config & - keyof typeof ingestor.config, + field.name as keyof IngestorConfig['config'], Number(e.target.value), ) } borderVariant="thin" label={field.label} + required={field.required} colorVariant="gray" /> ); @@ -393,7 +395,29 @@ function Upload({ formData.append('user', 'local'); formData.append('source', ingestor.type); - formData.append('data', JSON.stringify(ingestor.config)); + const defaultConfig = IngestorDefaultConfigs[ingestor.type].config; + + const mergedConfig = { ...defaultConfig, ...ingestor.config }; + const filteredConfig = Object.entries(mergedConfig).reduce( + (acc, [key, value]) => { + const field = IngestorFormSchemas[ingestor.type].find( + (f) => f.name === key, + ); + // Include the field if: + // 1. It's required, or + // 2. It's optional and has a non-empty value + if ( + field?.required || + (value !== undefined && value !== null && value !== '') + ) { + acc[key] = value; + } + return acc; + }, + {} as Record, + ); + + formData.append('data', JSON.stringify(filteredConfig)); const apiHost: string = import.meta.env.VITE_API_HOST; const xhr = new XMLHttpRequest(); @@ -419,7 +443,6 @@ function Upload({ xhr.open('POST', `${apiHost}/api/remote`); xhr.send(formData); }; - const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, multiple: true, @@ -460,29 +483,31 @@ function Upload({ } const formFields: FormField[] = IngestorFormSchemas[ingestor.type]; for (const field of formFields) { - const value = - ingestor.config[field.name as keyof typeof ingestor.config]; + if (field.required) { + // Validate only required fields + const value = + ingestor.config[field.name as keyof typeof ingestor.config]; - if (typeof value === 'string' && !value.trim()) { - return true; - } + if (typeof value === 'string' && !value.trim()) { + return true; + } - if ( - typeof value === 'number' && - (value === null || value === undefined || value <= 0) - ) { - return true; - } + if ( + typeof value === 'number' && + (value === null || value === undefined || value <= 0) + ) { + return true; + } - if (typeof value === 'boolean' && value === undefined) { - return true; + if (typeof value === 'boolean' && value === undefined) { + return true; + } } } return false; } return true; }; - const handleIngestorChange = ( key: keyof IngestorConfig['config'], value: string | number | boolean, diff --git a/frontend/src/upload/types/ingestor.ts b/frontend/src/upload/types/ingestor.ts index 3b410484..155e1fb9 100644 --- a/frontend/src/upload/types/ingestor.ts +++ b/frontend/src/upload/types/ingestor.ts @@ -47,6 +47,7 @@ export interface FormField { name: string; label: string; type: FieldType; + required?: boolean; options?: { label: string; value: string }[]; } @@ -56,6 +57,7 @@ export const IngestorFormSchemas: Record = { name: 'url', label: 'URL', type: 'string', + required: true, }, ], url: [ @@ -63,6 +65,7 @@ export const IngestorFormSchemas: Record = { name: 'url', label: 'URL', type: 'string', + required: true, }, ], reddit: [ @@ -70,26 +73,31 @@ export const IngestorFormSchemas: Record = { name: 'client_id', label: 'Client ID', type: 'string', + required: true, }, { name: 'client_secret', label: 'Client Secret', type: 'string', + required: true, }, { name: 'user_agent', label: 'User Agent', type: 'string', + required: true, }, { name: 'search_queries', label: 'Search Queries', type: 'string', + required: true, }, { name: 'number_posts', label: 'Number of Posts', type: 'number', + required: true, }, ], github: [ @@ -97,6 +105,7 @@ export const IngestorFormSchemas: Record = { name: 'repo_url', label: 'Repository URL', type: 'string', + required: true, }, ], }; From 68ee9743fec2c7f5a496ce2fa480652df220d5a6 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Sun, 9 Feb 2025 01:31:01 +0530 Subject: [PATCH 6/8] (feat:upload) advanced fields --- frontend/src/upload/Upload.tsx | 221 +++++++++++++++----------- frontend/src/upload/types/ingestor.ts | 3 +- 2 files changed, 126 insertions(+), 98 deletions(-) diff --git a/frontend/src/upload/Upload.tsx b/frontend/src/upload/Upload.tsx index e7635f3e..bff31b10 100644 --- a/frontend/src/upload/Upload.tsx +++ b/frontend/src/upload/Upload.tsx @@ -44,106 +44,121 @@ function Upload({ const [remoteName, setRemoteName] = useState(''); const [files, setfiles] = useState(receivedFile); const [activeTab, setActiveTab] = useState(renderTab); + const [showAdvancedOptions, setShowAdvancedOptions] = useState(false); const renderFormFields = () => { const schema = IngestorFormSchemas[ingestor.type]; - return schema.map((field: FormField) => { - const isRequired = field.required ?? false; - switch (field.type) { - case 'string': - return ( - , - ) => - handleIngestorChange( - field.name as keyof IngestorConfig['config'], - e.target.value, - ) - } - borderVariant="thin" - label={field.label} - required={field.required} - colorVariant="gray" - /> - ); - case 'number': - return ( - , - ) => - handleIngestorChange( - field.name as keyof IngestorConfig['config'], - Number(e.target.value), - ) - } - borderVariant="thin" - label={field.label} - required={field.required} - colorVariant="gray" - /> - ); - case 'enum': - return ( - { - 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 ( - { - handleIngestorChange( - field.name as keyof IngestorConfig['config'], - checked, - ); - }} - className="mt-2" - /> - ); - default: - return null; - } - }); + if (!schema) return null; + + const generalFields = schema.filter((field) => !field.advanced); + const advancedFields = schema.filter((field) => field.advanced); + + return ( + <> + {generalFields.map((field: FormField) => renderField(field))} + + {advancedFields.length > 0 && showAdvancedOptions && ( + <> +
+ {advancedFields.map((field: FormField) => renderField(field))} + + )} + + ); + }; + + const renderField = (field: FormField) => { + const isRequired = field.required ?? false; + switch (field.type) { + case 'string': + return ( + + handleIngestorChange( + field.name as keyof IngestorConfig['config'], + e.target.value, + ) + } + borderVariant="thin" + label={field.label} + required={isRequired} + colorVariant="gray" + /> + ); + case 'number': + return ( + + handleIngestorChange( + field.name as keyof IngestorConfig['config'], + Number(e.target.value), + ) + } + borderVariant="thin" + label={field.label} + required={isRequired} + colorVariant="gray" + /> + ); + case 'enum': + return ( + + opt.value === + ingestor.config[field.name as keyof typeof ingestor.config], + ) || null + } + onSelect={(selected: { label: string; value: string }) => { + handleIngestorChange( + field.name as keyof IngestorConfig['config'], + selected.value, + ); + }} + size="w-full" + rounded="3xl" + placeholder={field.label} + border="border" + borderColor="gray-5000" + /> + ); + case 'boolean': + return ( + { + handleIngestorChange( + field.name as keyof IngestorConfig['config'], + checked, + ); + }} + className="mt-2" + /> + ); + default: + return null; + } }; // New unified ingestor state @@ -645,6 +660,18 @@ function Upload({ label="Name" /> {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 155e1fb9..cd709847 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; + [key: string]: string | number | boolean | undefined; } export interface RedditIngestorConfig extends BaseIngestorConfig { @@ -48,6 +48,7 @@ export interface FormField { label: string; type: FieldType; required?: boolean; + advanced?: boolean; options?: { label: string; value: string }[]; } From 3b45b63d2a12fd60d625834b1d74a20c8aabe352 Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Mon, 10 Feb 2025 16:02:02 +0530 Subject: [PATCH 7/8] (fix:upload) ui adjust --- frontend/src/locale/en.json | 4 +++- frontend/src/locale/es.json | 4 +++- frontend/src/locale/jp.json | 4 +++- frontend/src/locale/ru.json | 4 +++- frontend/src/locale/zh-TW.json | 4 +++- frontend/src/locale/zh.json | 4 +++- frontend/src/upload/Upload.tsx | 9 +++++---- frontend/src/upload/types/ingestor.ts | 1 + 8 files changed, 24 insertions(+), 10 deletions(-) diff --git a/frontend/src/locale/en.json b/frontend/src/locale/en.json index 35058be0..df7895ed 100644 --- a/frontend/src/locale/en.json +++ b/frontend/src/locale/en.json @@ -156,7 +156,9 @@ "completed": "Training completed", "wait": "This may take several minutes", "tokenLimit": "Over the token limit, please consider uploading smaller document" - } + }, + "showAdvanced": "Show advanced options", + "hideAdvanced": "Hide advanced options" }, "createAPIKey": { "label": "Create New API Key", diff --git a/frontend/src/locale/es.json b/frontend/src/locale/es.json index d0b47874..123f9fdd 100644 --- a/frontend/src/locale/es.json +++ b/frontend/src/locale/es.json @@ -156,7 +156,9 @@ "completed": "Entrenamiento completado", "wait": "Esto puede tardar varios minutos", "tokenLimit": "Excede el límite de tokens, considere cargar un documento más pequeño" - } + }, + "showAdvanced": "Mostrar opciones avanzadas", + "hideAdvanced": "Ocultar opciones avanzadas" }, "createAPIKey": { "label": "Crear Nueva Clave de API", diff --git a/frontend/src/locale/jp.json b/frontend/src/locale/jp.json index 2fdc2c61..b4cd1531 100644 --- a/frontend/src/locale/jp.json +++ b/frontend/src/locale/jp.json @@ -155,7 +155,9 @@ "completed": "トレーニング完了", "wait": "数分かかる場合があります", "tokenLimit": "トークン制限を超えています。より小さいドキュメントをアップロードしてください" - } + }, + "showAdvanced": "詳細オプションを表示", + "hideAdvanced": "詳細オプションを非表示" }, "createAPIKey": { "label": "新しいAPIキーを作成", diff --git a/frontend/src/locale/ru.json b/frontend/src/locale/ru.json index 087b8dfd..d6bc2bdf 100644 --- a/frontend/src/locale/ru.json +++ b/frontend/src/locale/ru.json @@ -156,7 +156,9 @@ "completed": "Обучение завершено", "wait": "Это может занять несколько минут", "tokenLimit": "Превышен лимит токенов, рассмотрите возможность загрузки документа меньшего размера" - } + }, + "showAdvanced": "Показать расширенные настройки", + "hideAdvanced": "Скрыть расширенные настройки" }, "createAPIKey": { "label": "Создать новый API ключ", diff --git a/frontend/src/locale/zh-TW.json b/frontend/src/locale/zh-TW.json index f2abf1e5..8eef9e56 100644 --- a/frontend/src/locale/zh-TW.json +++ b/frontend/src/locale/zh-TW.json @@ -156,7 +156,9 @@ "completed": "訓練完成", "wait": "這可能需要幾分鐘", "tokenLimit": "超出令牌限制,請考慮上傳較小的文檔" - } + }, + "showAdvanced": "顯示進階選項", + "hideAdvanced": "隱藏進階選項" }, "createAPIKey": { "label": "建立新的 API 金鑰", diff --git a/frontend/src/locale/zh.json b/frontend/src/locale/zh.json index 56c8fbb1..eb9d1e21 100644 --- a/frontend/src/locale/zh.json +++ b/frontend/src/locale/zh.json @@ -156,7 +156,9 @@ "completed": "训练完成", "wait": "这可能需要几分钟", "tokenLimit": "超出令牌限制,请考虑上传较小的文档" - } + }, + "showAdvanced": "显示高级选项", + "hideAdvanced": "隐藏高级选项" }, "createAPIKey": { "label": "创建新的 API 密钥", diff --git a/frontend/src/upload/Upload.tsx b/frontend/src/upload/Upload.tsx index bff31b10..0e030beb 100644 --- a/frontend/src/upload/Upload.tsx +++ b/frontend/src/upload/Upload.tsx @@ -637,7 +637,7 @@ function Upload({ {activeTab === 'remote' && ( <> opt.value === ingestor.type) || null @@ -658,6 +658,7 @@ function Upload({ borderVariant="thin" placeholder="Name" label="Name" + required={true} /> {renderFormFields()} {IngestorFormSchemas[ingestor.type].some( @@ -665,11 +666,11 @@ function Upload({ ) && ( )} diff --git a/frontend/src/upload/types/ingestor.ts b/frontend/src/upload/types/ingestor.ts index cd709847..e934cf91 100644 --- a/frontend/src/upload/types/ingestor.ts +++ b/frontend/src/upload/types/ingestor.ts @@ -99,6 +99,7 @@ export const IngestorFormSchemas: Record = { label: 'Number of Posts', type: 'number', required: true, + advanced: true, }, ], github: [ From 2019f29e8cd93e63c25f8df2b71f46254abb96bc Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Mon, 10 Feb 2025 16:02:37 +0530 Subject: [PATCH 8/8] (clean) mock changes --- frontend/src/upload/types/ingestor.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/upload/types/ingestor.ts b/frontend/src/upload/types/ingestor.ts index e934cf91..cd709847 100644 --- a/frontend/src/upload/types/ingestor.ts +++ b/frontend/src/upload/types/ingestor.ts @@ -99,7 +99,6 @@ export const IngestorFormSchemas: Record = { label: 'Number of Posts', type: 'number', required: true, - advanced: true, }, ], github: [