-
-
Notifications
You must be signed in to change notification settings - Fork 181
feat(leaderboard): add user tag and group filters for user ranking #607
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ import { ProviderTypeFilter } from "@/app/[locale]/settings/providers/_component | |
| import { Card, CardContent } from "@/components/ui/card"; | ||
| import { Skeleton } from "@/components/ui/skeleton"; | ||
| import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; | ||
| import { TagInput } from "@/components/ui/tag-input"; | ||
| import { formatTokenAmount } from "@/lib/utils"; | ||
| import type { | ||
| DateRangeParams, | ||
|
|
@@ -51,6 +52,8 @@ export function LeaderboardView({ isAdmin }: LeaderboardViewProps) { | |
| const [period, setPeriod] = useState<LeaderboardPeriod>(initialPeriod); | ||
| const [dateRange, setDateRange] = useState<DateRangeParams | undefined>(undefined); | ||
| const [providerTypeFilter, setProviderTypeFilter] = useState<ProviderType | "all">("all"); | ||
| const [userTagFilters, setUserTagFilters] = useState<string[]>([]); | ||
| const [userGroupFilters, setUserGroupFilters] = useState<string[]>([]); | ||
| const [data, setData] = useState<AnyEntry[]>([]); | ||
| const [loading, setLoading] = useState(true); | ||
| const [error, setError] = useState<string | null>(null); | ||
|
|
@@ -96,6 +99,14 @@ export function LeaderboardView({ isAdmin }: LeaderboardViewProps) { | |
| ) { | ||
| url += `&providerType=${encodeURIComponent(providerTypeFilter)}`; | ||
| } | ||
| if (scope === "user") { | ||
| if (userTagFilters.length > 0) { | ||
| url += `&userTags=${encodeURIComponent(userTagFilters.join(","))}`; | ||
| } | ||
| if (userGroupFilters.length > 0) { | ||
| url += `&userGroups=${encodeURIComponent(userGroupFilters.join(","))}`; | ||
| } | ||
| } | ||
| const res = await fetch(url); | ||
|
|
||
| if (!res.ok) { | ||
|
|
@@ -120,7 +131,7 @@ export function LeaderboardView({ isAdmin }: LeaderboardViewProps) { | |
| return () => { | ||
| cancelled = true; | ||
| }; | ||
| }, [scope, period, dateRange, providerTypeFilter, t]); | ||
| }, [scope, period, dateRange, providerTypeFilter, userTagFilters, userGroupFilters, t]); | ||
|
|
||
| const handlePeriodChange = useCallback( | ||
| (newPeriod: LeaderboardPeriod, newDateRange?: DateRangeParams) => { | ||
|
|
@@ -369,6 +380,31 @@ export function LeaderboardView({ isAdmin }: LeaderboardViewProps) { | |
| ) : null} | ||
| </div> | ||
|
|
||
| {scope === "user" && isAdmin && ( | ||
| <div className="flex flex-wrap gap-4 mb-4"> | ||
| <div className="flex-1 min-w-[200px] max-w-[300px]"> | ||
| <TagInput | ||
| value={userTagFilters} | ||
| onChange={setUserTagFilters} | ||
| placeholder={t("filters.userTagsPlaceholder")} | ||
| disabled={loading} | ||
| maxTags={20} | ||
| clearable | ||
| /> | ||
| </div> | ||
| <div className="flex-1 min-w-[200px] max-w-[300px]"> | ||
| <TagInput | ||
| value={userGroupFilters} | ||
| onChange={setUserGroupFilters} | ||
| placeholder={t("filters.userGroupsPlaceholder")} | ||
| disabled={loading} | ||
| maxTags={20} | ||
| clearable | ||
| /> | ||
| </div> | ||
| </div> | ||
|
Comment on lines
+384
to
+405
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The two |
||
| )} | ||
|
|
||
| {/* Date range picker with quick period buttons */} | ||
| <div className="mb-6"> | ||
| <DateRangePicker | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
建议确认「userGroups」中文术语是否应为「用户组/用户群组」而非「用户分组」。
如果系统内其它地方把 group 统一翻译成「分组」,那现在的文案也没问题;主要是避免与「供应商分组」等概念混淆。
🤖 Prompt for AI Agents