Skip to content

Commit

Permalink
(UI) Delete Internal Users on Admin UI (#6442)
Browse files Browse the repository at this point in the history
* add /user/delete call

* ui show modal asking if you want to delete user

* fix delete user modal
  • Loading branch information
ishaan-jaff authored Oct 26, 2024
1 parent b3141e1 commit fb9fb34
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 0 deletions.
33 changes: 33 additions & 0 deletions ui/litellm-dashboard/src/components/networking.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,39 @@ export const keyDeleteCall = async (accessToken: String, user_key: String) => {
}
};

export const userDeleteCall = async (accessToken: string, userIds: string[]) => {
try {
const url = proxyBaseUrl ? `${proxyBaseUrl}/user/delete` : `/user/delete`;
console.log("in userDeleteCall:", userIds);

const response = await fetch(url, {
method: "POST",
headers: {
[globalLitellmHeaderName]: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
user_ids: userIds,
}),
});

if (!response.ok) {
const errorData = await response.text();
handleError(errorData);
throw new Error("Network response was not ok");
}

const data = await response.json();
console.log(data);
//message.success("User(s) Deleted");
return data;
} catch (error) {
console.error("Failed to delete user(s):", error);
throw error;
}
};


export const teamDeleteCall = async (accessToken: String, teamID: String) => {
try {
const url = proxyBaseUrl ? `${proxyBaseUrl}/team/delete` : `/team/delete`;
Expand Down
87 changes: 87 additions & 0 deletions ui/litellm-dashboard/src/components/view_users.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
} from "@tremor/react";

import { message } from "antd";
import { Modal } from "antd";

import {
userInfoCall,
Expand All @@ -43,6 +44,8 @@ import {
TrashIcon,
} from "@heroicons/react/outline";

import { userDeleteCall } from "./networking";

interface ViewUserDashboardProps {
accessToken: string | null;
token: string | null;
Expand Down Expand Up @@ -84,11 +87,42 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({
const [selectedItem, setSelectedItem] = useState<null | any>(null);
const [editModalVisible, setEditModalVisible] = useState(false);
const [selectedUser, setSelectedUser] = useState(null);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [userToDelete, setUserToDelete] = useState<string | null>(null);
const [possibleUIRoles, setPossibleUIRoles] = useState<
Record<string, Record<string, string>>
>({});
const defaultPageSize = 25;

const handleDelete = (userId: string) => {
setUserToDelete(userId);
setIsDeleteModalOpen(true);
};

const confirmDelete = async () => {
if (userToDelete && accessToken) {
try {
await userDeleteCall(accessToken, [userToDelete]);
message.success("User deleted successfully");
// Update the user list after deletion
if (userData) {
const updatedUserData = userData.filter(user => user.user_id !== userToDelete);
setUserData(updatedUserData);
}
} catch (error) {
console.error("Error deleting user:", error);
message.error("Failed to delete user");
}
}
setIsDeleteModalOpen(false);
setUserToDelete(null);
};

const cancelDelete = () => {
setIsDeleteModalOpen(false);
setUserToDelete(null);
};

const handleEditCancel = async () => {
setSelectedUser(null);
setEditModalVisible(false);
Expand Down Expand Up @@ -272,6 +306,12 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({
>
View Keys
</Icon>
<Icon
icon={TrashIcon}
onClick={() => handleDelete(user.user_id)}
>
Delete
</Icon>
</TableCell>
</TableRow>
))}
Expand All @@ -293,6 +333,53 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({
user={selectedUser}
onSubmit={handleEditSubmit}
/>
{isDeleteModalOpen && (
<div className="fixed z-10 inset-0 overflow-y-auto">
<div className="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div
className="fixed inset-0 transition-opacity"
aria-hidden="true"
>
<div className="absolute inset-0 bg-gray-500 opacity-75"></div>
</div>

{/* Modal Panel */}
<span
className="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true"
>
&#8203;
</span>

{/* Confirmation Modal Content */}
<div className="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
<div className="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div className="sm:flex sm:items-start">
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 className="text-lg leading-6 font-medium text-gray-900">
Delete User
</h3>
<div className="mt-2">
<p className="text-sm text-gray-500">
Are you sure you want to delete this user?
</p>
<p className="text-sm font-medium text-gray-900 mt-2">
User ID: {userToDelete}
</p>
</div>
</div>
</div>
</div>
<div className="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<Button onClick={confirmDelete} color="red" className="ml-2">
Delete
</Button>
<Button onClick={cancelDelete}>Cancel</Button>
</div>
</div>
</div>
</div>
)}
</Card>
{renderPagination()}
</Grid>
Expand Down

0 comments on commit fb9fb34

Please sign in to comment.