Merge pull request #25114 from BerriAI/litellm_fix-virtual-keys-team-filter-alias-dropdown

fix(ui): wire team_id filter to key alias dropdown on Virtual Keys tab
This commit is contained in:
ryan-crabbe-berri 2026-04-03 16:06:03 -07:00 • committed by GitHub
commit 1521004462
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 19 additions and 1 deletions

View file

@ -4395,6 +4395,9 @@ async def key_aliases(
search: Optional[str] = Query(
None, description="Search key aliases (case-insensitive partial match)"
),
team_id: Optional[str] = Query(
None, description="Filter aliases to keys belonging to this team"
),
) -> Dict[str, Any]:
"""
Lists key aliases with pagination and optional search.
@ -4470,6 +4473,10 @@ async def key_aliases(
query_params.append(f"%{search}%")
where_parts.append(f"key_alias ILIKE ${len(query_params)}")
if team_id:
query_params.append(team_id)
where_parts.append(f"team_id = ${len(query_params)}")
where_sql = " AND ".join(where_parts)
count_sql = f'SELECT COUNT(*) AS count FROM "LiteLLM_VerificationToken" WHERE {where_sql}'

View file

@ -8,6 +8,7 @@ const infiniteKeyAliasKeys = createQueryKeys("infiniteKeyAliases");
export const useInfiniteKeyAliases = (
size: number = 50,
search?: string,
team_id?: string,
) => {
const { accessToken } = useAuthorized();
return useInfiniteQuery<PaginatedKeyAliasResponse>({
@ -15,6 +16,7 @@ export const useInfiniteKeyAliases = (
filters: {
size,
...(search && { search }),
...(team_id && { team_id }),
},
}),
queryFn: async ({ pageParam }) => {
@ -23,6 +25,7 @@ export const useInfiniteKeyAliases = (
pageParam as number,
size,
search,
team_id,
);
},
initialPageParam: 1,

View file

@ -12,6 +12,7 @@ export interface PaginatedKeyAliasSelectProps {
pageSize?: number;
allowClear?: boolean;
disabled?: boolean;
allFilters?: { [key: string]: string };
}
const SCROLL_THRESHOLD = 0.8;
@ -25,19 +26,22 @@ export const PaginatedKeyAliasSelect = ({
pageSize = 50,
allowClear = true,
disabled = false,
allFilters,
}: PaginatedKeyAliasSelectProps) => {
const [searchInput, setSearchInput] = useState("");
const [debouncedSearch, setDebouncedSearch] = useDebouncedState("", {
wait: DEBOUNCE_MS,
});
const teamId = allFilters?.["Team ID"] || undefined;
const {
data,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
isLoading,
} = useInfiniteKeyAliases(pageSize, debouncedSearch || undefined);
} = useInfiniteKeyAliases(pageSize, debouncedSearch || undefined, teamId);
const options = useMemo(() => {
if (!data?.pages) return [];

View file

@ -7,6 +7,7 @@ export interface FilterOptionCustomComponentProps {
value?: string;
onChange: (value: string) => void;
placeholder?: string;
allFilters?: { [key: string]: string };
}
export interface FilterOption {
@ -209,6 +210,7 @@ const FilterComponent: React.FC<FilterComponentProps> = ({
value={tempValues[option.name] || undefined}
onChange={(value) => handleFilterChange(option.name, value ?? "")}
placeholder={`Select ${option.label || option.name}...`}
allFilters={tempValues}
/>
);
})()

View file

@ -3267,6 +3267,7 @@ export const keyAliasesCall = async (
page: number = 1,
size: number = 50,
search?: string,
team_id?: string,
): Promise<PaginatedKeyAliasResponse> => {
/**
* Get key aliases from proxy with pagination and optional search
@ -3277,6 +3278,7 @@ export const keyAliasesCall = async (
page: String(page),
size: String(size),
...(search ? { search } : {}),
...(team_id ? { team_id } : {}),
}),
);
let url = proxyBaseUrl ? `${proxyBaseUrl}/key/aliases` : `/key/aliases`;