model filters ui matches the users page

This commit is contained in:
tanjiro
2025-08-31 14:33:15 +09:00
parent dea3b53578
commit 82cec3885e
@@ -191,6 +191,9 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
const [currentTeam, setCurrentTeam] = useState<string>("personal") // 'personal' or team_id
const [modelViewMode, setModelViewMode] = useState<"current_team" | "all">("current_team")
// Add state for showing/hiding filters
const [showFilters, setShowFilters] = useState<boolean>(false)
const [showColumnDropdown, setShowColumnDropdown] = useState(false)
const [isDropdownOpen, setIsDropdownOpen] = useState(false)
@@ -206,6 +209,14 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
setSelectedTabIndex(1)
}
const resetFilters = () => {
setModelNameSearch("")
setSelectedModelGroup("all")
setSelectedModelAccessGroupFilter(null)
setCurrentTeam("personal")
setModelViewMode("current_team")
}
const setProviderModelsFn = (provider: Providers) => {
const _providerModels = getProviderModels(provider, modelMap)
setProviderModels(_providerModels)
@@ -1006,119 +1017,166 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
<div className="flex flex-col space-y-4">
<div className="bg-white rounded-lg shadow">
<div className="border-b px-6 py-4">
<div className="flex flex-col space-y-4">
{/* Current Team Selector - Prominent */}
<div className="flex items-center justify-between bg-gray-50 rounded-lg p-4 border-2 border-gray-200">
<div>
<div className="flex items-center gap-4">
<Text className="text-lg font-semibold text-gray-900">Current Team:</Text>
<Select
className="w-80"
defaultValue="personal"
value={currentTeam}
onValueChange={(value) => setCurrentTeam(value)}
>
<SelectItem value="personal">
{/* Current Team and View Mode Selector - Prominent Section */}
<div className="border-b px-6 py-4 bg-gray-50">
<div className="flex items-center justify-between">
<div className="flex items-center gap-4">
<Text className="text-lg font-semibold text-gray-900">Current Team:</Text>
<Select
className="w-80"
defaultValue="personal"
value={currentTeam}
onValueChange={(value) => setCurrentTeam(value)}
>
<SelectItem value="personal">
<div className="flex items-center gap-2">
<div className="w-2 h-2 bg-blue-500 rounded-full"></div>
<span className="font-medium">Personal</span>
</div>
</SelectItem>
{teams
?.filter((team) => team.team_id)
.map((team) => (
<SelectItem key={team.team_id} value={team.team_id}>
<div className="flex items-center gap-2">
<div className="w-2 h-2 bg-blue-500 rounded-full"></div>
<span className="font-medium">Personal</span>
<div className="w-2 h-2 bg-green-500 rounded-full"></div>
<span className="font-medium">
{team.team_alias
? `${team.team_alias.slice(0, 30)}...`
: `Team ${team.team_id.slice(0, 30)}...`}
</span>
</div>
</SelectItem>
{teams
?.filter((team) => team.team_id)
.map((team) => (
<SelectItem key={team.team_id} value={team.team_id}>
<div className="flex items-center gap-2">
<div className="w-2 h-2 bg-green-500 rounded-full"></div>
<span className="font-medium">
{team.team_alias
? `${team.team_alias.slice(0, 30)}...`
: `Team ${team.team_id.slice(0, 30)}...`}
</span>
</div>
</SelectItem>
))}
</Select>
</div>
{modelViewMode === "current_team" && (
<div className="flex items-start gap-2 mt-2 bg-gray-50 rounded">
<InfoCircleOutlined className="text-gray-400 mt-0.5 flex-shrink-0 text-xs" />
<div className="text-xs text-gray-500">
{currentTeam === "personal" ? (
<span>
To access these models: Create a Virtual Key without selecting a team on the{" "}
<a
href="/?login=success&page=api-keys"
className="text-gray-600 hover:text-gray-800 underline"
>
Virtual Keys page
</a>
</span>
) : (
<span>
To access these models: Create a Virtual Key and select Team as &quot;
{currentTeam}&quot; on the{" "}
<a
href="/?login=success&page=api-keys"
className="text-gray-600 hover:text-gray-800 underline"
>
Virtual Keys page
</a>
</span>
)}
</div>
</div>
)}
</div>
{/* Model View Mode Toggle - Also prominent */}
<div className="flex items-center gap-4">
<Text className="text-lg font-semibold text-gray-900">View:</Text>
<Select
className="w-64"
defaultValue="current_team"
value={modelViewMode}
onValueChange={(value) => setModelViewMode(value as "current_team" | "all")}
>
<SelectItem value="current_team">
<div className="flex items-center gap-2">
<div className="w-2 h-2 bg-purple-500 rounded-full"></div>
<span className="font-medium">Current Team Models</span>
</div>
</SelectItem>
<SelectItem value="all">
<div className="flex items-center gap-2">
<div className="w-2 h-2 bg-gray-500 rounded-full"></div>
<span className="font-medium">All Available Models</span>
</div>
</SelectItem>
</Select>
</div>
))}
</Select>
</div>
{/* Other Filters */}
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
{/* Model Name Search */}
<div className="flex items-center gap-2">
<Text>Search Public Model Name:</Text>
<TextInput
className="w-64"
placeholder="Search model names..."
value={modelNameSearch}
onValueChange={setModelNameSearch}
/>
</div>
<div className="flex items-center gap-4">
<Text className="text-lg font-semibold text-gray-900">View:</Text>
<Select
className="w-64"
defaultValue="current_team"
value={modelViewMode}
onValueChange={(value) => setModelViewMode(value as "current_team" | "all")}
>
<SelectItem value="current_team">
<div className="flex items-center gap-2">
<div className="w-2 h-2 bg-purple-500 rounded-full"></div>
<span className="font-medium">Current Team Models</span>
</div>
</SelectItem>
<SelectItem value="all">
<div className="flex items-center gap-2">
<div className="w-2 h-2 bg-gray-500 rounded-full"></div>
<span className="font-medium">All Available Models</span>
</div>
</SelectItem>
</Select>
</div>
</div>
{modelViewMode === "current_team" && (
<div className="flex items-start gap-2 mt-3">
<InfoCircleOutlined className="text-gray-400 mt-0.5 flex-shrink-0 text-xs" />
<div className="text-xs text-gray-500">
{currentTeam === "personal" ? (
<span>
To access these models: Create a Virtual Key without selecting a team on the{" "}
<a
href="/?login=success&page=api-keys"
className="text-gray-600 hover:text-gray-800 underline"
>
Virtual Keys page
</a>
</span>
) : (
<span>
To access these models: Create a Virtual Key and select Team as &quot;
{currentTeam}&quot; on the{" "}
<a
href="/?login=success&page=api-keys"
className="text-gray-600 hover:text-gray-800 underline"
>
Virtual Keys page
</a>
</span>
)}
</div>
</div>
)}
</div>
{/* Search and Filter Controls */}
<div className="border-b px-6 py-4">
<div className="flex flex-col space-y-4">
{/* Search and Filter Controls */}
<div className="flex flex-wrap items-center gap-3">
{/* Model Name Search */}
<div className="relative w-64">
<input
type="text"
placeholder="Search model names..."
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"
value={modelNameSearch}
onChange={(e) => setModelNameSearch(e.target.value)}
/>
<svg
className="absolute left-2.5 top-2.5 h-4 w-4 text-gray-500"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
/>
</svg>
</div>
{/* Filter Button */}
<button
className={`px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2 ${showFilters ? "bg-gray-100" : ""}`}
onClick={() => setShowFilters(!showFilters)}
>
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
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"
/>
</svg>
Filters
</button>
{/* Reset Filters Button */}
<button
className="px-3 py-2 text-sm border rounded-md hover:bg-gray-50 flex items-center gap-2"
onClick={resetFilters}
>
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
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"
/>
</svg>
Reset Filters
</button>
</div>
{/* Additional Filters */}
{showFilters && (
<div className="flex flex-wrap items-center gap-3 mt-3">
{/* Model Name Filter */}
<div className="flex items-center gap-2">
<Text>Filter by Public Model Name:</Text>
<div className="w-64">
<Select
className="w-64"
defaultValue={selectedModelGroup ?? "all"}
onValueChange={(value) => setSelectedModelGroup(value === "all" ? "all" : value)}
value={selectedModelGroup ?? "all"}
onValueChange={(value) => setSelectedModelGroup(value === "all" ? "all" : value)}
placeholder="Filter by Public Model Name"
>
<SelectItem value="all">All Models</SelectItem>
<SelectItem value="wildcard">Wildcard Models (*)</SelectItem>
@@ -1130,15 +1188,14 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
</Select>
</div>
<div className="flex items-center gap-2">
<Text>Filter by Model Access Group:</Text>
{/* Model Access Group Filter */}
<div className="w-64">
<Select
className="w-64"
defaultValue="all"
value={selectedModelAccessGroupFilter ?? "all"}
onValueChange={(value) =>
setSelectedModelAccessGroupFilter(value === "all" ? null : value)
}
placeholder="Filter by Model Access Group"
>
<SelectItem value="all">All Model Access Groups</SelectItem>
{availableModelAccessGroups.map((accessGroup, idx) => (
@@ -1149,11 +1206,11 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
</Select>
</div>
</div>
</div>
)}
{/* Results Count */}
<div className="flex justify-between items-center">
<Text className="text-sm text-gray-700">
<span className="text-sm text-gray-700">
Showing{" "}
{modelData && modelData.data.length > 0
? modelData.data.filter((model: any) => {
@@ -1164,7 +1221,8 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
const modelNameMatch =
selectedModelGroup === "all" ||
model.model_name === selectedModelGroup ||
!selectedModelGroup
!selectedModelGroup ||
(selectedModelGroup === "wildcard" && model.model_name?.includes("*"))
const accessGroupMatch =
selectedModelAccessGroupFilter === "all" ||
model.model_info["access_groups"]?.includes(selectedModelAccessGroupFilter) ||
@@ -1183,7 +1241,7 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
}).length
: 0}{" "}
results
</Text>
</span>
</div>
</div>
</div>