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 { setSourceDocs } from '../preferences/preferenceSlice'; export default function Upload({ modalState, setModalState, }: { modalState: ActiveState; setModalState: (state: ActiveState) => void; }) { const [docName, setDocName] = useState(''); 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 { 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

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

setDocName(e.target.value)} >
Name
Choose Files

Uploaded Files

{files.map((file) => (

{file.name}

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

None

}
); } return (
{view}
); } // TODO: sanitize all inputs