add worker api to refresh data in the background

This commit is contained in:
Viktor Barzin 2025-06-21 12:49:04 +00:00
parent fc722b6b5f
commit a7e0773c0a
No known key found for this signature in database
GPG key ID: 4056458DBDBF8863
12 changed files with 465 additions and 38 deletions

View file

@ -0,0 +1,138 @@
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;