Easier user onboarding via SSO (#8187)

* fix(ui_sso.py): use common `get_user_object` logic across jwt + ui sso auth

Allows finding users by their email, and attaching the sso user id to the user if found

* Improve Team Management flow on UI  (#8204)

* build(teams.tsx): refactor teams page to make it easier to add members to a team

make a row in table clickable -> allows user to add users to team they intended

* build(teams.tsx): make it clear user should click on team id to view team details

simplifies team management by putting team details on separate page

* build(team_info.tsx): separately show user id and user email

make it easy for user to understand the information they're seeing

* build(team_info.tsx): add back in 'add member' button

* build(team_info.tsx): working team member update on team_info.tsx

* build(team_info.tsx): enable team member delete on ui

allow user to delete accidental adds

* build(internal_user_endpoints.py): expose new endpoint for ui to allow filtering on user table

allows proxy admin to quickly find user they're looking for

* feat(team_endpoints.py): expose new team filter endpoint for ui

allows proxy admin to easily find team they're looking for

* feat(user_search_modal.tsx): allow admin to filter on users when adding new user to teams

* test: mark flaky test

* test: mark flaky test

* fix(exception_mapping_utils.py): fix anthropic text route error

* fix(ui_sso.py): handle situation when user not in db
This commit is contained in:
Krish Dholakia 2025-02-02 23:02:33 -08:00 committed by GitHub
parent 8900b18504
commit 65d3f85a69
14 changed files with 862 additions and 111 deletions

View file

@ -1510,6 +1510,36 @@ export const allEndUsersCall = async (accessToken: String) => {
}
};
export const userFilterUICall = async (accessToken: String, params: URLSearchParams) => {
try {
let url = proxyBaseUrl ? `${proxyBaseUrl}/user/filter/ui` : `/user/filter/ui`;
if (params.get("user_email")) {
url += `?user_email=${params.get("user_email")}`;
}
if (params.get("user_id")) {
url += `?user_id=${params.get("user_id")}`;
}
const response = await fetch(url, {
method: "GET",
headers: {
[globalLitellmHeaderName]: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
});
if (!response.ok) {
const errorData = await response.text();
handleError(errorData);
throw new Error("Network response was not ok");
}
return await response.json();
} catch (error) {
console.error("Failed to create key:", error);
throw error;
}
}
export const userSpendLogsCall = async (
accessToken: String,
token: String,
@ -2402,6 +2432,47 @@ export const teamMemberUpdateCall = async (
}
}
export const teamMemberDeleteCall = async (
accessToken: string,
teamId: string,
formValues: Member // Assuming formValues is an object
) => {
try {
console.log("Form Values in teamMemberAddCall:", formValues); // Log the form values before making the API call
const url = proxyBaseUrl
? `${proxyBaseUrl}/team/member_delete`
: `/team/member_delete`;
const response = await fetch(url, {
method: "POST",
headers: {
[globalLitellmHeaderName]: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
team_id: teamId,
...(formValues.user_email && { user_email: formValues.user_email }),
...(formValues.user_id && { user_id: formValues.user_id })
}),
});
if (!response.ok) {
const errorData = await response.text();
handleError(errorData);
console.error("Error response from the server:", errorData);
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 organizationMemberAddCall = async (
accessToken: string,
organizationId: string,