diff --git a/ui/litellm-dashboard/src/components/key_team_helpers/key_list.tsx b/ui/litellm-dashboard/src/components/key_team_helpers/key_list.tsx index 02b4aad3755..6de408dbb76 100644 --- a/ui/litellm-dashboard/src/components/key_team_helpers/key_list.tsx +++ b/ui/litellm-dashboard/src/components/key_team_helpers/key_list.tsx @@ -1,5 +1,5 @@ import { useState, useEffect } from 'react'; -import { keyListCall, Organization } from '../networking'; +import { keyListCall, Member, Organization } from '../networking'; import { Setter } from '@/types'; export interface Team { @@ -12,6 +12,8 @@ export interface Team { rpm_limit: number | null; organization_id: string; created_at: string; + keys: KeyResponse[]; + members_with_roles: Member[]; } export interface KeyResponse { diff --git a/ui/litellm-dashboard/src/components/teams.tsx b/ui/litellm-dashboard/src/components/teams.tsx index 2a7e667ee7c..fbcf4948a6b 100644 --- a/ui/litellm-dashboard/src/components/teams.tsx +++ b/ui/litellm-dashboard/src/components/teams.tsx @@ -26,7 +26,7 @@ import { fetchAvailableModelsForTeamOrKey, getModelDisplayName, unfurlWildcardMo import { Select, SelectItem } from "@tremor/react"; import { InfoCircleOutlined } from '@ant-design/icons'; import { getGuardrailsList } from "./networking"; -import TeamInfoView from "@/components/team/team_info"; +import TeamInfoView, { TeamData } from "@/components/team/team_info"; import TeamSSOSettings from "@/components/TeamSSOSettings"; import { isAdminRole } from "@/utils/roles"; import { @@ -55,7 +55,7 @@ import { } from "@tremor/react"; import { CogIcon } from "@heroicons/react/outline"; import AvailableTeamsPanel from "@/components/team/available_teams"; -import type { Team } from "./key_team_helpers/key_list"; +import type { KeyResponse, Team } from "./key_team_helpers/key_list"; const isLocal = process.env.NODE_ENV === "development"; const proxyBaseUrl = isLocal ? "http://localhost:4000" : null; if (isLocal != true) { @@ -96,6 +96,15 @@ import { } from "./networking"; import { updateExistingKeys } from "@/utils/dataUtils"; +interface TeamInfo { + members_with_roles: Member[]; +} + +interface PerTeamInfo { + keys: KeyResponse[]; + team_info: TeamInfo; +} + const getOrganizationModels = (organization: Organization | null, userModels: string[]) => { let tempModelsToPick = []; @@ -164,10 +173,7 @@ const Teams: React.FC = ({ const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [teamToDelete, setTeamToDelete] = useState(null); const [modelsToPick, setModelsToPick] = useState([]); - - - - const [perTeamInfo, setPerTeamInfo] = useState>({}); + const [perTeamInfo, setPerTeamInfo] = useState>({}); // Add this state near the other useState declarations const [guardrailsList, setGuardrailsList] = useState([]); @@ -202,26 +208,24 @@ const Teams: React.FC = ({ }, [accessToken]); useEffect(() => { - const fetchTeamInfo = async () => { - if (!teams || !accessToken) return; + const fetchTeamInfo = () => { + if (!teams) return; + + const newPerTeamInfo = teams.reduce((acc, team) => { + acc[team.team_id] = { + keys: team.keys || [], + team_info: { + members_with_roles: team.members_with_roles || [] + } + }; + return acc; + }, {} as Record); - const teamInfoPromises = teams.map(async (team) => { - try { - const info = await teamInfoCall(accessToken, team.team_id); - return { [team.team_id]: info }; - } catch (error) { - console.error(`Error fetching info for team ${team.team_id}:`, error); - return { [team.team_id]: null }; - } - }); - - const results = await Promise.all(teamInfoPromises); - const newPerTeamInfo = results.reduce((acc, curr) => ({ ...acc, ...curr }), {}); setPerTeamInfo(newPerTeamInfo); }; fetchTeamInfo(); - }, [teams, accessToken]); + }, [teams]); const handleOk = () => { setIsTeamModalVisible(false);