Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const mockAISpend: UserAISpendStatus = {
period_end: "2026-07-01T00:00:00Z",
};

const spendPeriodLabel = "Estimated AI spend: June 1 - July 1, 2026";
const spendPeriodLabel = "Approximate AI spend June 1 - July 1, 2026";

const aiCostControl: { features: FeatureName[] } = {
features: ["aibridge"],
Expand Down Expand Up @@ -71,10 +71,10 @@ export const WithAISpend: Story = {
},
play: async ({ canvasElement, step }) => {
await step("shows AI spend", async () => {
const menu = await openDropdown(canvasElement);
await openDropdown(canvasElement);
await waitFor(() => {
expect(document.body).toHaveTextContent("$819 / $1,200 USD");
expect(menu.getByText(spendPeriodLabel)).toBeVisible();
expect(document.body).toHaveTextContent(spendPeriodLabel);
});
expect(
screen.getByRole("progressbar", { name: "AI spend usage" }),
Expand All @@ -95,10 +95,10 @@ export const AISpendWarning: Story = {
},
play: async ({ canvasElement, step }) => {
await step("shows the warning marker near the limit", async () => {
const menu = await openDropdown(canvasElement);
await openDropdown(canvasElement);
await waitFor(() => {
expect(document.body).toHaveTextContent("$1,080 / $1,200 USD");
expect(menu.getByText(spendPeriodLabel)).toBeVisible();
expect(document.body).toHaveTextContent(spendPeriodLabel);
});
expect(
screen.getByRole("progressbar", { name: "AI spend usage" }),
Expand Down Expand Up @@ -142,10 +142,10 @@ export const AISpendExceeded: Story = {
},
play: async ({ canvasElement, step }) => {
await step("shows the exceeded marker at the limit", async () => {
const menu = await openDropdown(canvasElement);
await openDropdown(canvasElement);
await waitFor(() => {
expect(document.body).toHaveTextContent("$1,500 / $1,200 USD");
expect(menu.getByText(spendPeriodLabel)).toBeVisible();
expect(document.body).toHaveTextContent(spendPeriodLabel);
});
expect(
screen.getByRole("progressbar", { name: "AI spend usage" }),
Expand All @@ -163,10 +163,10 @@ export const AISpendUnlimited: Story = {
},
play: async ({ canvasElement, step }) => {
await step("shows unlimited spend without a bar", async () => {
const menu = await openDropdown(canvasElement);
await openDropdown(canvasElement);
await waitFor(() => {
expect(document.body).toHaveTextContent("$819 / Unlimited USD");
expect(menu.getByText(spendPeriodLabel)).toBeVisible();
expect(document.body).toHaveTextContent(spendPeriodLabel);
});
expect(
screen.queryByRole("progressbar", { name: "AI spend usage" }),
Expand Down Expand Up @@ -274,7 +274,7 @@ export const AISpendHiddenOnInvalidData: Story = {
play: async ({ canvasElement, step }) => {
await step("hides AI spend on invalid data", async () => {
await openDropdown(canvasElement);
expect(screen.queryByText(spendPeriodLabel)).not.toBeInTheDocument();
expect(document.body).not.toHaveTextContent(spendPeriodLabel);
});
},
};
Expand All @@ -295,7 +295,7 @@ export const AISpendHiddenOnNegativeLimit: Story = {
play: async ({ canvasElement, step }) => {
await step("hides AI spend on a negative limit", async () => {
await openDropdown(canvasElement);
expect(screen.queryByText(spendPeriodLabel)).not.toBeInTheDocument();
expect(document.body).not.toHaveTextContent(spendPeriodLabel);
});
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ export const UserDropdownAISpend: FC<UserDropdownAISpendProps> = ({
/>
)}
<div className="mt-1 text-xs text-content-secondary">
Estimated AI spend: {formatSpendPeriodLabel(periodStart, periodEnd)}
Approximate AI spend{" "}
<span className="whitespace-nowrap">
{formatSpendPeriodLabel(periodStart, periodEnd)}
</span>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const meta: Meta<typeof GroupMemberBudgetCells> = {
<Table aria-label="Member budget">
<TableHeader>
<TableRow>
<TableHead>AI budget</TableHead>
<TableHead>AI spend</TableHead>
<TableHead>Budget group</TableHead>
</TableRow>
</TableHeader>
Expand Down
2 changes: 1 addition & 1 deletion site/src/pages/GroupsPage/GroupMemberBudgetCells.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const OTHER_ORG_MESSAGE =
"This user's AI budget is managed by a group in another organization and isn't visible here.";

/**
* The AI budget and Budget group cells for a group member. Spend is scoped to
* The AI spend and Budget group cells for a group member. Spend is scoped to
* the viewed group; the limit comes from the member's effective group.
*/
export const GroupMemberBudgetCells: FC<{
Expand Down
4 changes: 2 additions & 2 deletions site/src/pages/GroupsPage/GroupMembersPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ const GroupMembersPage: FC = () => {
}),
);
const aiBudgetNote = [
"Estimated monthly AI spend for this user.",
"Approximate monthly AI spend for this user.",
// Spend resets at period_end, rendered in the viewer's local time.
aiSpend &&
`Resets ${dayjs(aiSpend.period_end).format("MMM D, YYYY h:mm A")}.`,
Expand Down Expand Up @@ -141,7 +141,7 @@ const GroupMembersPage: FC = () => {
<>
<TableHead>
<div className="flex items-center gap-1">
AI budget
AI spend
{membersSpendQuery.isError ? (
<StatusIconTooltip
kind="warning"
Expand Down
12 changes: 6 additions & 6 deletions site/src/pages/GroupsPage/GroupPage.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ export const WithMemberAIBudget: Story = {
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await expect(await canvas.findByText("AI budget")).toBeInTheDocument();
await expect(await canvas.findByText("AI spend")).toBeInTheDocument();
await expect(await canvas.findByText("Budget group")).toBeInTheDocument();
await expect(
await canvas.findByText("AI budget period: June 1 - July 1, 2026"),
Expand All @@ -358,13 +358,13 @@ export const WithMemberAIBudget: Story = {

const body = within(document.body);
await userEvent.click(
within(canvas.getByText("AI budget")).getByRole("button", {
within(canvas.getByText("AI spend")).getByRole("button", {
name: "More info",
}),
);
await expect(
await body.findByText(
/^Estimated monthly AI spend for this user\. Resets .*The group's default limit is \$7,000 per member\.$/,
/^Approximate monthly AI spend for this user\. Resets .*The group's default limit is \$7,000 per member\.$/,
),
).toBeInTheDocument();
await userEvent.click(
Expand All @@ -391,7 +391,7 @@ export const WithoutMemberAIBudgetColumn: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await canvas.findByRole("table", { name: "Group members" });
expect(canvas.queryByText("AI budget")).not.toBeInTheDocument();
expect(canvas.queryByText("AI spend")).not.toBeInTheDocument();
expect(canvas.queryByText("Budget group")).not.toBeInTheDocument();
expect(canvas.queryByText(/AI budget period/)).not.toBeInTheDocument();
},
Expand Down Expand Up @@ -428,13 +428,13 @@ export const AIBudgetActionDisabledForOtherGroup: Story = {

// Without a group default budget, the header note ends at the reset date.
await userEvent.click(
within(canvas.getByText("AI budget")).getByRole("button", {
within(canvas.getByText("AI spend")).getByRole("button", {
name: "More info",
}),
);
await expect(
await body.findByText(
/^Estimated monthly AI spend for this user\. Resets .*\.$/,
/^Approximate monthly AI spend for this user\. Resets .*\.$/,
),
).toBeInTheDocument();
await userEvent.keyboard("{Escape}");
Expand Down
6 changes: 3 additions & 3 deletions site/src/pages/GroupsPage/GroupsPageView.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export const WithAIBudgetsLoading: Story = {
},
};

// Spend still loading: every AI budget cell falls back to an em dash.
// Spend still loading: every AI spend cell falls back to an em dash.
export const WithAIBudgetsSpendLoading: Story = {
args: {
groups: [aiGroup("ai-loading", "Spend loading")],
Expand Down Expand Up @@ -223,7 +223,7 @@ export const WithAIBudgetsSpendUnavailable: Story = {
},
};

// AI Bridge hidden: no AI budget column.
// AI Bridge hidden: no AI spend column.
export const WithoutAIBudgetColumn: Story = {
args: {
groups: [aiGroup("ai-hidden", "No AI column")],
Expand All @@ -233,7 +233,7 @@ export const WithoutAIBudgetColumn: Story = {
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
expect(canvas.queryByText("AI budget")).not.toBeInTheDocument();
expect(canvas.queryByText("AI spend")).not.toBeInTheDocument();
},
};

Expand Down
6 changes: 3 additions & 3 deletions site/src/pages/GroupsPage/GroupsPageView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export const GroupsPageView: FC<GroupsPageViewProps> = ({
{showAIBudget && (
<TableHead className="w-2/5">
<div className="flex items-center gap-1">
AI budget
AI spend
{spendError ? (
<StatusIconTooltip
kind="warning"
Expand All @@ -102,8 +102,8 @@ export const GroupsPageView: FC<GroupsPageViewProps> = ({
<StatusIconTooltip
message={
<>
Estimated AI spend compared to the group's AI budget for
the active period. <SpendEstimateDocsLink />
Approximate AI spend compared to the group's AI budget
for the active period. <SpendEstimateDocsLink />
</>
}
/>
Expand Down
Loading