diff --git a/frontend/src/components/queues/QueueTable/QueueTable.jsx b/frontend/src/components/queues/QueueTable/QueueTable.jsx
index ac2455b..d4296ff 100644
--- a/frontend/src/components/queues/QueueTable/QueueTable.jsx
+++ b/frontend/src/components/queues/QueueTable/QueueTable.jsx
@@ -1,9 +1,11 @@
-import React, { useState } from "react";
+import React, { useState, useEffect } from "react";
import {
TableContainer,
Table,
TableBody,
Paper,
+ TableRow,
+ TableCell,
useTheme,
alpha,
} from "@mui/material";
@@ -23,12 +25,20 @@ const QueueTable = ({
uniqueStates,
handleFilterClose,
setAnchorEl,
- handleDelete,
+ onQueueUpdate,
}) => {
const theme = useTheme();
+
+ const [queues, setQueues] = useState([]);
+
+ useEffect(() => {
+ setQueues(sortedQueues);
+ }, [sortedQueues]);
+
const [openDeleteDialog, setOpenDeleteDialog] = useState(false);
const [queueToDelete, setQueueToDelete] = useState(null);
-
+ const [deleteError, setDeleteError] = useState(null);
+ const [isDeleting, setIsDeleting] = useState(false);
const handleOpenDeleteDialog = (queueName) => {
setQueueToDelete(queueName);
setOpenDeleteDialog(true);
@@ -37,13 +47,77 @@ const QueueTable = ({
const handleCloseDeleteDialog = () => {
setOpenDeleteDialog(false);
setQueueToDelete(null);
+ setDeleteError(null);
+ setIsDeleting(false);
};
- const confirmDelete = () => {
- if (handleDelete && queueToDelete) {
- handleDelete(queueToDelete);
+ const handleDelete = async () => {
+ try {
+ setIsDeleting(true);
+
+ const response = await fetch(
+ `/api/queues/${encodeURIComponent(queueToDelete)}`,
+ {
+ method: "DELETE",
+ headers: {
+ "Content-Type": "application/json",
+ Accept: "application/json",
+ },
+ },
+ );
+
+ let data = {};
+ const contentType = response.headers.get("content-type");
+ const text = await response.text();
+
+ let isJsonResponse = false;
+ try {
+ if (
+ (contentType && contentType.includes("application/json")) ||
+ (text && !text.trim().startsWith("<"))
+ ) {
+ data = text ? JSON.parse(text) : {};
+ isJsonResponse = true;
+ }
+ } catch (parseError) {
+ console.warn("Failed to parse response as JSON:", parseError);
+ }
+
+ if (!response.ok) {
+ let customMessage = `queues.scheduling.volcano.sh "${queueToDelete}" is forbidden.`;
+ let errorType = "UnknownError";
+
+ if (
+ isJsonResponse &&
+ typeof data === "object" &&
+ (data.message || data.details)
+ ) {
+ customMessage = data.message || data.details;
+ if (customMessage.toLowerCase().includes("denied")) {
+ errorType = "ValidationError";
+ } else {
+ errorType = "KubernetesError";
+ }
+ }
+
+ const fullMessage = `Cannot delete "${queueToDelete}". Error message: ${customMessage}`;
+ const error = new Error(fullMessage);
+ error.type = errorType;
+ error.status = response.status;
+ throw error;
+ }
+
+ // Success
+ setQueues((prev) =>
+ prev.filter((queue) => queue.metadata.name !== queueToDelete),
+ );
+ handleCloseDeleteDialog();
+ } catch (error) {
+ console.error("Error deleting queue:", error);
+ setDeleteError(error.message || "An unexpected error occurred.");
+ } finally {
+ setIsDeleting(false);
}
- handleCloseDeleteDialog();
};
return (
@@ -94,23 +168,39 @@ const QueueTable = ({
setAnchorEl={setAnchorEl}
/>
- {sortedQueues.map((queue) => (
-
- ))}
+ {queues.length === 0 ? (
+
+
+ No queues found.
+
+
+ ) : (
+ queues.map((queue) => (
+
+ ))
+ )}
);