diff --git a/ui/litellm-dashboard/src/components/view_users.tsx b/ui/litellm-dashboard/src/components/view_users.tsx index 1d80e513e35..7c828f756b5 100644 --- a/ui/litellm-dashboard/src/components/view_users.tsx +++ b/ui/litellm-dashboard/src/components/view_users.tsx @@ -79,7 +79,6 @@ const ViewUserDashboard: React.FC = ({ accessToken, toke const [activeTab, setActiveTab] = useState("users") const [filters, setFilters] = useState(initialFilters) const [debouncedFilters, setDebouncedFilters, debouncer] = useDebouncedState(filters, { wait: 300 }) - const [showFilters, setShowFilters] = useState(false) const [isInvitationLinkModalVisible, setIsInvitationLinkModalVisible] = useState(false) const [invitationLinkData, setInvitationLinkData] = useState(null) const [baseUrl, setBaseUrl] = useState(null) @@ -330,209 +329,35 @@ const ViewUserDashboard: React.FC = ({ accessToken, toke -
-
-
- {/* Search and Filter Controls */} -
- {/* Email Search */} -
- updateFilters({ email: e.target.value })} - /> - - - -
- - {/* Filter Button */} - - - {/* Reset Filters Button */} - -
- - {/* Additional Filters */} - {showFilters && ( -
- {/* User ID Search */} -
- updateFilters({ user_id: e.target.value })} - /> - - - -
- - {/* Role Dropdown */} -
- -
- - {/* Team Dropdown */} -
- -
- - {/* SSO ID Search */} -
- updateFilters({ sso_user_id: e.target.value })} - /> -
-
- )} - - {/* Results Count and Pagination */} -
- - Showing{" "} - {userListResponse && userListResponse.users && userListResponse.users.length > 0 - ? (userListResponse.page - 1) * userListResponse.page_size + 1 - : 0}{" "} - -{" "} - {userListResponse && userListResponse.users - ? Math.min(userListResponse.page * userListResponse.page_size, userListResponse.total) - : 0}{" "} - of {userListResponse ? userListResponse.total : 0} results - - - {/* Pagination Buttons */} -
- - -
-
-
-
-
- { - setSelectedUser(user) - setEditModalVisible(true) - }} - handleDelete={handleDelete} - handleResetPassword={handleResetPassword} - enableSelection={selectionMode} - selectedUsers={selectedUsers} - onSelectionChange={handleSelectionChange} - /> -
- -
+ { + setSelectedUser(user) + setEditModalVisible(true) + }} + handleDelete={handleDelete} + handleResetPassword={handleResetPassword} + enableSelection={selectionMode} + selectedUsers={selectedUsers} + onSelectionChange={handleSelectionChange} + filters={filters} + updateFilters={updateFilters} + initialFilters={initialFilters} + teams={teams} + userListResponse={userListResponse} + currentPage={currentPage} + handlePageChange={handlePageChange} + />
diff --git a/ui/litellm-dashboard/src/components/view_users/table.tsx b/ui/litellm-dashboard/src/components/view_users/table.tsx index 0f1193c6e87..0b422ead7b3 100644 --- a/ui/litellm-dashboard/src/components/view_users/table.tsx +++ b/ui/litellm-dashboard/src/components/view_users/table.tsx @@ -15,12 +15,27 @@ import { TableBody, TableRow, TableCell, + Select, + SelectItem, } from "@tremor/react"; import { SwitchVerticalIcon, ChevronUpIcon, ChevronDownIcon } from "@heroicons/react/outline"; import { UserInfo } from "./types"; import UserInfoView from "./user_info_view"; import { columns as createColumns } from "./columns"; +interface FilterState { + email: string; + user_id: string; + user_role: string; + sso_user_id: string; + team: string; + model: string; + min_spend: number | null; + max_spend: number | null; + sort_by: string; + sort_order: "asc" | "desc"; +} + interface UserDataTableProps { data: UserInfo[]; columns: ColumnDef[]; @@ -39,6 +54,15 @@ interface UserDataTableProps { selectedUsers?: UserInfo[]; onSelectionChange?: (selectedUsers: UserInfo[]) => void; enableSelection?: boolean; + // Filter-related props + filters: FilterState; + updateFilters: (update: Partial) => void; + initialFilters: FilterState; + teams: any[] | null; + // Pagination props + userListResponse: any; + currentPage: number; + handlePageChange: (newPage: number) => void; } export function UserDataTable({ @@ -56,6 +80,13 @@ export function UserDataTable({ selectedUsers = [], onSelectionChange, enableSelection = false, + filters, + updateFilters, + initialFilters, + teams, + userListResponse, + currentPage, + handlePageChange, }: UserDataTableProps) { const [sorting, setSorting] = React.useState([ { @@ -65,6 +96,7 @@ export function UserDataTable({ ]); const [selectedUserId, setSelectedUserId] = React.useState(null); const [openInEditMode, setOpenInEditMode] = React.useState(false); + const [showFilters, setShowFilters] = React.useState(false); const handleUserClick = (userId: string, openInEditMode: boolean = false) => { setSelectedUserId(userId); @@ -171,9 +203,190 @@ export function UserDataTable({ } return ( -
-
- +
+ {/* Filter Section */} +
+
+ {/* Search and Filter Controls */} +
+ {/* Email Search */} +
+ updateFilters({ email: e.target.value })} + /> + + + +
+ + {/* Filter Button */} + + + {/* Reset Filters Button */} + +
+ + {/* Additional Filters */} + {showFilters && ( +
+ {/* User ID Search */} +
+ updateFilters({ user_id: e.target.value })} + /> + + + +
+ + {/* Role Dropdown */} +
+ +
+ + {/* Team Dropdown */} +
+ +
+ + {/* SSO ID Search */} +
+ updateFilters({ sso_user_id: e.target.value })} + /> +
+
+ )} + + {/* Results Count and Pagination */} +
+ + Showing{" "} + {userListResponse && userListResponse.users && userListResponse.users.length > 0 + ? (userListResponse.page - 1) * userListResponse.page_size + 1 + : 0}{" "} + -{" "} + {userListResponse && userListResponse.users + ? Math.min(userListResponse.page * userListResponse.page_size, userListResponse.total) + : 0}{" "} + of {userListResponse ? userListResponse.total : 0} results + + + {/* Pagination Buttons */} +
+ + +
+
+
+
+ + {/* Table Section */} +
+
+
+
{table.getHeaderGroups().map((headerGroup) => ( @@ -260,6 +473,8 @@ export function UserDataTable({ )}
+
+
);