Approved ≠ Applied
Neutralize the CPQ action-plan approval badge so blocked executions stop reading as successful draft writes.
An approved action plan rendered a green "N changes applied — saved as draft" badge, implying the write already landed. It hadn't — the actions may still be blocked from executing.
Rewrite the copy to "N changes approved for execution" and swap the celebratory green chrome for neutral tan/grey. No functional change, no logic change.
Single file, single component: ResolvedApprovalBadge in the ConfigAgent chat message renderer. Approved-state branch only.
1. Why this exists
Inside the ConfigAgent chat, when a user approves an action plan, the assistant bubble stamps a badge summarizing what happened. Before this PR, that badge said the changes were applied and saved as draft — green check, green border, green text. It looked like a success confirmation from a successful write.
The problem: approval and execution are two different things. A plan can be approved but its execution can then be blocked (permissions, downstream errors, whatever gates the actual apply). In that window, users saw the green "applied" badge and reasonably concluded the draft was already written. It wasn't.
This PR corrects the copy and the visual tone. It does not change the badge's trigger conditions or when it appears.
2. Before / after
Green border #5a8a5a, mint fill #eaf0e7, CheckIcon to the left, verb "applied", trailing claim "saved as draft".
Neutral grey border #e5e7eb, warm off-white fill #faf9f7, no icon, verb "approved for execution".
3. What changes in code
All edits are inside the resolved === 'approved' branch of ResolvedApprovalBadge in apps/client/src/dashboard/V3Admin/ConfigAgent/ChatMessages.tsx. Three concrete deltas:
N changes applied — saved as draft → N changes approved for execution
Border/fill/text swap from the green trio to neutral #e5e7eb / #faf9f7 / #6c6761.
The CheckIcon element is removed entirely. A checkmark reads as confirmation of a completed action.
Diff excerpt
if (resolved === 'approved') {
return (
- <div className="... border-[#5a8a5a] bg-[#eaf0e7] ...">
- <CheckIcon className="h-3.5 w-3.5 text-[#5a8a5a]" />
- <DealopsXS as="span" className="font-medium text-[#5a8a5a]">
- {actionCount} change{actionCount !== 1 ? 's' : ''} applied — saved as
- draft
+ <div className="... border-[#e5e7eb] bg-[#faf9f7] ...">
+ <DealopsXS as="span" className="font-medium text-[#6c6761]">
+ {actionCount} change{actionCount !== 1 ? 's' : ''} approved for
+ execution
</DealopsXS>
</div>
);
}
A stale comment on the sibling isExecuting guard is also trimmed — it referenced flipping to "the green 'N changes applied' badge", which no longer exists.
4. What it doesn't change
- No change to when the badge renders — the same
resolved === 'approved'andisExecutingguards still gate it. - No change to
actionCountderivation or pluralization logic. - No change to the
ThinkingIndicatorthat shows below the bubble during streaming. - No change to any other resolution state (rejected, pending, errored) or their badges.
- No change to server-side execution behavior — this is a pure client copy/style fix.
- No new dependencies, no new components;
CheckIconimport may become unused elsewhere in the file (worth a glance).
5. Risks & follow-up
- Is
CheckIconstill referenced elsewhere inChatMessages.tsx? If not, drop the import to silence a future lint warning. - The neutral palette (
#e5e7eb/#faf9f7/#6c6761) is hand-picked hex, not a design-token reference. Fine for a copy fix, but flag if the ConfigAgent surface has a shared "neutral info" token this should route through instead. - Copy: "approved for execution" is accurate but slightly bureaucratic. Product may prefer "N changes approved" or "N changes queued". Non-blocking.