import React from 'react'; import { useCallback, useEffect, useState } from 'react'; import { useDropzone } from 'react-dropzone'; import { useDispatch } from 'react-redux'; import { ActiveState } from '../models/misc'; import { getDocs } from '../preferences/preferenceApi'; import Arrow2 from '../assets/dropdown-arrow.svg'; import { setSourceDocs } from '../preferences/preferenceSlice'; type urlOption = { label: string, value: string } | null function DropdownUrlType({ options, selectedOption, onSelect, }: { options: urlOption[]; selectedOption: urlOption; onSelect: (value: urlOption) => void; }) { const [isOpen, setIsOpen] = useState(false); return (
{isOpen && (
{options.map((option, index) => (
{ onSelect(option); setIsOpen(false); }} className="ml-2 flex-1 overflow-hidden overflow-ellipsis whitespace-nowrap px-1 py-3" > {option?.label}
))}
)}
); } export default function Upload({ modalState, setModalState, }: { modalState: ActiveState; setModalState: (state: ActiveState) => void; }) { const [docName, setDocName] = useState(''); const [urlName, setUrlName] = useState('') const [url, setUrl] = useState('') const urlOptions: urlOption[] = [ { label: 'Github', value: 'github' }, { label: 'Sitemap', value: 'Sitemap' }, { label: 'Link', value: 'link' }] const [urlType, setUrlType] = useState(null) const [activeTab, setActiveTab] = useState('file'); const [files, setfiles] = useState([]); const [progress, setProgress] = useState<{ type: 'UPLOAD' | 'TRAINIING'; percentage: number; taskId?: string; failed?: boolean; }>(); function Progress({ title, isCancellable = false, isFailed = false, }: { title: string; isCancellable?: boolean; isFailed?: boolean; }) { return (

{title}...

This may take several minutes

Over the token limit, please consider uploading smaller document

{progress?.percentage || 0}%

); } function UploadProgress() { return ; } function TrainingProgress() { const dispatch = useDispatch(); useEffect(() => { (progress?.percentage ?? 0) < 100 && setTimeout(() => { const apiHost = import.meta.env.VITE_API_HOST; fetch(`${apiHost}/api/task_status?task_id=${progress?.taskId}`) .then((data) => data.json()) .then((data) => { if (data.status == 'SUCCESS') { if (data.result.limited === true) { getDocs().then((data) => dispatch(setSourceDocs(data))); setProgress( (progress) => progress && { ...progress, percentage: 100, failed: true, }, ); } else { getDocs().then((data) => dispatch(setSourceDocs(data))); setProgress( (progress) => progress && { ...progress, percentage: 100, failed: false, }, ); } } else if (data.status == 'PROGRESS') { setProgress( (progress) => progress && { ...progress, percentage: data.result.current, }, ); } }); }, 5000); }, [progress, dispatch]); return ( ); } const onDrop = useCallback((acceptedFiles: File[]) => { setfiles(acceptedFiles); setDocName(acceptedFiles[0]?.name); }, []); const doNothing = () => undefined; const uploadFile = () => { const formData = new FormData(); files.forEach((file) => { formData.append('file', file); }); formData.append('name', docName); formData.append('user', 'local'); const apiHost = 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.onload = () => { const { task_id } = JSON.parse(xhr.responseText); setProgress({ type: 'TRAINIING', percentage: 0, taskId: task_id }); }; xhr.open('POST', `${apiHost + '/api/upload'}`); xhr.send(formData); }; const uploadRemote = () => { console.log("here") const formData = new FormData(); formData.append('name', urlName); formData.append('user', 'local'); if (urlType !== null) { formData.append('source', urlType?.value); } formData.append('data', url); const apiHost = 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.onload = () => { const { task_id } = JSON.parse(xhr.responseText); setProgress({ type: 'TRAINIING', percentage: 0, taskId: task_id }); }; xhr.open('POST', `${apiHost + '/api/remote'}`); xhr.send(formData); }; const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, multiple: false, onDragEnter: doNothing, onDragOver: doNothing, onDragLeave: doNothing, maxSize: 25000000, accept: { 'application/pdf': ['.pdf'], 'text/plain': ['.txt'], 'text/x-rst': ['.rst'], 'text/x-markdown': ['.md'], 'application/zip': ['.zip'], 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx'], }, }); let view; if (progress?.type === 'UPLOAD') { view = ; } else if (progress?.type === 'TRAINIING') { view = ; } else { view = ( <>

Upload New Documentation

{ activeTab === 'file' && ( <> setDocName(e.target.value)} >
Name
Choose Files

Please upload .pdf, .txt, .rst, .docx, .md, .zip limited to 25mb

Uploaded Files

{files.map((file) => (

{file.name}

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

None

}
) } { activeTab === 'remote' && ( <> setUrlType(value)} selectedOption={urlType} options={urlOptions} /> setUrlName(e.target.value)} >
Name
setUrl(e.target.value)} >
Link
) }
); } return (
{view}
); } // TODO: sanitize all inputs