(UI) Delete Internal Users on Admin UI (#6442)

* add /user/delete call

* ui show modal asking if you want to delete user

* fix delete user modal
This commit is contained in:
Ishaan Jaff 2024-10-26 11:41:37 +04:00 committed by GitHub
parent b3141e1a5f
commit fb9fb3467d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 120 additions and 0 deletions

View file

@ -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) => { export const teamDeleteCall = async (accessToken: String, teamID: String) => {
try { try {
const url = proxyBaseUrl ? `${proxyBaseUrl}/team/delete` : `/team/delete`; const url = proxyBaseUrl ? `${proxyBaseUrl}/team/delete` : `/team/delete`;

View file

@ -26,6 +26,7 @@ import {
} from "@tremor/react"; } from "@tremor/react";
import { message } from "antd"; import { message } from "antd";
import { Modal } from "antd";
import { import {
userInfoCall, userInfoCall,
@ -43,6 +44,8 @@ import {
TrashIcon, TrashIcon,
} from "@heroicons/react/outline"; } from "@heroicons/react/outline";
import { userDeleteCall } from "./networking";
interface ViewUserDashboardProps { interface ViewUserDashboardProps {
accessToken: string | null; accessToken: string | null;
token: string | null; token: string | null;
@ -84,11 +87,42 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({
const [selectedItem, setSelectedItem] = useState<null | any>(null); const [selectedItem, setSelectedItem] = useState<null | any>(null);
const [editModalVisible, setEditModalVisible] = useState(false); const [editModalVisible, setEditModalVisible] = useState(false);
const [selectedUser, setSelectedUser] = useState(null); const [selectedUser, setSelectedUser] = useState(null);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [userToDelete, setUserToDelete] = useState<string | null>(null);
const [possibleUIRoles, setPossibleUIRoles] = useState< const [possibleUIRoles, setPossibleUIRoles] = useState<
Record<string, Record<string, string>> Record<string, Record<string, string>>
>({}); >({});
const defaultPageSize = 25; 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 () => { const handleEditCancel = async () => {
setSelectedUser(null); setSelectedUser(null);
setEditModalVisible(false); setEditModalVisible(false);
@ -272,6 +306,12 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({
> >
View Keys View Keys
</Icon> </Icon>
<Icon
icon={TrashIcon}
onClick={() => handleDelete(user.user_id)}
>
Delete
</Icon>
</TableCell> </TableCell>
</TableRow> </TableRow>
))} ))}
@ -293,6 +333,53 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({
user={selectedUser} user={selectedUser}
onSubmit={handleEditSubmit} 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> </Card>
{renderPagination()} {renderPagination()}
</Grid> </Grid>