From 7bc98408f0184fb2764b77e1be35e403ddb1e2b1 Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Sat, 20 Dec 2025 17:21:53 -0800 Subject: [PATCH] chore: change to reusable buttons and delete modal --- .../LoggingCallbacksTable.tsx | 30 ++------------- .../src/components/budgets/budget_panel.tsx | 16 ++++---- .../src/components/organizations.tsx | 37 ++++++++----------- .../vector_store_management/DeleteModal.tsx | 27 -------------- .../VectorStoreTable.tsx | 17 ++++----- .../vector_store_management/index.tsx | 21 ++++++++--- 6 files changed, 49 insertions(+), 99 deletions(-) delete mode 100644 ui/litellm-dashboard/src/components/vector_store_management/DeleteModal.tsx diff --git a/ui/litellm-dashboard/src/components/Settings/LoggingAndAlerts/LoggingCallbacks/LoggingCallbacksTable.tsx b/ui/litellm-dashboard/src/components/Settings/LoggingAndAlerts/LoggingCallbacks/LoggingCallbacksTable.tsx index 6b79b54ec0..5ad5260c94 100644 --- a/ui/litellm-dashboard/src/components/Settings/LoggingAndAlerts/LoggingCallbacks/LoggingCallbacksTable.tsx +++ b/ui/litellm-dashboard/src/components/Settings/LoggingAndAlerts/LoggingCallbacks/LoggingCallbacksTable.tsx @@ -1,10 +1,10 @@ -import { PencilAltIcon, PlayIcon, TrashIcon } from "@heroicons/react/outline"; import { Button, Icon } from "@tremor/react"; import type { TableProps } from "antd"; import { Table, Tooltip } from "antd"; import Title from "antd/es/typography/Title"; import React from "react"; import { AlertingObject } from "./types"; +import TableIconActionButton from "../../../common_components/IconActionButton/TableIconActionButtons/TableIconActionButton"; type LoggingCallbacksProps = { callbacks: AlertingObject[]; @@ -79,31 +79,9 @@ export const LoggingCallbacksTable: React.FC = ({ align: "right", render: (_: unknown, record: CallbackRow) => (
- - onTest(record)} - /> - - - - onEdit(record)} - /> - - - onDelete(record)} - /> - + onTest(record)} /> + onEdit(record)} /> + onDelete(record)} />
), width: 240, diff --git a/ui/litellm-dashboard/src/components/budgets/budget_panel.tsx b/ui/litellm-dashboard/src/components/budgets/budget_panel.tsx index 7f581ca648..2ca05e7161 100644 --- a/ui/litellm-dashboard/src/components/budgets/budget_panel.tsx +++ b/ui/litellm-dashboard/src/components/budgets/budget_panel.tsx @@ -3,7 +3,6 @@ * */ -import { PencilAltIcon, TrashIcon } from "@heroicons/react/outline"; import { Button, Card, @@ -28,6 +27,7 @@ import NotificationsManager from "../molecules/notifications_manager"; import { budgetDeleteCall, getBudgetList } from "../networking"; import BudgetModal from "./budget_modal"; import EditBudgetModal from "./edit_budget_modal"; +import TableIconActionButton from "../common_components/IconActionButton/TableIconActionButtons/TableIconActionButton"; interface BudgetSettingsPageProps { accessToken: string | null; @@ -149,16 +149,14 @@ const BudgetPanel: React.FC = ({ accessToken }) => { {value.max_budget ? value.max_budget : "n/a"} {value.tpm_limit ? value.tpm_limit : "n/a"} {value.rpm_limit ? value.rpm_limit : "n/a"} - handleEditCall(value)} /> - handleDeleteClick(value)} /> diff --git a/ui/litellm-dashboard/src/components/organizations.tsx b/ui/litellm-dashboard/src/components/organizations.tsx index 5f7275091e..32ba210161 100644 --- a/ui/litellm-dashboard/src/components/organizations.tsx +++ b/ui/litellm-dashboard/src/components/organizations.tsx @@ -23,7 +23,7 @@ import NumericalInput from "./shared/numerical_input"; import { Input } from "antd"; import { Modal, Form, Tooltip, Select as Select2 } from "antd"; import { InfoCircleOutlined } from "@ant-design/icons"; -import { PencilAltIcon, TrashIcon, RefreshIcon, ChevronDownIcon, ChevronRightIcon } from "@heroicons/react/outline"; +import { RefreshIcon, ChevronDownIcon, ChevronRightIcon } from "@heroicons/react/outline"; import { TextInput } from "@tremor/react"; import { getModelDisplayName } from "./key_team_helpers/fetch_available_models_team_key"; import OrganizationInfoView from "./organization/organization_view"; @@ -33,6 +33,7 @@ import MCPServerSelector from "./mcp_server_management/MCPServerSelector"; import { formatNumberWithCommas } from "../utils/dataUtils"; import NotificationsManager from "./molecules/notifications_manager"; import DeleteResourceModal from "./common_components/DeleteResourceModal"; +import TableIconActionButton from "./common_components/IconActionButton/TableIconActionButtons/TableIconActionButton"; interface OrganizationsTableProps { organizations: Organization[]; @@ -375,27 +376,19 @@ const OrganizationsTable: React.FC = ({ {userRole === "Admin" && ( <> - - {" "} - { - setSelectedOrgId(org.organization_id); - setEditOrg(true); - }} - /> - - - {" "} - handleDelete(org.organization_id)} - icon={TrashIcon} - size="sm" - className="cursor-pointer hover:text-red-600" - /> - + { + setSelectedOrgId(org.organization_id); + setEditOrg(true); + }} + /> + handleDelete(org.organization_id)} + /> )} diff --git a/ui/litellm-dashboard/src/components/vector_store_management/DeleteModal.tsx b/ui/litellm-dashboard/src/components/vector_store_management/DeleteModal.tsx deleted file mode 100644 index 34713359d1..0000000000 --- a/ui/litellm-dashboard/src/components/vector_store_management/DeleteModal.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from "react"; -import { Modal } from "antd"; -import { Button as TremorButton } from "@tremor/react"; - -interface DeleteModalProps { - isVisible: boolean; - onCancel: () => void; - onConfirm: () => void; -} - -const DeleteModal: React.FC = ({ isVisible, onCancel, onConfirm }) => { - return ( - -

Are you sure you want to delete this vector store? This action cannot be undone.

-
- - Delete - - - Cancel - -
-
- ); -}; - -export default DeleteModal; diff --git a/ui/litellm-dashboard/src/components/vector_store_management/VectorStoreTable.tsx b/ui/litellm-dashboard/src/components/vector_store_management/VectorStoreTable.tsx index b54b5404fd..a5097d8325 100644 --- a/ui/litellm-dashboard/src/components/vector_store_management/VectorStoreTable.tsx +++ b/ui/litellm-dashboard/src/components/vector_store_management/VectorStoreTable.tsx @@ -1,6 +1,6 @@ import React from "react"; import { Table, TableBody, TableCell, TableHead, TableHeaderCell, TableRow, Icon } from "@tremor/react"; -import { TrashIcon, PencilAltIcon, SwitchVerticalIcon, ChevronUpIcon, ChevronDownIcon } from "@heroicons/react/outline"; +import { SwitchVerticalIcon, ChevronUpIcon, ChevronDownIcon } from "@heroicons/react/outline"; import { Tooltip } from "antd"; import { ColumnDef, @@ -12,6 +12,7 @@ import { } from "@tanstack/react-table"; import { VectorStore } from "./types"; import { getProviderLogoAndName } from "../provider_info_helpers"; +import TableIconActionButton from "../common_components/IconActionButton/TableIconActionButtons/TableIconActionButton"; interface VectorStoreTableProps { data: VectorStore[]; @@ -104,17 +105,15 @@ const VectorStoreTable: React.FC = ({ data, onView, onEdi const vectorStore = row.original; return (
- onEdit(vectorStore.vector_store_id)} - className="cursor-pointer" /> - onDelete(vectorStore.vector_store_id)} - className="cursor-pointer" />
); diff --git a/ui/litellm-dashboard/src/components/vector_store_management/index.tsx b/ui/litellm-dashboard/src/components/vector_store_management/index.tsx index c8f6ed2d19..6d21e861d4 100644 --- a/ui/litellm-dashboard/src/components/vector_store_management/index.tsx +++ b/ui/litellm-dashboard/src/components/vector_store_management/index.tsx @@ -5,7 +5,7 @@ import { vectorStoreListCall, vectorStoreDeleteCall, credentialListCall, Credent import { VectorStore } from "./types"; import VectorStoreTable from "./VectorStoreTable"; import VectorStoreForm from "./VectorStoreForm"; -import DeleteModal from "./DeleteModal"; +import DeleteResourceModal from "../common_components/DeleteResourceModal"; import VectorStoreInfoView from "./vector_store_info"; import { isAdminRole } from "@/utils/roles"; import NotificationsManager from "../molecules/notifications_manager"; @@ -25,6 +25,7 @@ const VectorStoreManagement: React.FC = ({ accessToken, userID const [credentials, setCredentials] = useState([]); const [selectedVectorStoreId, setSelectedVectorStoreId] = useState(null); const [editVectorStore, setEditVectorStore] = useState(false); + const [isDeleting, setIsDeleting] = useState(false); const fetchVectorStores = async () => { if (!accessToken) return; @@ -80,6 +81,7 @@ const VectorStoreManagement: React.FC = ({ accessToken, userID const confirmDelete = async () => { if (!accessToken || !vectorStoreToDelete) return; + setIsDeleting(true); try { await vectorStoreDeleteCall(accessToken, vectorStoreToDelete); NotificationsManager.success("Vector store deleted successfully"); @@ -87,9 +89,11 @@ const VectorStoreManagement: React.FC = ({ accessToken, userID } catch (error) { console.error("Error deleting vector store:", error); NotificationsManager.fromBackend("Error deleting vector store: " + error); + } finally { + setIsDeleting(false); + setIsDeleteModalOpen(false); + setVectorStoreToDelete(null); } - setIsDeleteModalOpen(false); - setVectorStoreToDelete(null); }; const handleCreateSuccess = () => { @@ -153,10 +157,15 @@ const VectorStoreManagement: React.FC = ({ accessToken, userID /> {/* Delete Confirmation Modal */} - setIsDeleteModalOpen(false)} - onConfirm={confirmDelete} + onOk={confirmDelete} + confirmLoading={isDeleting} />