|
@@ -1,12 +1,13 @@
|
|
|
"use client";
|
|
"use client";
|
|
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
|
|
|
+import { useEffect } from "react";
|
|
|
import toast from "react-hot-toast";
|
|
import toast from "react-hot-toast";
|
|
|
import { get, post } from "../../lib/api";
|
|
import { get, post } from "../../lib/api";
|
|
|
|
|
|
|
|
export default function StatsSection() {
|
|
export default function StatsSection() {
|
|
|
const queryClient = useQueryClient();
|
|
const queryClient = useQueryClient();
|
|
|
|
|
|
|
|
- const { data: tasks, isLoading: tasksLoading } = useQuery({
|
|
|
|
|
|
|
+ const { data: tasks, isLoading: _tasksLoading } = useQuery({
|
|
|
queryKey: ["tasks"],
|
|
queryKey: ["tasks"],
|
|
|
queryFn: () => get("/tasks")
|
|
queryFn: () => get("/tasks")
|
|
|
});
|
|
});
|
|
@@ -24,7 +25,7 @@ export default function StatsSection() {
|
|
|
queryFn: () => get("/files/stats/processed")
|
|
queryFn: () => get("/files/stats/processed")
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- const { data: datasets, isLoading: datasetsLoading } = useQuery({
|
|
|
|
|
|
|
+ const { data: _datasets, isLoading: _datasetsLoading } = useQuery({
|
|
|
queryKey: ["datasets"],
|
|
queryKey: ["datasets"],
|
|
|
queryFn: () => get("/files")
|
|
queryFn: () => get("/files")
|
|
|
});
|
|
});
|
|
@@ -45,7 +46,7 @@ export default function StatsSection() {
|
|
|
queryFn: () => get("/tasks/processing-status")
|
|
queryFn: () => get("/tasks/processing-status")
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- const { data: queueStatus, isLoading: queueLoading } = useQuery({
|
|
|
|
|
|
|
+ const { data: queueStatus, isLoading: _queueLoading } = useQuery({
|
|
|
queryKey: ["tasks", "queue", "status"],
|
|
queryKey: ["tasks", "queue", "status"],
|
|
|
queryFn: () => get("/tasks/queue/status")
|
|
queryFn: () => get("/tasks/queue/status")
|
|
|
});
|
|
});
|
|
@@ -107,7 +108,7 @@ export default function StatsSection() {
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- const tasksRunning = tasks?.length || 0;
|
|
|
|
|
|
|
+ const _tasksRunning = tasks?.length || 0;
|
|
|
const filesProcessed = filesSuccessful || 0;
|
|
const filesProcessed = filesSuccessful || 0;
|
|
|
const totalProcessed = filesProcessedTotal || 0;
|
|
const totalProcessed = filesProcessedTotal || 0;
|
|
|
const successRate =
|
|
const successRate =
|
|
@@ -123,6 +124,50 @@ export default function StatsSection() {
|
|
|
const isWatcherActive = watcherStatus?.isWatching;
|
|
const isWatcherActive = watcherStatus?.isWatching;
|
|
|
const isTaskProcessingActive = taskProcessingStatus?.isProcessing;
|
|
const isTaskProcessingActive = taskProcessingStatus?.isProcessing;
|
|
|
|
|
|
|
|
|
|
+ // Listen for WebSocket updates to refresh stats
|
|
|
|
|
+ useEffect(() => {
|
|
|
|
|
+ const handleTaskUpdate = (event: CustomEvent) => {
|
|
|
|
|
+ const taskData = event.detail;
|
|
|
|
|
+ // Refresh task-related queries when tasks are updated
|
|
|
|
|
+ if (
|
|
|
|
|
+ taskData.type === "progress" ||
|
|
|
|
|
+ taskData.type === "completed" ||
|
|
|
|
|
+ taskData.type === "failed"
|
|
|
|
|
+ ) {
|
|
|
|
|
+ queryClient.invalidateQueries({ queryKey: ["tasks"] });
|
|
|
|
|
+ queryClient.invalidateQueries({
|
|
|
|
|
+ queryKey: ["tasks", "processing-status"]
|
|
|
|
|
+ });
|
|
|
|
|
+ queryClient.invalidateQueries({
|
|
|
|
|
+ queryKey: ["tasks", "queue", "status"]
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const handleFileUpdate = (event: CustomEvent) => {
|
|
|
|
|
+ const fileData = event.detail;
|
|
|
|
|
+ // Refresh file stats when files are processed
|
|
|
|
|
+ if (fileData.type === "processed" || fileData.type === "success") {
|
|
|
|
|
+ queryClient.invalidateQueries({ queryKey: ["files-stats-successful"] });
|
|
|
|
|
+ queryClient.invalidateQueries({ queryKey: ["files-stats-processed"] });
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ window.addEventListener("taskUpdate", handleTaskUpdate as EventListener);
|
|
|
|
|
+ window.addEventListener("fileUpdate", handleFileUpdate as EventListener);
|
|
|
|
|
+
|
|
|
|
|
+ return () => {
|
|
|
|
|
+ window.removeEventListener(
|
|
|
|
|
+ "taskUpdate",
|
|
|
|
|
+ handleTaskUpdate as EventListener
|
|
|
|
|
+ );
|
|
|
|
|
+ window.removeEventListener(
|
|
|
|
|
+ "fileUpdate",
|
|
|
|
|
+ handleFileUpdate as EventListener
|
|
|
|
|
+ );
|
|
|
|
|
+ };
|
|
|
|
|
+ }, [queryClient]);
|
|
|
|
|
+
|
|
|
return (
|
|
return (
|
|
|
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
|
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
|
|
{/* File Watcher */}
|
|
{/* File Watcher */}
|