UI: approval detail page, agent hiring UX, costs breakdown, sidebar badges, and dashboard improvements

Add ApprovalDetail page with comment thread, revision request/resubmit flow,
and ApprovalPayload component for structured payload display. Extend AgentDetail
with permissions management, config revision history, and duplicate action.
Add agent hire dialog with permission-gated access. Rework Costs page with
per-agent breakdown table and period filtering. Add sidebar badge counts for
pending approvals and inbox items. Enhance Dashboard with live metrics and
sparkline trends. Extend Agents list with pending_approval status and bulk
actions. Update IssueDetail with approval linking. Various component improvements
to MetricCard, InlineEditor, CommentThread, and StatusBadge.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Forgotten
2026-02-19 13:03:08 -06:00
parent 0d73e1b407
commit 176d279403
31 changed files with 1271 additions and 214 deletions

View File

@@ -68,6 +68,14 @@ export function Companies() {
},
});
const companySettingsMutation = useMutation({
mutationFn: ({ id, requireApproval }: { id: string; requireApproval: boolean }) =>
companiesApi.update(id, { requireBoardApprovalForNewAgents: requireApproval }),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: queryKeys.companies.all });
},
});
useEffect(() => {
setBreadcrumbs([{ label: "Companies" }]);
}, [setBreadcrumbs]);
@@ -260,6 +268,40 @@ export function Companies() {
</div>
</div>
{selected && (
<div
className="mt-4 border-t border-border pt-4"
onClick={(e) => e.stopPropagation()}
>
<div className="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2">
Advanced Settings
</div>
<div className="flex items-center justify-between gap-3 rounded-md border border-border px-3 py-2">
<div>
<div className="text-sm font-medium">Require board approval for new hires</div>
<div className="text-xs text-muted-foreground">
New agent hires stay pending until approved by board.
</div>
</div>
<Button
size="sm"
variant={
company.requireBoardApprovalForNewAgents ? "default" : "outline"
}
onClick={() =>
companySettingsMutation.mutate({
id: company.id,
requireApproval: !company.requireBoardApprovalForNewAgents,
})
}
disabled={companySettingsMutation.isPending}
>
{company.requireBoardApprovalForNewAgents ? "On" : "Off"}
</Button>
</div>
</div>
)}
{/* Delete confirmation */}
{isConfirmingDelete && (
<div