Skip to content

Commit

The top bar's spend pill counts both tabs the same way, at price: You is what agents did for you, Workspace is everything the workspace used this month, the figure Home and Spend show, with what it was charged after its plan and credit underneath, against its spend limit; so a comped workspace reads as what it used and nothing charged, not the other way round. The spend guide says so.

syntaqxcommitted Parent9845922Browse files
3 files+40−230/3 viewed
+9−6
171171 ## In the top bar
172172
173173 Your spend this month sits in the page's header, beside **Ask g1t**: what
174−agents did for you against your budget. Choose it for where it went, by
175−kind of work and by agent, and a link to Spend. Owners and billing
176−managers can switch it to **Workspace**: what the workspace was charged
177−this month against its spend limit, and its agents' spend. The choice is
178−remembered on this browser. On a phone, open **Spend** from the Workspace
179−sidebar instead.
174+agents did for you, at price, against your budget. Choose it for where it
175+went, by kind of work and by agent, and a link to Spend. Owners and billing
176+managers can switch it to **Workspace**: everything the workspace used
177+this month at price, the same figure as Home and Spend, with what it was
178+charged after its plan and credit underneath, against its spend limit, and
179+its agents' share. Both tabs count at price, so they add up: a comped
180+workspace can show $10 used and $0 charged. The choice is remembered on
181+this browser. On a phone, open **Spend** from the Workspace sidebar
182+instead.
180183
181184 ## Next
182185
+21−14
556556 }
557557
558558 /**
559− * Your spend this month in the top bar: what agents did for you against
560− * your budget, or, for owners and billing managers who switch it, what the
561− * workspace was charged against its spend limit. A click opens where it
562− * went. Read after the page draws, so it adds nothing to the page's time.
559+ * Your spend this month in the top bar: what agents did for you, at price,
560+ * against your budget, or, for owners and billing managers who switch it,
561+ * everything the workspace used at price, with what it was charged against
562+ * its spend limit underneath. Both tabs count the same way, at price, so
563+ * the numbers add up across them. A click opens where it went. Read after
564+ * the page draws, so it adds nothing to the page's time.
563565 */
564566 export function SpendPill({ slug, mayWorkspace }: { slug: string; mayWorkspace: boolean }) {
565567 const pill = useFetcher<PillData>({ key: `spend-pill:${slug}` });
585587 const data = pill.data;
586588 const ws = scope === "workspace" ? data?.workspace : null;
587589 const spent = ws ? ws.spentMicros : (data?.me?.spentMicros ?? null);
590+ // The limit governs what is charged, so the meter measures that.
591+ const against = ws ? ws.chargedMicros : (data?.me?.spentMicros ?? null);
588592 const budget = ws ? ws.limitMicros : (data?.me?.budgetMicros ?? null);
589− const share = spent != null ? shareOfBudget(spent, budget) : null;
593+ const share = against != null ? shareOfBudget(against, budget) : null;
590594 const label = spent == null ? (data ? "Spend" : "") : money(spent);
591595 return (
592596 <Popover open={open} onOpenChange={setOpen}>
601605 {data ? <span>{label}</span> : <Skeleton className="h-3 w-10" />}
602606 {share != null && (
603607 <span className="hidden w-9 lg:block">
604− <Meter spent={spent!} cap={budget} label="Spent of the budget" size="sm" />
608+ <Meter spent={against!} cap={budget} label={ws ? "Charged of the spend limit" : "Spent of your budget"} size="sm" />
605609 </span>
606610 )}
607611 </Button>
661665 </div>
662666 ) : ws ? (
663667 <div className="p-4">
664− <p className="text-xs text-muted">The workspace · {month}, charged</p>
665− <p className="mt-1 text-xl font-semibold tabular-nums">
666− {ws.spentMicros != null ? money(ws.spentMicros) : "—"}
667− {ws.limitMicros != null && <span className="ml-1.5 text-sm font-normal text-muted">of {money(ws.limitMicros)}</span>}
668− </p>
669− {ws.spentMicros != null && ws.limitMicros != null && <Meter spent={ws.spentMicros} cap={ws.limitMicros} label="Charged of the spend limit" size="sm" className="mt-2" />}
670− <p className="mt-3 text-xs text-muted">Agents this month{ws.agentsMicros != null ? `: ${money(ws.agentsMicros)}` : ""}</p>
668+ <p className="text-xs text-muted">The workspace · {month}, everything it used, at price</p>
669+ <p className="mt-1 text-xl font-semibold tabular-nums">{ws.spentMicros != null ? money(ws.spentMicros) : "—"}</p>
670+ {ws.chargedMicros != null && (
671+ <p className="mt-1 text-xs text-muted">
672+ Charged after its plan and credit: <span className="text-fg tabular-nums">{money(ws.chargedMicros)}</span>
673+ {ws.limitMicros != null ? ` of a ${money(ws.limitMicros)} spend limit` : " · no spend limit set"}
674+ </p>
675+ )}
676+ {ws.chargedMicros != null && ws.limitMicros != null && <Meter spent={ws.chargedMicros} cap={ws.limitMicros} label="Charged of the spend limit" size="sm" className="mt-2" />}
677+ <p className="mt-3 text-xs text-muted">Of that, agents{ws.agentsMicros != null ? `: ${money(ws.agentsMicros)}` : ""}</p>
671678 <PopoverSlices slices={ws.byAgent} />
672679 </div>
673680 ) : data.me ? (
674681 <div className="p-4">
675− <p className="text-xs text-muted">You · {month}, agents working for you included</p>
682+ <p className="text-xs text-muted">You · {month}, what agents did for you, at price</p>
676683 <p className="mt-1 text-xl font-semibold tabular-nums">
677684 {money(data.me.spentMicros)}
678685 {data.me.budgetMicros != null && <span className="ml-1.5 text-sm font-normal text-muted">of {money(data.me.budgetMicros)}</span>}
+10−3
8686 export type PillData = {
8787 month: string;
8888 me: { spentMicros: number; budgetMicros: number | null; byKind: AgentSpendBreakdown["by_kind"]; byAgent: AgentSpendBreakdown["by_agent"] } | null;
89− workspace: { spentMicros: number | null; limitMicros: number | null; agentsMicros: number | null; byAgent: AgentSpendBreakdown["by_agent"] } | null;
89+ /**
90+ * The workspace's month: everything it used at price (the figure Home and
91+ * Spend show), what it was charged after its plan and credit (the figure
92+ * its spend limit governs), its limit, and its agents' share.
93+ */
94+ workspace: { spentMicros: number | null; chargedMicros: number | null; limitMicros: number | null; agentsMicros: number | null; byAgent: AgentSpendBreakdown["by_agent"] } | null;
9095 };
9196
9297 export async function loadPill(viewer: User, slug: string, mayWorkspace: boolean): Promise<PillData> {
9398 const me = viewer.username.toLowerCase();
94− const [mine, people, everyone, limit] = await Promise.all([
99+ const [mine, people, everyone, limit, used] = await Promise.all([
95100 loadBreakdown(viewer, slug, "me", "month"),
96101 workspaceAgents.personBudgets(slug, viewer).then(value).catch(warn("person budgets")),
97102 mayWorkspace ? loadBreakdown(viewer, slug, "workspace", "month") : Promise.resolve(null),
98103 mayWorkspace ? billing.limit(slug, viewer).then(value).catch(warn("limit")) : Promise.resolve(null),
104+ mayWorkspace ? loadUsage(viewer, slug, "month", new Date()) : Promise.resolve(null),
99105 ]);
100106 const own = people?.people.find((p) => p.username === me);
101107 const budget = own ? own.monthly_micros : (people?.default_micros ?? null);
104110 me: mine ? { spentMicros: mine.total_micros, budgetMicros: budget, byKind: mine.by_kind, byAgent: mine.by_agent } : null,
105111 workspace: mayWorkspace
106112 ? {
107− spentMicros: limit?.spentMicros ?? null,
113+ spentMicros: used ? (used.free ? used.totals.costMicros : used.totals.priceMicros) : null,
114+ chargedMicros: limit?.spentMicros ?? null,
108115 limitMicros: limit ? (limit.spendLimitMicros ?? limit.ceilingMicros) : null,
109116 agentsMicros: everyone?.total_micros ?? null,
110117 byAgent: everyone?.by_agent ?? [],