adds training modals

This commit is contained in:
ajaythapliyal
2023-03-18 18:25:23 +05:30
parent 26450aca3a
commit d98c876f82
2 changed files with 112 additions and 32 deletions

View File

@@ -1,6 +1,9 @@
import { useCallback, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
import { useDropzone } from 'react-dropzone'; import { useDropzone } from 'react-dropzone';
import { useDispatch } from 'react-redux';
import { ActiveState } from '../models/misc'; import { ActiveState } from '../models/misc';
import { getDocs } from '../preferences/preferenceApi';
import { setSourceDocs } from '../preferences/preferenceSlice';
export default function Upload({ export default function Upload({
modalState, modalState,
@@ -11,6 +14,79 @@ export default function Upload({
}) { }) {
const [docName, setDocName] = useState(''); const [docName, setDocName] = useState('');
const [files, setfiles] = useState<File[]>([]); const [files, setfiles] = useState<File[]>([]);
const [progress, setProgress] = useState<{
type: 'UPLOAD' | 'TRAINIING';
percentage: number;
taskId?: string;
}>();
function Progress({
title,
isCancellable = false,
}: {
title: string;
isCancellable?: boolean;
}) {
return (
<div className="mt-5 flex flex-col items-center gap-2">
<p className="text-xl tracking-[0.15px]">{title}...</p>
<p className="text-sm text-gray-2000">This may take several minutes</p>
<p className="mt-10 text-2xl">{progress?.percentage}%</p>
<div className="mb-10 w-[50%]">
<div className="h-1 w-[100%] bg-blue-4000"></div>
<div
className={`relative bottom-1 h-1 bg-blue-5000 transition-all`}
style={{ width: `${progress?.percentage}%` }}
></div>
</div>
<button
onClick={() => {
setDocName('');
setfiles([]);
setProgress(undefined);
setModalState('INACTIVE');
}}
className={`rounded-md bg-blue-3000 px-4 py-2 text-sm font-medium text-white ${
isCancellable ? 'hidden' : ''
}`}
>
Finish
</button>
</div>
);
}
function UploadProgress() {
return <Progress title="Upload is in progress"></Progress>;
}
function TrainingProgress() {
const dispatch = useDispatch();
useEffect(() => {
const id = setInterval(() => {
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') {
clearInterval(id);
getDocs().then((data) => dispatch(setSourceDocs(data)));
}
setProgress(
(progress) =>
progress && { ...progress, percentage: data.result.current },
);
});
});
return () => clearInterval(id);
}, []);
return (
<Progress
title="Training is in progress"
isCancellable={progress?.percentage === 1000}
></Progress>
);
}
const onDrop = useCallback((acceptedFiles: File[]) => { const onDrop = useCallback((acceptedFiles: File[]) => {
setfiles(acceptedFiles); setfiles(acceptedFiles);
@@ -19,36 +95,25 @@ export default function Upload({
const doNothing = () => undefined; const doNothing = () => undefined;
const uploadFile = async () => { const uploadFile = () => {
const formData = new FormData(); const formData = new FormData();
// Add the uploaded files to formData
files.forEach((file) => { files.forEach((file) => {
formData.append('file', file); formData.append('file', file);
}); });
// Add the document name to formData
formData.append('name', docName); formData.append('name', docName);
formData.append('user', 'local'); formData.append('user', 'local');
const apiHost = import.meta.env.VITE_API_HOST; const apiHost = import.meta.env.VITE_API_HOST;
const xhr = new XMLHttpRequest();
try { xhr.upload.addEventListener('progress', (event) => {
const response = await fetch(apiHost + '/api/upload', { const progress = +((event.loaded / event.total) * 100).toFixed(2);
method: 'POST', setProgress({ type: 'UPLOAD', percentage: progress });
body: formData, });
}); xhr.onload = () => {
const { task_id } = JSON.parse(xhr.responseText);
if (response.ok) { setProgress({ type: 'TRAINIING', percentage: 0, taskId: task_id });
console.log('Files uploaded successfully'); };
setDocName(''); xhr.open('POST', `${apiHost + '/api/upload'}`);
setfiles([]); xhr.send(formData);
setModalState('INACTIVE');
} else {
console.error('File upload failed');
}
} catch (error) {
console.error('Error during file upload:', error);
}
}; };
const { getRootProps, getInputProps, isDragActive } = useDropzone({ const { getRootProps, getInputProps, isDragActive } = useDropzone({
@@ -58,13 +123,15 @@ export default function Upload({
onDragOver: doNothing, onDragOver: doNothing,
onDragLeave: doNothing, onDragLeave: doNothing,
}); });
return (
<article let view;
className={`${ if (progress?.type === 'UPLOAD') {
modalState === 'ACTIVE' ? 'visible' : 'hidden' view = <UploadProgress></UploadProgress>;
} absolute z-30 h-screen w-screen bg-gray-alpha`} } else if (progress?.type === 'TRAINIING') {
> view = <TrainingProgress></TrainingProgress>;
<article className="mx-auto mt-24 flex w-[90vw] max-w-lg flex-col gap-4 rounded-lg bg-white p-6 shadow-lg"> } else {
view = (
<>
<p className="mb-7 text-xl text-jet">Upload New Documentation</p> <p className="mb-7 text-xl text-jet">Upload New Documentation</p>
<input <input
type="text" type="text"
@@ -108,9 +175,20 @@ export default function Upload({
Cancel Cancel
</button> </button>
</div> </div>
</>
);
}
return (
<article
className={`${
modalState === 'ACTIVE' ? 'visible' : 'hidden'
} absolute z-30 h-screen w-screen bg-gray-alpha`}
>
<article className="mx-auto mt-24 flex w-[90vw] max-w-lg flex-col gap-4 rounded-lg bg-white p-6 shadow-lg">
{view}
</article> </article>
</article> </article>
); );
} }
// TODO: sanitize all inputs // TODO: sanitize all inputs

View File

@@ -24,6 +24,8 @@ module.exports = {
'blue-1000': '#7D54D1', 'blue-1000': '#7D54D1',
'blue-2000': '#002B49', 'blue-2000': '#002B49',
'blue-3000': '#4B02E2', 'blue-3000': '#4B02E2',
'blue-4000': 'rgba(0, 125, 255, 0.36)',
'blue-5000': 'rgba(0, 125, 255)',
}, },
}, },
}, },