Inbox views
Saved filters over agent runs, like Needs review or Failed this week, with live counts and a way to make your own.
Loading preview…
Install
- 1
Run this command in your Tailwind CSS project. It adds
components/ai/inbox-views-tabs.tsxand installs its dependencies.$ npx shadcn@latest add https://gradientdeck.com/ai-components/r/inbox-views-tabs.json
Usage & API
Example
import { AgentMark } from "@/components/ai/inbox-views-tabs"
<AgentMark
agent={agent}
/>Props AgentMark
| Prop | Type & description | Required |
|---|---|---|
agent | InboxAgent | Required |
size | "sm" | "md" | Optional |
Dependencies
- React
- Tailwind CSS
- motion
- lucide-react
Implementation notes
Tabs show each view name and a live count, and a dot when the open view's filters differ from what was saved. The bar under them lists the filters as chips. Remove drops one. Add inserts a field, an operator and a value. Status options are the run states. Agent options are the agents you configured. Trigger options in the preview include Schedule, a ticket, GitHub, an alert and a git tag. Reset puts the saved filters back. Save as asks for a view name, refuses a name already taken, and calls you with the new view. Delete view is there for a custom one. An empty match says no runs match and that new matching runs will show up here. All, with no filters, is labeled as every run.
Choosing a layout
Use the tabs when the inbox is a single page and three or four views are enough to sit across the top, with the filter builder directly under them. Use the sidebar when views are part of the navigation, including a private My views group, and when people will rename and reorder them the way they reorder folders.
The list and the open run beside it are the agent inbox. These views are the saved queries over that list. A one-off decision with an undo window is the decision inbox. If you only ever show one status, you do not need a view model. The value is the named filter and the count next to it.
Do the counts include runs that are filtered out of the list?
Each count is the number of runs that match that view's filters, not the number currently painted. Changing a filter on the open view does not change the saved count until the view is updated. The dirty mark is how you see that the chips and the saved view disagree.
Can two views share a name?
Save as checks the names you pass as taken and will not accept a duplicate. Rename in the sidebar writes whatever you submit through onRename. Keeping names unique is that taken-name check, not a second list inside the sidebar.