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 { useDispatch } from 'react-redux';
import { ActiveState } from '../models/misc';
import { getDocs } from '../preferences/preferenceApi';
import { setSourceDocs } from '../preferences/preferenceSlice';
export default function Upload({
modalState,
@@ -11,6 +14,79 @@ export default function Upload({
}) {
const [docName, setDocName] = useState('');
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[]) => {
setfiles(acceptedFiles);
@@ -19,36 +95,25 @@ export default function Upload({
const doNothing = () => undefined;
const uploadFile = async () => {
const uploadFile = () => {
const formData = new FormData();
// Add the uploaded files to formData
files.forEach((file) => {
formData.append('file', file);
});
// Add the document name to formData
formData.append('name', docName);
formData.append('user', 'local');
const apiHost = import.meta.env.VITE_API_HOST;
try {
const response = await fetch(apiHost + '/api/upload', {
method: 'POST',
body: formData,
});
if (response.ok) {
console.log('Files uploaded successfully');
setDocName('');
setfiles([]);
setModalState('INACTIVE');
} else {
console.error('File upload failed');
}
} catch (error) {
console.error('Error during file upload:', error);
}
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({
@@ -58,13 +123,15 @@ export default function Upload({
onDragOver: doNothing,
onDragLeave: doNothing,
});
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">
let view;
if (progress?.type === 'UPLOAD') {
view = <UploadProgress></UploadProgress>;
} else if (progress?.type === 'TRAINIING') {
view = <TrainingProgress></TrainingProgress>;
} else {
view = (
<>
<p className="mb-7 text-xl text-jet">Upload New Documentation</p>
<input
type="text"
@@ -108,9 +175,20 @@ export default function Upload({
Cancel
</button>
</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>
);
}
// TODO: sanitize all inputs