Review Card
Asks someone to review a proposed change in chat before it happens. The header names the change and its status and opens or closes the details. The footer holds the outcome and the decision buttons.ReviewRows, ReviewSteps, andReviewValues lay out what will change.
- Change
- Updates an existing row
- Table
- Supplier deliveries
- Supplier
- Northwind TradersCurrently Northwind Traders
- Delivery date
- 14 Nov 2026Currently 7 Nov 2026
- Status
- DelayedCurrently On track
- Notes
- Carrier confirmed a one-week delay on the October order.Currently —
This chat used content from outside your tables, such as web pages, knowledge, files or connected apps, so the change waits for your approval. Approving makes this exact change with your table access.
- Table ID
- tbl_7d1c4e2a9b
- Row ID
- rec_0f9e81c4d2
- Applied revision
- 42
- Draft ID
- drf_5b2a7c19e0
- SHA-256
- 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
Usage
import { Database } from "reicon-react/icons/Database";
import {
ReviewCard,
ReviewRow,
ReviewRows,
} from "@tulipfarm/sprout/review-card";
<ReviewCard
label="Review row change"
icon={<Database size={16} />}
title="Update a row in Supplier deliveries"
badge={{ label: "Needs approval", variant: "warning" }}
settled={status !== "pending"}
actions={
<>
<Button onClick={approve}>Approve change</Button>
<Button variant="ghost" onClick={dismiss}>Dismiss</Button>
</>
}
status={<p role="status">{outcome}</p>}
>
<ReviewRows>
<ReviewRow label="Change">Updates an existing row</ReviewRow>
<ReviewRow label="Table">Supplier deliveries</ReviewRow>
</ReviewRows>
</ReviewCard>icon: a 14 or 16px icon shown in a tile before the title.badge:{ label, variant }. The variant is"warning","info","success","secondary","destructive","default", or"outline".settled: the decision is made. The card folds to its header and footer, and folds again each timesettledturns true. It opens again whensettledturns false.status: footer content that stays visible when folded, such as the outcome, feedback, or a status check.actions: decision buttons. They show only while the card is open.label: names the card, such as “Review row change”. Without it the title names the card.
Badge variants
Long titles end with an ellipsis; the badge and chevron keep their place.
Approval
An action that waits for approval. While submitting, both buttons are disabled and the chosen one shows a spinner. When settled, the card folds and focus moves to the outcome if the decision was made here.
The agent wants to post this reply with your Slack account.
- App
- Slack
- Channel
- #supplier-updates
- Posts as
- Your Slack account
- Message
- Thanks, Northwind. We’ve moved the October delivery to 14 November and updated the tracker.
Drafts
Workflow, agent, and skill drafts share one card. Agent drafts list the change, team, model, actions, and skills; long instructions keep their line breaks. Feedback, technical details, and a status check sit below.
- Change
- Updates existing agent “Supplier follow-up”
- Changed fields
- Instructions, Tools, Model family
Each Monday, check the Supplier deliveries table for late orders. Email each late supplier a polite reminder and post a summary in #supplier-updates.
- Team
- Operations
- Model
- Claude Sonnet
- Actions
- Read Gmail
- Send Gmail
- Read Slack
- Post to Slack
- Read GitHub issues
2 actions change data.
- Skills
- Summarize meeting notes
- Built-in skill: web-research
Saving does not activate these changes. An agent manager must activate the exact saved revision separately.
- Agent ID
- agt_3c9e10f2b7
- Team ID
- team_8a71c0
- Tool IDs
- google.gmail.read, google.gmail.send, slack.read, slack.post, github.issues.read
- Draft ID
- drf_4e8c2a9d71
- SHA-256
- 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae
Agent setup
Three decisions, with activation disabled until each consent box is checked. A sponsor conflict shows as an alert.
Updates the existing agent. The earlier active setup remains until this replacement succeeds.
- Team
- Operations
- Schedule 1
- Every Monday at 9:00 (Asia/Kolkata)
- Schedule 2
- Every day at 17:30 (Europe/London)
- Slack channel 1
- #supplier-updates
Only this review action can save or activate the setup. Chat text is not approval.
Workflow steps
ReviewSteps numbers each step. A step’sdetail can hold ReviewValues, code, or notes.
<ReviewSteps
title="3 steps"
steps={[
{
summary: "notify api: send POST to https://hooks.example.com/suppliers",
detail: (
<ReviewValues
values={[
{ name: "content-type", value: "application/json" },
{ name: "Body", value: body },
]}
/>
),
},
{ summary: "pause: wait 3600 seconds" },
]}
/>- Change
- Creates a new workflow. It stays inactive.
- Trigger
- When a row of “Supplier deliveries” is updated. Run input holds the row ID and its values before and after the change
- Watched fields
- “Status”, “Delivery date”
- Only rows where
- “Status” is “Delayed”
- Next run
- Within about a minute of each matching change
12 steps
find late: find up to 50 rows in “Supplier deliveries” matching 2 conditions
- “Status”
- is “Delayed”
- “Delivery date”
- before {{ trigger.date }}
check count: check whether {{ steps.find_late.count }} is greater than 0
- If it holds
- run draft reply, post summary
- Otherwise
- skip draft reply, post summary
draft reply: ask Supplier follow-up to write a reminder for each late supplier
Limits: 40 tool calls, 120 seconds, 25 Credits.
shape: set subject, owner
- subject
- Delivery reminder: {{ row.supplier }}
- owner
- {{ trigger.requester }}
notify api: send POST to https://hooks.example.com/suppliers
- content-type
- application/json
- x-shop-id
- northwind-eu
- Body
- { "supplier": "{{ row.supplier }}", "status": "delayed" }
score: run JavaScript code with {{ steps.find_late.rows }}
score.jslog result: add a row to “Follow-up log”, writing 2 fields
- “Supplier”
- {{ row.supplier }}
- “Sent at”
- {{ now }}
mark sent: update the row in {{ trigger.row }} in “Supplier deliveries”, writing 1 field
- unavailable field (fld_93a1)
- Reminder sent
approve: ask for a response. “Should we escalate suppliers more than two weeks late?”
pause: wait 3600 seconds
follow up: wait until the time in {{ trigger.row.delivery_date }}
post summary: send a Slack message
#supplier-updates · Slack workspace T024BE7LD
Channel C061EG9SL
Destination ID: dst_6f2b91e0
- Message
- {{ steps.find_late.count }} suppliers are late this week.
- Posts as
- TulipFarm app
Saving this workflow does not approve a send. Each run asks its requester or sponsor to approve the exact message. Approval expires after 24 hours.
Without actions
A table proposal whose values expired. It has no actions, only a status check, and scrolls inside a bounded area.
History values expired. Proposal values were permanently removed on 2 October 2026, 18:42.
The original digest and execution outcomes remain available. Ask for a new proposal to make further changes.
- Table 1: completed. 1,284 of 1,500 rows imported. 216 not yet imported.
- Table 2: Not completed
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Composition
- Owner
- Alex Meadow
- Status
- Draft
Changes
Create a planting list
- Plant
- Tulip
- Quantity
- 12
Assign watering to Robin
No review action taken.
Accessibility
The card is a section named by label or the title. The title is an h4 holding the button that opens and closes the details, with aria-expanded; the whole header is its click target, and its focus ring outlines the header. Enter and Space toggle it. The icon and chevron are hidden from assistive tech. Rows and values are description lists; steps are an ordered list under an h5, with the numbers hidden so screen readers use the list order.
The details grow and shrink in 180ms and the chevron turns in 120ms; with reduced motion both happen at once.
Theme tokens
The card uses --sprout-surface,--sprout-line, --sprout-canvas for the icon tile,--sprout-hover, --sprout-focus,--sprout-muted, and --sprout-secondary for step numbers. Badges use the Badge tokens.