139 lines
4.2 KiB
TypeScript
139 lines
4.2 KiB
TypeScript
|
|
import { getUser } from '@/auth/authService';
|
||
|
|
import type { User } from 'oidc-client-ts';
|
||
|
|
import React, { useEffect, useState } from 'react';
|
||
|
|
import { HoverCard, HoverCardContent, HoverCardTrigger } from './ui/hover-card';
|
||
|
|
import { Progress } from './ui/progress';
|
||
|
|
|
||
|
|
interface ModalProps {
|
||
|
|
taskID: string | null;
|
||
|
|
}
|
||
|
|
|
||
|
|
const fetchTaskStatus = async (user: User, taskID: string) => {
|
||
|
|
const accessToken = user?.access_token;
|
||
|
|
const response = await fetch(`/api/task_status?task_id=${taskID}`, {
|
||
|
|
method: 'GET',
|
||
|
|
headers: {
|
||
|
|
'Authorization': `Bearer ${accessToken}`, // Pass the token
|
||
|
|
'Content-Type': 'application/json',
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
if (!response.ok) {
|
||
|
|
throw new Error(`Failed to fetch task status: ${response.status}`);
|
||
|
|
}
|
||
|
|
|
||
|
|
const data =
|
||
|
|
await response.json();
|
||
|
|
return data;
|
||
|
|
};
|
||
|
|
|
||
|
|
enum TaskStatus {
|
||
|
|
QUEUED = 'queued',
|
||
|
|
PROCESSING = 'processing',
|
||
|
|
COMPLETED = 'completed',
|
||
|
|
FAILED = 'failed',
|
||
|
|
}
|
||
|
|
|
||
|
|
const taskStatusToProgress = (taskStatus: TaskStatus): number => {
|
||
|
|
switch (taskStatus) {
|
||
|
|
case TaskStatus.QUEUED:
|
||
|
|
return 0.33; // Queued status
|
||
|
|
case TaskStatus.PROCESSING:
|
||
|
|
return 0.66; // Processing status
|
||
|
|
case TaskStatus.COMPLETED:
|
||
|
|
return 1.0; // Completed status
|
||
|
|
default:
|
||
|
|
throw new Error('Unknown task status: ' + status);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
const getTaskStatus = (status: string): TaskStatus => {
|
||
|
|
switch (status.toLowerCase()) {
|
||
|
|
case 'queued':
|
||
|
|
return TaskStatus.QUEUED;
|
||
|
|
case 'processing':
|
||
|
|
return TaskStatus.PROCESSING;
|
||
|
|
case 'completed':
|
||
|
|
return TaskStatus.COMPLETED;
|
||
|
|
case 'failed':
|
||
|
|
return TaskStatus.FAILED;
|
||
|
|
default:
|
||
|
|
throw new Error('Unknown task status: ' + status);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const ActiveQuery: React.FC<ModalProps> = ({
|
||
|
|
taskID
|
||
|
|
}) => {
|
||
|
|
const [user, setUser] = useState<User | null>(null);
|
||
|
|
useEffect(() => {
|
||
|
|
getUser().then(setUser);
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
const [progressPercentage, setProgressPercentage] = useState<number>(0);
|
||
|
|
const [taskStatus, setTaskStatus] = useState<TaskStatus | null>(TaskStatus.QUEUED);
|
||
|
|
const [lastUpdateTime, setLastUpdateTime] = useState<Date>(new Date());
|
||
|
|
|
||
|
|
// fetch status periodically
|
||
|
|
// maybe move to ws one day
|
||
|
|
useEffect(() => {
|
||
|
|
const interval = setInterval
|
||
|
|
(async () => {
|
||
|
|
if (!user || !taskID) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
let data = null
|
||
|
|
try {
|
||
|
|
data = await fetchTaskStatus(user, taskID);
|
||
|
|
} catch (error: any) {
|
||
|
|
clearInterval(interval);
|
||
|
|
setTaskStatus(TaskStatus.FAILED)
|
||
|
|
alert(error)
|
||
|
|
}
|
||
|
|
if (!data) {
|
||
|
|
clearInterval(interval);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
setLastUpdateTime(new Date());
|
||
|
|
const taskStatus = getTaskStatus(data.status);
|
||
|
|
if (taskStatus === TaskStatus.FAILED) {
|
||
|
|
clearInterval(interval);
|
||
|
|
throw new Error('Task failed');
|
||
|
|
}
|
||
|
|
setTaskStatus(taskStatus);
|
||
|
|
const progress = taskStatusToProgress(taskStatus);
|
||
|
|
setProgressPercentage(progress * 100);
|
||
|
|
if (taskStatus === TaskStatus.COMPLETED) {
|
||
|
|
clearInterval(interval);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}, 5000); // every 5 seconds
|
||
|
|
return () => clearInterval(interval);
|
||
|
|
}, [taskID]);
|
||
|
|
|
||
|
|
if (!taskID) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
return (
|
||
|
|
<>
|
||
|
|
<div>
|
||
|
|
<HoverCard>
|
||
|
|
<HoverCardTrigger>
|
||
|
|
{taskStatus && <p>Task status: {taskStatus} </p>}
|
||
|
|
<Progress value={progressPercentage} />
|
||
|
|
</HoverCardTrigger>
|
||
|
|
<HoverCardContent>
|
||
|
|
Task ID: {taskID}
|
||
|
|
<br />
|
||
|
|
Last updated: {lastUpdateTime.toLocaleString()}
|
||
|
|
</HoverCardContent>
|
||
|
|
</HoverCard>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
</>
|
||
|
|
)
|
||
|
|
};
|
||
|
|
|
||
|
|
export default ActiveQuery;
|