From 8ff8b29cfa57d2d85b8eba169a1830603df1c606 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Thu, 25 Apr 2024 11:09:15 -0700 Subject: [PATCH 1/2] ui - show num keys, members in team --- ui/litellm-dashboard/src/components/teams.tsx | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/ui/litellm-dashboard/src/components/teams.tsx b/ui/litellm-dashboard/src/components/teams.tsx index 3cafe126738..b2480179909 100644 --- a/ui/litellm-dashboard/src/components/teams.tsx +++ b/ui/litellm-dashboard/src/components/teams.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from "react"; import Link from "next/link"; import { Typography } from "antd"; -import { teamDeleteCall, teamUpdateCall } from "./networking"; +import { teamDeleteCall, teamUpdateCall, teamInfoCall } from "./networking"; import { InformationCircleIcon, PencilAltIcon, PencilIcon, StatusOnlineIcon, TrashIcon } from "@heroicons/react/outline"; import { Button as Button2, @@ -73,6 +73,9 @@ const Team: React.FC = ({ const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [teamToDelete, setTeamToDelete] = useState(null); + // store team info as {"team_id": team_info_object} + const [perTeamInfo, setPerTeamInfo] = useState>({}); + const EditTeamModal: React.FC = ({ visible, onCancel, team, onSubmit }) => { const [form] = Form.useForm(); @@ -271,9 +274,39 @@ const handleEditSubmit = async (formValues: Record) => { console.error("Error fetching user models:", error); } }; + + + const fetchTeamInfo = async () => { + try { + if (userID === null || userRole === null || accessToken === null) { + return; + } + + if (teams === null) { + return; + } + + console.log("fetching team info:"); + + + let _team_id_to_info: Record = {}; + for (let i = 0; i < teams?.length; i++) { + let _team_id = teams[i].team_id; + const teamInfo = await teamInfoCall(accessToken, _team_id); + console.log("teamInfo response:", teamInfo); + if (teamInfo !== null) { + _team_id_to_info = {..._team_id_to_info, [_team_id]: teamInfo}; + } + } + setPerTeamInfo(_team_id_to_info); + } catch (error) { + console.error("Error fetching team info:", error); + } + }; fetchUserModels(); - }, [accessToken, userID, userRole]); + fetchTeamInfo(); + }, [accessToken, userID, userRole, teams]); const handleCreate = async (formValues: Record) => { try { @@ -346,6 +379,7 @@ const handleEditSubmit = async (formValues: Record) => { Budget (USD) Models TPM / RPM Limits + Info @@ -381,6 +415,7 @@ const handleEditSubmit = async (formValues: Record) => { ) : null} + @@ -390,6 +425,10 @@ const handleEditSubmit = async (formValues: Record) => { {team.rpm_limit ? team.rpm_limit : "Unlimited"} + + {perTeamInfo && team.team_id && perTeamInfo[team.team_id] && perTeamInfo[team.team_id].keys && perTeamInfo[team.team_id].keys.length} Keys + {perTeamInfo && team.team_id && perTeamInfo[team.team_id] && perTeamInfo[team.team_id].team_info && perTeamInfo[team.team_id].team_info.members_with_roles && perTeamInfo[team.team_id].team_info.members_with_roles.length} Members + Date: Thu, 25 Apr 2024 11:09:28 -0700 Subject: [PATCH 2/2] ui - show number of keys in team --- .../src/components/networking.tsx | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/ui/litellm-dashboard/src/components/networking.tsx b/ui/litellm-dashboard/src/components/networking.tsx index 9de32ac50d6..264964a9400 100644 --- a/ui/litellm-dashboard/src/components/networking.tsx +++ b/ui/litellm-dashboard/src/components/networking.tsx @@ -329,6 +329,42 @@ export const userInfoCall = async ( } }; + +export const teamInfoCall = async ( + accessToken: String, + teamID: String | null, +) => { + try { + let url = proxyBaseUrl ? `${proxyBaseUrl}/team/info` : `/team/info`; + if (teamID) { + url = `${url}?team_id=${teamID}`; + } + console.log("in teamInfoCall"); + const response = await fetch(url, { + method: "GET", + headers: { + Authorization: `Bearer ${accessToken}`, + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + const errorData = await response.text(); + message.error(errorData, 20); + throw new Error("Network response was not ok"); + } + + const data = await response.json(); + console.log("API Response:", data); + return data; + // Handle success - you might want to update some state or UI based on the created key + } catch (error) { + console.error("Failed to create key:", error); + throw error; + } +}; + + export const getTotalSpendCall = async ( accessToken: String, ) => {