-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat(team_endpoints.py): new `/teams/available` endpoint - allows proxy admin to expose available teams for users to join on UI * build(ui/): available_teams.tsx allow user to join available teams on UI makes it easier to onboard new users to teams * fix(navbar.tsx): cleanup title * fix(team_endpoints.py): fix linting error * test: update groq model in test * build(model_prices_and_context_window.json): update groq 3.3 model with 'supports function calling'
- Loading branch information
1 parent
f778829
commit 1ab10d8
Showing
10 changed files
with
329 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
143 changes: 143 additions & 0 deletions
143
ui/litellm-dashboard/src/components/team/available_teams.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
import React, { useState, useEffect } from 'react'; | ||
import { | ||
Table, | ||
TableBody, | ||
TableCell, | ||
TableHead, | ||
TableHeaderCell, | ||
TableRow, | ||
Card, | ||
Button, | ||
Text, | ||
Badge, | ||
} from "@tremor/react"; | ||
import { message } from 'antd'; | ||
import { availableTeamListCall, teamMemberAddCall } from "../networking"; | ||
|
||
interface AvailableTeam { | ||
team_id: string; | ||
team_alias: string; | ||
description?: string; | ||
models: string[]; | ||
members_with_roles: {user_id?: string, user_email?: string, role: string}[]; | ||
} | ||
|
||
interface AvailableTeamsProps { | ||
accessToken: string | null; | ||
userID: string | null; | ||
} | ||
|
||
const AvailableTeamsPanel: React.FC<AvailableTeamsProps> = ({ | ||
accessToken, | ||
userID, | ||
}) => { | ||
const [availableTeams, setAvailableTeams] = useState<AvailableTeam[]>([]); | ||
|
||
useEffect(() => { | ||
const fetchAvailableTeams = async () => { | ||
if (!accessToken || !userID) return; | ||
|
||
try { | ||
const response = await availableTeamListCall(accessToken); | ||
|
||
setAvailableTeams(response); | ||
} catch (error) { | ||
console.error('Error fetching available teams:', error); | ||
message.error('Failed to load available teams'); | ||
} | ||
}; | ||
|
||
fetchAvailableTeams(); | ||
}, [accessToken, userID]); | ||
|
||
const handleJoinTeam = async (teamId: string) => { | ||
if (!accessToken || !userID) return; | ||
|
||
try { | ||
const response = await teamMemberAddCall(accessToken, teamId, { | ||
"user_id": userID, | ||
"role": "user" | ||
} | ||
); | ||
|
||
message.success('Successfully joined team'); | ||
// Update available teams list | ||
setAvailableTeams(teams => teams.filter(team => team.team_id !== teamId)); | ||
} catch (error) { | ||
console.error('Error joining team:', error); | ||
message.error('Failed to join team'); | ||
} | ||
}; | ||
|
||
|
||
return ( | ||
<Card className="w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]"> | ||
<Table> | ||
<TableHead> | ||
<TableRow> | ||
<TableHeaderCell>Team Name</TableHeaderCell> | ||
<TableHeaderCell>Description</TableHeaderCell> | ||
<TableHeaderCell>Members</TableHeaderCell> | ||
<TableHeaderCell>Models</TableHeaderCell> | ||
<TableHeaderCell>Actions</TableHeaderCell> | ||
</TableRow> | ||
</TableHead> | ||
<TableBody> | ||
{availableTeams.map((team) => ( | ||
<TableRow key={team.team_id}> | ||
<TableCell> | ||
<Text>{team.team_alias}</Text> | ||
</TableCell> | ||
<TableCell> | ||
<Text>{team.description || 'No description available'}</Text> | ||
</TableCell> | ||
<TableCell> | ||
<Text>{team.members_with_roles.length} members</Text> | ||
</TableCell> | ||
<TableCell> | ||
<div className="flex flex-col"> | ||
{!team.models || team.models.length === 0 ? ( | ||
<Badge size="xs" color="red"> | ||
<Text>All Proxy Models</Text> | ||
</Badge> | ||
) : ( | ||
team.models.map((model, index) => ( | ||
<Badge | ||
key={index} | ||
size="xs" | ||
className="mb-1" | ||
color="blue" | ||
> | ||
<Text> | ||
{model.length > 30 ? `${model.slice(0, 30)}...` : model} | ||
</Text> | ||
</Badge> | ||
)) | ||
)} | ||
</div> | ||
</TableCell> | ||
<TableCell> | ||
<Button | ||
size="xs" | ||
variant="secondary" | ||
onClick={() => handleJoinTeam(team.team_id)} | ||
> | ||
Join Team | ||
</Button> | ||
</TableCell> | ||
</TableRow> | ||
))} | ||
{availableTeams.length === 0 && ( | ||
<TableRow> | ||
<TableCell colSpan={5} className="text-center"> | ||
<Text>No available teams to join</Text> | ||
</TableCell> | ||
</TableRow> | ||
)} | ||
</TableBody> | ||
</Table> | ||
</Card> | ||
); | ||
}; | ||
|
||
export default AvailableTeamsPanel; |
Oops, something went wrong.