feat(05-03): policy-level BudgetSummary, incident-based BudgetAlertBanner, AgentEditor policy wiring

- BudgetSummary shows policy-level utilization bars when companyId provided, falls back to agent-level
- BudgetAlertBanner loads open incidents for policy-based alerts (warn_threshold/hard_stop), falls back to agent thresholds
- AgentEditor reads budget from budget_policies and writes budget as policy on save (D-11)
- Dashboard passes companyId through to BudgetAlertBanner
This commit is contained in:
ZacharyZhang-NY committed 2026-03-26 21:17:02 -04:00
1 parent 3a8e4c40ad
commit 1c462d571c
5 files changed
+217 -46

No files matched your search

@@ -30,6 +30,7 @@ import { BudgetAlertBanner } from "./BudgetAlertBanner";
export interface DashboardProps {
companyName?: string;
companyId?: string;
agents: AgentRecord[];
tasks: TaskRecord[];
runs: RunRecord[];
@@ -44,7 +45,7 @@ export interface DashboardProps {
export function Dashboard(props: DashboardProps) {
const t = useT();
const { companyName, agents, tasks, runs, approvals, activity, costs, messages = [], onNavigate } = props;
const { companyName, companyId, agents, tasks, runs, approvals, activity, costs, messages = [], onNavigate } = props;
const agentMap = useMemo(() => new Map(agents.map((a) => [a.id, a])), [agents]);
const taskMap = useMemo(() => new Map(tasks.map((t) => [t.id, t])), [tasks]);
@@ -95,7 +96,7 @@ export function Dashboard(props: DashboardProps) {
{/* Conditional banners */}
<RecoveryBanner />
<BudgetAlertBanner agents={agents} onNavigate={onNavigate} />
<BudgetAlertBanner agents={agents} onNavigate={onNavigate} companyId={companyId} />
{/* Key Metrics — 4 cards */}
<div className="grid grid-cols-2 gap-3 lg:grid-cols-4">