-
-
Notifications
You must be signed in to change notification settings - Fork 181
feat(providers): add group-level priority override #641
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
Closed
Closed
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
fd7ec4e
feat(providers): add group-level priority override
NieiR 8abd137
fix(providers): address code review feedback for group priority feature
NieiR 3b2ab21
feat(UI): change group selection to horizontal flow layout
NieiR 8d55f33
fix(validation): add max length constraint to group_priorities record…
NieiR 8bd0e08
docs: add mobile usage logs card layout design
NieiR 781bfae
docs: add mobile leaderboard optimization design
NieiR ba86153
Merge remote-tracking branch 'upstream/dev' into feature/group-priori…
NieiR 0ccfc6f
feat(dashboard): add mobile responsive layouts for provider, leaderbo…
NieiR 105eb25
fix: address lint errors from upstream merge
NieiR a2ae323
fix(test): update TagInput highlight tests for horizontal flow layout
NieiR 50bc1e4
chore: format code (feature-group-priority-override-a2ae323)
github-actions[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| # Mobile Leaderboard Optimization Design | ||
|
|
||
| ## Problem | ||
|
|
||
| The leaderboard page has usability issues on mobile devices: | ||
|
|
||
| 1. **Tab labels truncated** - "供应商缓存命中率排行" gets cut off, appearing as garbled text | ||
| 2. **Table too cramped** - 4+ columns squeezed into narrow viewport | ||
| 3. **Filter inputs crowded** - Two TagInputs side by side have limited width | ||
|
|
||
| ## Solution Overview | ||
|
|
||
| Transform the leaderboard from table-based layout to card-based layout on mobile, with simplified tab labels and stacked filter inputs. | ||
|
|
||
| ## Design Details | ||
|
|
||
| ### 1. Tab Label Simplification | ||
|
|
||
| Use shorter labels on mobile (< 768px): | ||
|
|
||
| | Desktop | Mobile | | ||
| |---------|--------| | ||
| | 用户排行 | 用户 | | ||
| | 供应商排行 | 供应商 | | ||
| | 供应商缓存命中率排行 | 缓存率 | | ||
| | 模型排行 | 模型 | | ||
|
|
||
| Implementation: Use `useIsMobile()` hook to conditionally render tab labels. | ||
|
|
||
| ### 2. Card-Based Layout | ||
|
|
||
| Replace table with expandable cards on mobile. | ||
|
|
||
| #### Default View (Collapsed) | ||
|
|
||
| ``` | ||
| ┌─────────────────────────────────────┐ | ||
| │ 🏆 #1 username $18.01M │ → tap to expand | ||
| ├─────────────────────────────────────┤ | ||
| │ 🥈 #2 another_user $5.32M │ | ||
| ├─────────────────────────────────────┤ | ||
| │ 🥉 #3 test_account $2.10M │ | ||
| └─────────────────────────────────────┘ | ||
| ``` | ||
|
|
||
| - Left: Rank badge (reuse existing Trophy/Medal/Award icons) | ||
| - Center: Name (user/provider/model depending on scope) | ||
| - Right: Primary metric (cost/tokens) | ||
| - Visual: Top 3 highlighted with `bg-muted/50` | ||
|
|
||
| #### Expanded View | ||
|
|
||
| ``` | ||
| ┌─────────────────────────────────────┐ | ||
| │ 🏆 #1 default ▲ 收起 │ | ||
| │─────────────────────────────────────│ | ||
| │ 请求数 Token数 消耗 │ | ||
| │ 299 18.01M $12.50 │ | ||
| └─────────────────────────────────────┘ | ||
| ``` | ||
|
|
||
| Fields by scope: | ||
|
|
||
| | Scope | Expanded Fields | | ||
| |-------|-----------------| | ||
| | User | requests, tokens, cost | | ||
| | Provider | requests, cost, tokens, successRate, avgTtfbMs, avgTokensPerSecond | | ||
| | CacheHitRate | requests, cacheHitRate, cacheReadTokens, totalInputTokens | | ||
| | Model | requests, tokens, cost, successRate | | ||
|
|
||
| Layout: | ||
| - 3-4 fields: single row `grid-cols-3` | ||
| - 5-6 fields: two rows `grid-cols-3` | ||
|
|
||
| ### 3. Filter Area | ||
|
|
||
| Mobile layout (stacked): | ||
|
|
||
| ``` | ||
| ┌─────────────────────────────────────┐ | ||
| │ [按用户标签筛选... ] │ ← full width | ||
| │ [按用户分组筛选... ] │ ← full width | ||
| ├─────────────────────────────────────┤ | ||
| │ [今日] [本周] [本月] [全部] │ ← keep horizontal | ||
| │ [<] [2026-01-24 ] [>] │ | ||
| └─────────────────────────────────────┘ | ||
| ``` | ||
|
|
||
| Changes: | ||
| - TagInputs stack vertically on mobile | ||
| - Each TagInput takes full width | ||
| - Date picker area remains unchanged | ||
|
|
||
| ### 4. Responsive Switching | ||
|
|
||
| Use existing `useIsMobile()` hook from `src/lib/hooks/use-mobile.ts`: | ||
| - Breakpoint: 768px | ||
| - Mobile (< 768px): Render card components | ||
| - Desktop (>= 768px): Keep existing table | ||
|
|
||
| ## Implementation Plan | ||
|
|
||
| ### Files to Create | ||
|
|
||
| 1. `src/app/[locale]/dashboard/leaderboard/_components/mobile-leaderboard-card.tsx` | ||
| - Reusable card component for all scopes | ||
| - Props: rank, data, scope, expanded, onToggle | ||
|
|
||
| ### Files to Modify | ||
|
|
||
| 1. `src/app/[locale]/dashboard/leaderboard/_components/leaderboard-view.tsx` | ||
| - Add `useIsMobile()` hook | ||
| - Conditionally render mobile tabs labels | ||
| - Stack TagInputs on mobile | ||
| - Render cards instead of table on mobile | ||
|
|
||
| 2. `messages/*/dashboard/leaderboard.json` (all 5 languages) | ||
| - Add short tab labels: `tabs.userRankingShort`, `tabs.providerRankingShort`, etc. | ||
|
|
||
| ### Files Unchanged | ||
|
|
||
| - `leaderboard-table.tsx` - Desktop table component, no changes needed | ||
| - `date-range-picker.tsx` - Already works on mobile | ||
|
|
||
| ## Related Work | ||
|
|
||
| This follows the same pattern as the mobile logs optimization: | ||
| - `src/app/[locale]/dashboard/logs/_components/mobile-log-card.tsx` | ||
| - `src/app/[locale]/dashboard/logs/_components/mobile-logs-list.tsx` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| # Mobile Usage Logs Card Layout Design | ||
|
|
||
| ## Overview | ||
|
|
||
| Optimize the usage logs display on mobile devices (< 768px) by replacing the table layout with a card-based layout that shows all essential information without truncation. | ||
|
|
||
| ## Problem | ||
|
|
||
| Current table layout on mobile: | ||
| - 11 columns squeezed into narrow screen | ||
| - Content truncated with `...` everywhere | ||
| - Users cannot see complete information | ||
| - Poor mobile browsing experience | ||
|
|
||
| ## Solution | ||
|
|
||
| Switch to card-based layout on mobile while keeping desktop table unchanged. | ||
|
|
||
| ## Card Structure | ||
|
|
||
| ``` | ||
| +-------------------------------------+ | ||
| | [Header] Time + Status Badge | | ||
| | Left: Relative time (3s ago) | | ||
| | Right: Status badge (OK 200) | | ||
| +-------------------------------------+ | ||
| | [Identity] User + Provider + Model | | ||
| | Username - Provider name | | ||
| | Model name (with redirect arrow) | | ||
| +-------------------------------------+ | ||
| | [Data] Tokens + Cache + Cost | | ||
| | Col1: Input/Output tokens | | ||
| | Col2: Cache write/read | | ||
| | Col3: Cost amount | | ||
| +-------------------------------------+ | ||
| | [Performance] Duration + TTFB + Rate| | ||
| | Total time - TTFB - Output rate | | ||
| +-------------------------------------+ | ||
| ``` | ||
|
|
||
| ## Visual Design | ||
|
|
||
| ### Card Base Style | ||
| - Border radius: `rounded-lg` | ||
| - Border: `border` | ||
| - Gap between cards: `gap-3` (12px) | ||
| - Padding: `p-3` (12px) | ||
| - Click feedback: slight press effect | ||
|
|
||
| ### Status Badges | ||
|
|
||
| | Status | Style | Example | | ||
| |--------|-------|---------| | ||
| | Success (200) | Green background | `OK 200` | | ||
| | Client error (4xx) | Orange background | `! 429` | | ||
| | Server error (5xx) | Red background | `X 500` | | ||
| | Blocked | Orange outline | `Blocked` | | ||
|
|
||
| ### Special States | ||
| - **Session resume**: Small tag after provider name | ||
| - **Model redirect**: Arrow display `gpt-4 -> claude-sonnet` | ||
| - **Cost multiplier**: Badge next to cost `x1.50` | ||
| - **Non-billing request**: Muted card background `bg-muted/60` | ||
|
|
||
| ### Data Section Layout | ||
| ``` | ||
| +-----------+-----------+---------+ | ||
| | Tokens | Cache | Cost | | ||
| | In: 1.2K | W: 500 | $0.0234 | | ||
| | Out: 856 | R: 2.1K | | | ||
| +-----------+-----------+---------+ | ||
| ``` | ||
| - Three equal-width columns | ||
| - Numbers right-aligned | ||
| - Labels left-aligned | ||
|
|
||
| ## Implementation | ||
|
|
||
| ### File Structure | ||
| ``` | ||
| src/app/[locale]/dashboard/logs/_components/ | ||
| ├── virtualized-logs-table.tsx # Add responsive detection | ||
| ├── mobile-log-card.tsx # New: Single card component | ||
| └── mobile-logs-list.tsx # New: Mobile card list with virtual scroll | ||
| ``` | ||
|
|
||
| ### Changes | ||
|
|
||
| 1. **virtualized-logs-table.tsx** | ||
| - Import `useIsMobile()` hook | ||
| - Render `MobileLogsList` when `isMobile` | ||
| - Keep existing table for desktop | ||
|
|
||
| 2. **mobile-log-card.tsx** | ||
| - Accept single log data | ||
| - Render four sections (header/identity/data/performance) | ||
| - Click triggers `onCardClick` to open detail dialog | ||
|
|
||
| 3. **mobile-logs-list.tsx** | ||
| - Reuse existing `useInfiniteQuery` logic | ||
| - Reuse existing `useVirtualizer` for virtual scrolling | ||
| - Adjust `ROW_HEIGHT` to card height (~140px) | ||
|
|
||
| ### Reused Components | ||
| - Data fetching: `getUsageLogsBatch` | ||
| - Detail dialog: `ErrorDetailsDialog` | ||
| - Time format: `RelativeTime` | ||
| - Currency format: `formatCurrency` | ||
| - Token format: `formatTokenAmount` | ||
|
|
||
| ## Interaction | ||
|
|
||
| - Tap card: Open detail dialog (reuse ErrorDetailsDialog) | ||
| - Virtual scrolling: Infinite scroll with auto-fetch | ||
| - Pull to refresh: Supported via existing refresh logic | ||
|
|
||
| ## Responsive Breakpoint | ||
|
|
||
| - `< 768px`: Card layout (mobile) | ||
| - `>= 768px`: Table layout (desktop) | ||
|
|
||
| Detection via `useIsMobile()` hook from `@/lib/hooks/use-mobile.ts` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| ALTER TABLE "providers" ALTER COLUMN "provider_vendor_id" DROP NOT NULL;--> statement-breakpoint | ||
| ALTER TABLE "providers" ADD COLUMN "group_priorities" jsonb DEFAULT 'null'::jsonb; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
为代码块补充语言标识以通过 markdownlint。
目前的围栏代码块缺少语言标识,建议统一标注为
text。修改建议
Also applies to: 66-72, 80-85
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
21-21: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents