TaskProcessingControls.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. "use client";
  2. import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
  3. import { useEffect } from "react";
  4. import toast from "react-hot-toast";
  5. import { get, post } from "../../lib/api";
  6. import { useNotifications } from "./NotificationContext";
  7. export default function TaskProcessingControls() {
  8. const queryClient = useQueryClient();
  9. const { addNotification } = useNotifications();
  10. const { data } = useQuery({
  11. queryKey: ["tasks", "processing-status"],
  12. queryFn: () => get("/tasks/processing-status")
  13. });
  14. const startMutation = useMutation({
  15. mutationFn: () => post("/tasks/start-processing"),
  16. onSuccess: () => {
  17. queryClient.invalidateQueries({
  18. queryKey: ["tasks", "processing-status"]
  19. });
  20. queryClient.invalidateQueries({ queryKey: ["tasks", "queue", "status"] });
  21. toast.success("Task processing started successfully");
  22. addNotification({
  23. type: "success",
  24. title: "Task Processing Started",
  25. message: "The task processing queue has been started successfully."
  26. });
  27. }
  28. });
  29. const stopMutation = useMutation({
  30. mutationFn: () => post("/tasks/stop-processing"),
  31. onSuccess: () => {
  32. queryClient.invalidateQueries({
  33. queryKey: ["tasks", "processing-status"]
  34. });
  35. queryClient.invalidateQueries({ queryKey: ["tasks", "queue", "status"] });
  36. toast.success("Task processing stopped successfully");
  37. addNotification({
  38. type: "success",
  39. title: "Task Processing Stopped",
  40. message: "The task processing queue has been stopped successfully."
  41. });
  42. }
  43. });
  44. // Listen for WebSocket events
  45. useEffect(() => {
  46. const handleTaskUpdate = (event: CustomEvent) => {
  47. const updateData = event.detail;
  48. if (
  49. updateData.type === "started" ||
  50. updateData.type === "stopped" ||
  51. updateData.type === "progress"
  52. ) {
  53. // Invalidate and refetch the task processing status
  54. queryClient.invalidateQueries({
  55. queryKey: ["tasks", "processing-status"]
  56. });
  57. queryClient.invalidateQueries({
  58. queryKey: ["tasks", "queue", "status"]
  59. });
  60. }
  61. };
  62. window.addEventListener("taskUpdate", handleTaskUpdate as EventListener);
  63. return () => {
  64. window.removeEventListener(
  65. "taskUpdate",
  66. handleTaskUpdate as EventListener
  67. );
  68. };
  69. }, [queryClient]);
  70. return (
  71. <div className="flex items-center gap-2">
  72. <button
  73. className="inline-flex items-center rounded-md bg-green-600 px-3 py-2 text-sm font-medium text-white shadow-sm hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 disabled:opacity-50"
  74. onClick={() => startMutation.mutate()}
  75. disabled={data?.isProcessing || startMutation.isPending}
  76. title="Start task processing"
  77. >
  78. <svg
  79. className="h-4 w-4"
  80. fill="none"
  81. viewBox="0 0 24 24"
  82. stroke="currentColor"
  83. >
  84. <path
  85. strokeLinecap="round"
  86. strokeLinejoin="round"
  87. strokeWidth={2}
  88. d="M14.828 14.828a4 4 0 01-5.656 0M9 10h1.586a1 1 0 01.707.293l.707.707A1 1 0 0012.414 11H15m-3-3v3m0 0v3m0-3h3m-3 0H9"
  89. />
  90. </svg>
  91. {startMutation.isPending ? "Starting..." : "Start"}
  92. </button>
  93. <button
  94. className="inline-flex items-center rounded-md bg-red-600 px-3 py-2 text-sm font-medium text-white shadow-sm hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 disabled:opacity-50"
  95. onClick={() => stopMutation.mutate()}
  96. disabled={!data?.isProcessing || stopMutation.isPending}
  97. title="Stop task processing"
  98. >
  99. <svg
  100. className="h-4 w-4"
  101. fill="none"
  102. viewBox="0 0 24 24"
  103. stroke="currentColor"
  104. >
  105. <path
  106. strokeLinecap="round"
  107. strokeLinejoin="round"
  108. strokeWidth={2}
  109. d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
  110. />
  111. <path
  112. strokeLinecap="round"
  113. strokeLinejoin="round"
  114. strokeWidth={2}
  115. d="M9 10a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1v-4z"
  116. />
  117. </svg>
  118. {stopMutation.isPending ? "Stopping..." : "Stop"}
  119. </button>
  120. </div>
  121. );
  122. }