Skip to content

Commit 6e852bc

Browse files
Merge pull request #14169 from BerriAI/remove-filters-in-user-info
Remove table filter on user info page
2 parents c8b1779 + eed2358 commit 6e852bc

File tree

2 files changed

+247
-207
lines changed

2 files changed

+247
-207
lines changed

ui/litellm-dashboard/src/components/view_users.tsx

Lines changed: 29 additions & 204 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({ accessToken, toke
7979
const [activeTab, setActiveTab] = useState("users")
8080
const [filters, setFilters] = useState<FilterState>(initialFilters)
8181
const [debouncedFilters, setDebouncedFilters, debouncer] = useDebouncedState(filters, { wait: 300 })
82-
const [showFilters, setShowFilters] = useState(false)
8382
const [isInvitationLinkModalVisible, setIsInvitationLinkModalVisible] = useState(false)
8483
const [invitationLinkData, setInvitationLinkData] = useState<InvitationLink | null>(null)
8584
const [baseUrl, setBaseUrl] = useState<string | null>(null)
@@ -330,209 +329,35 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({ accessToken, toke
330329

331330
<TabPanels>
332331
<TabPanel>
333-
<div className="bg-white rounded-lg shadow">
334-
<div className="border-b px-6 py-4">
335-
<div className="flex flex-col space-y-4">
336-
{/* Search and Filter Controls */}
337-
<div className="flex flex-wrap items-center gap-3">
338-
{/* Email Search */}
339-
<div className="relative w-64">
340-
<input
341-
type="text"
342-
placeholder="Search by email..."
343-
className="w-full px-3 py-2 pl-8 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
344-
value={filters.email}
345-
onChange={(e) => updateFilters({ email: e.target.value })}
346-
/>
347-
<svg
348-
className="absolute left-2.5 top-2.5 h-4 w-4 text-gray-500"
349-
fill="none"
350-
stroke="currentColor"
351-
viewBox="0 0 24 24"
352-
>
353-
<path
354-
strokeLinecap="round"
355-
strokeLinejoin="round"
356-
strokeWidth={2}
357-
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
358-
/>
359-
</svg>
360-
</div>
361-
362-
{/* Filter Button */}
363-
<button
364-
className={`px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2 ${showFilters ? "bg-gray-100" : ""}`}
365-
onClick={() => setShowFilters(!showFilters)}
366-
>
367-
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
368-
<path
369-
strokeLinecap="round"
370-
strokeLinejoin="round"
371-
strokeWidth={2}
372-
d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"
373-
/>
374-
</svg>
375-
Filters
376-
{(filters.user_id || filters.user_role || filters.team) && (
377-
<span className="w-2 h-2 rounded-full bg-blue-500"></span>
378-
)}
379-
</button>
380-
381-
{/* Reset Filters Button */}
382-
<button
383-
className="px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2"
384-
onClick={() => {
385-
updateFilters(initialFilters)
386-
}}
387-
>
388-
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
389-
<path
390-
strokeLinecap="round"
391-
strokeLinejoin="round"
392-
strokeWidth={2}
393-
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
394-
/>
395-
</svg>
396-
Reset Filters
397-
</button>
398-
</div>
399-
400-
{/* Additional Filters */}
401-
{showFilters && (
402-
<div className="flex flex-wrap items-center gap-3 mt-3">
403-
{/* User ID Search */}
404-
<div className="relative w-64">
405-
<input
406-
type="text"
407-
placeholder="Filter by User ID"
408-
className="w-full px-3 py-2 pl-8 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
409-
value={filters.user_id}
410-
onChange={(e) => updateFilters({ user_id: e.target.value })}
411-
/>
412-
<svg
413-
className="absolute left-2.5 top-2.5 h-4 w-4 text-gray-500"
414-
fill="none"
415-
stroke="currentColor"
416-
viewBox="0 0 24 24"
417-
>
418-
<path
419-
strokeLinecap="round"
420-
strokeLinejoin="round"
421-
strokeWidth={2}
422-
d="M5.121 17.804A13.937 13.937 0 0112 16c2.5 0 4.847.655 6.879 1.804M15 10a3 3 0 11-6 0 3 3 0 016 0zm6 2a9 9 0 11-18 0 9 9 0 0118 0z"
423-
/>
424-
</svg>
425-
</div>
426-
427-
{/* Role Dropdown */}
428-
<div className="w-64">
429-
<Select
430-
value={filters.user_role}
431-
onValueChange={(value) => updateFilters({ user_role: value })}
432-
placeholder="Select Role"
433-
>
434-
{Object.entries(possibleUIRoles).map(([key, value]) => (
435-
<SelectItem key={key} value={key}>
436-
{value.ui_label}
437-
</SelectItem>
438-
))}
439-
</Select>
440-
</div>
441-
442-
{/* Team Dropdown */}
443-
<div className="w-64">
444-
<Select
445-
value={filters.team}
446-
onValueChange={(value) => updateFilters({ team: value })}
447-
placeholder="Select Team"
448-
>
449-
{teams?.map((team) => (
450-
<SelectItem key={team.team_id} value={team.team_id}>
451-
{team.team_alias || team.team_id}
452-
</SelectItem>
453-
))}
454-
</Select>
455-
</div>
456-
457-
{/* SSO ID Search */}
458-
<div className="relative w-64">
459-
<input
460-
type="text"
461-
placeholder="Filter by SSO ID"
462-
className="w-full px-3 py-2 pl-8 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
463-
value={filters.sso_user_id}
464-
onChange={(e) => updateFilters({ sso_user_id: e.target.value })}
465-
/>
466-
</div>
467-
</div>
468-
)}
469-
470-
{/* Results Count and Pagination */}
471-
<div className="flex justify-between items-center">
472-
<span className="text-sm text-gray-700">
473-
Showing{" "}
474-
{userListResponse && userListResponse.users && userListResponse.users.length > 0
475-
? (userListResponse.page - 1) * userListResponse.page_size + 1
476-
: 0}{" "}
477-
-{" "}
478-
{userListResponse && userListResponse.users
479-
? Math.min(userListResponse.page * userListResponse.page_size, userListResponse.total)
480-
: 0}{" "}
481-
of {userListResponse ? userListResponse.total : 0} results
482-
</span>
483-
484-
{/* Pagination Buttons */}
485-
<div className="flex space-x-2">
486-
<button
487-
onClick={() => handlePageChange(currentPage - 1)}
488-
disabled={currentPage === 1}
489-
className={`px-3 py-1 text-sm border rounded-md ${
490-
currentPage === 1 ? "bg-gray-100 text-gray-400 cursor-not-allowed" : "hover:bg-gray-50"
491-
}`}
492-
>
493-
Previous
494-
</button>
495-
<button
496-
onClick={() => handlePageChange(currentPage + 1)}
497-
disabled={!userListResponse || currentPage >= userListResponse.total_pages}
498-
className={`px-3 py-1 text-sm border rounded-md ${
499-
!userListResponse || currentPage >= userListResponse.total_pages
500-
? "bg-gray-100 text-gray-400 cursor-not-allowed"
501-
: "hover:bg-gray-50"
502-
}`}
503-
>
504-
Next
505-
</button>
506-
</div>
507-
</div>
508-
</div>
509-
</div>
510-
<div className="overflow-auto">
511-
<UserDataTable
512-
data={userListQuery.data?.users || []}
513-
columns={tableColumns}
514-
isLoading={userListQuery.isLoading}
515-
accessToken={accessToken}
516-
userRole={userRole}
517-
onSortChange={handleSortChange}
518-
currentSort={{
519-
sortBy: filters.sort_by,
520-
sortOrder: filters.sort_order,
521-
}}
522-
possibleUIRoles={possibleUIRoles}
523-
handleEdit={(user) => {
524-
setSelectedUser(user)
525-
setEditModalVisible(true)
526-
}}
527-
handleDelete={handleDelete}
528-
handleResetPassword={handleResetPassword}
529-
enableSelection={selectionMode}
530-
selectedUsers={selectedUsers}
531-
onSelectionChange={handleSelectionChange}
532-
/>
533-
</div>
534-
535-
</div>
332+
<UserDataTable
333+
data={userListQuery.data?.users || []}
334+
columns={tableColumns}
335+
isLoading={userListQuery.isLoading}
336+
accessToken={accessToken}
337+
userRole={userRole}
338+
onSortChange={handleSortChange}
339+
currentSort={{
340+
sortBy: filters.sort_by,
341+
sortOrder: filters.sort_order,
342+
}}
343+
possibleUIRoles={possibleUIRoles}
344+
handleEdit={(user) => {
345+
setSelectedUser(user)
346+
setEditModalVisible(true)
347+
}}
348+
handleDelete={handleDelete}
349+
handleResetPassword={handleResetPassword}
350+
enableSelection={selectionMode}
351+
selectedUsers={selectedUsers}
352+
onSelectionChange={handleSelectionChange}
353+
filters={filters}
354+
updateFilters={updateFilters}
355+
initialFilters={initialFilters}
356+
teams={teams}
357+
userListResponse={userListResponse}
358+
currentPage={currentPage}
359+
handlePageChange={handlePageChange}
360+
/>
536361
</TabPanel>
537362

538363
<TabPanel>

0 commit comments

Comments
 (0)