feat(ui): show item counts on inbox filter tabs#1922
feat(ui): show item counts on inbox filter tabs#1922bluzername wants to merge 2 commits intopaperclipai:masterfrom
Conversation
The Inbox page had four tabs (Mine, Recent, Unread, All) but none of them show how many items are in each category. User had to click each tab to find out if there are any items. Now the first three tabs show counts in parentheses: - Mine (5) - Recent (12) - Unread (3) - All (no count, shows everything) The "All" tab doesn't show a count because it include mixed content types (issues, approvals, join requests, failed runs) and the total would be misleading. The counts come from the already-computed memoized arrays: mineIssues, touchedIssues, unreadTouchedIssues.
Greptile SummaryThis PR adds item counts to the "Mine", "Recent", and "Unread" inbox filter tabs (e.g. Confidence Score: 5/5Safe to merge; no runtime errors or data issues introduced — remaining findings are UX polish and a PR description gap All findings are P2: a brief (0) flash during loading and a potential count/rendered-item discrepancy when approvals or failed runs are present. Neither blocks correct functionality. The core change — surfacing issue counts on inbox tabs — is correct and matches how existing arrays are already used. ui/src/pages/Inbox.tsx — verify whether issue-only counts are the intended design or if total workItemsToRender count would be more accurate Important Files Changed
Prompt To Fix All With AIThis is a comment left during a code review.
Path: ui/src/pages/Inbox.tsx
Line: 963-969
Comment:
**Counts show (0) during loading**
`mineIssuesRaw` and `touchedIssuesRaw` both default to `[]` (lines 586 and 599), so all three counts render as `Mine (0)`, `Recent (0)`, `Unread (0)` while the queries are in-flight. The tab bar is always rendered before `allLoaded` is true, so users will briefly see zeros before the real numbers appear. Consider suppressing the count suffix while loading, e.g.:
```suggestion
label: `Mine${isMineIssuesLoading ? "" : ` (${mineIssues.length})`}`,
```
```suggestion
label: `Recent${isTouchedIssuesLoading ? "" : ` (${touchedIssues.length})`}`,
```
```suggestion
{ value: "unread", label: `Unread${isTouchedIssuesLoading ? "" : ` (${unreadTouchedIssues.length})`}` },
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: ui/src/pages/Inbox.tsx
Line: 963-969
Comment:
**Tab counts only reflect issues, not all rendered items**
Each tab actually renders a mixed list via `workItemsToRender`, which includes **approvals**, **failed runs**, and **join requests** alongside issues (`getInboxWorkItems` in `inbox.ts` line 174-200). Specifically, from `getApprovalsForTab` (line 156):
- `mine` and `recent` tabs receive **all** approvals
- `unread` tab receives all approvals with actionable statuses
So "Mine (5)" could show 5 issues + several approvals + failed runs, meaning the label count does not match the number of items a user actually sees when they click the tab. If the intent is to count only issues, a comment explaining that design decision would help future readers. If the intent is to reflect total visible items, `workItemsToRender.length` would be the accurate value to use here.
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "feat(ui): show item counts on inbox filt..." | Re-trigger Greptile |
ui/src/pages/Inbox.tsx
Outdated
| label: `Mine (${mineIssues.length})`, | ||
| }, | ||
| { | ||
| value: "recent", | ||
| label: "Recent", | ||
| label: `Recent (${touchedIssues.length})`, | ||
| }, | ||
| { value: "unread", label: "Unread" }, | ||
| { value: "unread", label: `Unread (${unreadTouchedIssues.length})` }, |
There was a problem hiding this comment.
Counts show (0) during loading
mineIssuesRaw and touchedIssuesRaw both default to [] (lines 586 and 599), so all three counts render as Mine (0), Recent (0), Unread (0) while the queries are in-flight. The tab bar is always rendered before allLoaded is true, so users will briefly see zeros before the real numbers appear. Consider suppressing the count suffix while loading, e.g.:
| label: `Mine (${mineIssues.length})`, | |
| }, | |
| { | |
| value: "recent", | |
| label: "Recent", | |
| label: `Recent (${touchedIssues.length})`, | |
| }, | |
| { value: "unread", label: "Unread" }, | |
| { value: "unread", label: `Unread (${unreadTouchedIssues.length})` }, | |
| label: `Mine${isMineIssuesLoading ? "" : ` (${mineIssues.length})`}`, |
| label: `Mine (${mineIssues.length})`, | |
| }, | |
| { | |
| value: "recent", | |
| label: "Recent", | |
| label: `Recent (${touchedIssues.length})`, | |
| }, | |
| { value: "unread", label: "Unread" }, | |
| { value: "unread", label: `Unread (${unreadTouchedIssues.length})` }, | |
| label: `Recent${isTouchedIssuesLoading ? "" : ` (${touchedIssues.length})`}`, |
| label: `Mine (${mineIssues.length})`, | |
| }, | |
| { | |
| value: "recent", | |
| label: "Recent", | |
| label: `Recent (${touchedIssues.length})`, | |
| }, | |
| { value: "unread", label: "Unread" }, | |
| { value: "unread", label: `Unread (${unreadTouchedIssues.length})` }, | |
| { value: "unread", label: `Unread${isTouchedIssuesLoading ? "" : ` (${unreadTouchedIssues.length})`}` }, |
Prompt To Fix With AI
This is a comment left during a code review.
Path: ui/src/pages/Inbox.tsx
Line: 963-969
Comment:
**Counts show (0) during loading**
`mineIssuesRaw` and `touchedIssuesRaw` both default to `[]` (lines 586 and 599), so all three counts render as `Mine (0)`, `Recent (0)`, `Unread (0)` while the queries are in-flight. The tab bar is always rendered before `allLoaded` is true, so users will briefly see zeros before the real numbers appear. Consider suppressing the count suffix while loading, e.g.:
```suggestion
label: `Mine${isMineIssuesLoading ? "" : ` (${mineIssues.length})`}`,
```
```suggestion
label: `Recent${isTouchedIssuesLoading ? "" : ` (${touchedIssues.length})`}`,
```
```suggestion
{ value: "unread", label: `Unread${isTouchedIssuesLoading ? "" : ` (${unreadTouchedIssues.length})`}` },
```
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Fixed. Now the count is hidden while query is loading, so no more (0) flash. Pushed in 139c62f.
ui/src/pages/Inbox.tsx
Outdated
| label: `Mine (${mineIssues.length})`, | ||
| }, | ||
| { | ||
| value: "recent", | ||
| label: "Recent", | ||
| label: `Recent (${touchedIssues.length})`, | ||
| }, | ||
| { value: "unread", label: "Unread" }, | ||
| { value: "unread", label: `Unread (${unreadTouchedIssues.length})` }, |
There was a problem hiding this comment.
Tab counts only reflect issues, not all rendered items
Each tab actually renders a mixed list via workItemsToRender, which includes approvals, failed runs, and join requests alongside issues (getInboxWorkItems in inbox.ts line 174-200). Specifically, from getApprovalsForTab (line 156):
mineandrecenttabs receive all approvalsunreadtab receives all approvals with actionable statuses
So "Mine (5)" could show 5 issues + several approvals + failed runs, meaning the label count does not match the number of items a user actually sees when they click the tab. If the intent is to count only issues, a comment explaining that design decision would help future readers. If the intent is to reflect total visible items, workItemsToRender.length would be the accurate value to use here.
Prompt To Fix With AI
This is a comment left during a code review.
Path: ui/src/pages/Inbox.tsx
Line: 963-969
Comment:
**Tab counts only reflect issues, not all rendered items**
Each tab actually renders a mixed list via `workItemsToRender`, which includes **approvals**, **failed runs**, and **join requests** alongside issues (`getInboxWorkItems` in `inbox.ts` line 174-200). Specifically, from `getApprovalsForTab` (line 156):
- `mine` and `recent` tabs receive **all** approvals
- `unread` tab receives all approvals with actionable statuses
So "Mine (5)" could show 5 issues + several approvals + failed runs, meaning the label count does not match the number of items a user actually sees when they click the tab. If the intent is to count only issues, a comment explaining that design decision would help future readers. If the intent is to reflect total visible items, `workItemsToRender.length` would be the accurate value to use here.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Good catch. The counts are intentionally showing issues only, not total rendered items. I added explanation in the PR description for why - basically issues are the main work unit, and approvals/failed runs show on multiple tabs so counting them would inflate numbers without useful signal. Added a code comment too for future readers.
Suppress count display during query loading so users do not see misleading (0) values before the real numbers arrive.
Thinking Path
Problem
The Inbox page have four filter tabs at the top: "Mine", "Recent", "Unread", "All". But none of them show how many items are in each category. When I open the inbox, I don't know if I have 3 unread items or 30 without clicking the "Unread" tab first.
The Approvals page already show count on the "Pending" tab (line 90-96 in Approvals.tsx), and we just added counts to the Agents page tabs too. But Inbox was missing this even though it is probably the most important page to have quick count visibility.
What I changed
Added item counts to the three main tabs:
All three arrays are already computed and memoized in the component, so this add zero extra API calls or computation.
Why counts show issues only, not total rendered items
Each tab also render approvals, failed runs, and join requests alongside issues. The counts here intentionally reflect issues only because:
Loading state
Counts are hidden while the queries are still in-flight, so users will not see misleading (0) values. Once data arrive, the count appears next to each tab label.
How to test
1 file, ~7 lines changed.