mirror of
https://github.com/coder/coder.git
synced 2026-09-22 05:05:20 +08:00
feat(site/src/pages/AISettingsPage/SpendPage): announce cost controls move to AI Governance (#27543)
Adds an informational banner to the AI settings **Spend** tab announcing that cost controls features move to AI Governance in v2.37, with a link to the AI Gateway cost controls docs. Banner copy: > Cost controls features will move to AI Governance in v2.37. [Read more here](https://coder.com/docs/ai-coder/ai-gateway/cost-controls) The link uses the existing `docs()` helper from `#/utils/docs`, so it resolves the deployment's configured `docs-url` meta tag and otherwise falls back to a version-pinned `coder.com/docs/@<version>` URL. This matches how sibling AI settings pages link out (for example `GatewayKeysPageView` and `ProvidersPageView`). It points at `/ai-coder/ai-gateway/cost-controls`, the AI Gateway Cost Controls page added in #27570. That page is present on `main` and the URL resolves, so the banner links to live documentation. The banner renders on the main Spend tab. It is intentionally not shown in the per-user spend drill-in sub-view, which returns early from a separate component. ## Validation - Extended the existing `SpendWithLimitsAndUsers` story to assert the banner copy and the resolved docs `href`. Both assertions were verified to fail when the banner is removed and when the link points somewhere else. - Storybook story tests for `SpendPageView.stories.tsx` pass (12 tests), plus `tsc -p .`, `biome check`, and `lint:compiler` clean. - `make pre-commit` passed through the git hooks. > Mux opened this PR on Mike's behalf.
This commit is contained in:
@@ -300,6 +300,17 @@ export const SpendWithLimitsAndUsers: Story = {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
await canvas.findByText("Spend limits and usage");
|
||||
await expect(
|
||||
canvas.getByText(
|
||||
/Cost controls features will move to AI Governance in v2\.37\./,
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
await expect(
|
||||
canvas.getByRole("link", { name: /Read more here/ }),
|
||||
).toHaveAttribute(
|
||||
"href",
|
||||
expect.stringContaining("/ai-coder/ai-gateway/cost-controls"),
|
||||
);
|
||||
await expect(
|
||||
canvas.getByRole("switch", { name: "Spend limit" }),
|
||||
).toBeInTheDocument();
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import type { FC } from "react";
|
||||
import { getErrorMessage } from "#/api/errors";
|
||||
import type * as TypesGen from "#/api/typesGenerated";
|
||||
import { Alert, AlertDescription } from "#/components/Alert/Alert";
|
||||
import { ErrorAlert } from "#/components/Alert/ErrorAlert";
|
||||
import { Button } from "#/components/Button/Button";
|
||||
import type { DateRangeValue } from "#/components/DateRangePicker/DateRangePicker";
|
||||
import { Link } from "#/components/Link/Link";
|
||||
import type { PaginationResult } from "#/components/PaginationWidget/PaginationContainer";
|
||||
import {
|
||||
SettingsHeader,
|
||||
@@ -22,6 +24,7 @@ import {
|
||||
useTemporarySavedState,
|
||||
} from "#/components/TemporarySavedState/TemporarySavedState";
|
||||
import { dollarsToMicros, microsToDollars } from "#/utils/currency";
|
||||
import { docs } from "#/utils/docs";
|
||||
import {
|
||||
DefaultLimitController,
|
||||
type DefaultLimitFormValues,
|
||||
@@ -232,6 +235,19 @@ export const SpendPageView: FC<SpendPageViewProps> = ({
|
||||
>
|
||||
{(userCtrl) => (
|
||||
<div className="flex max-w-[1100px] flex-col gap-8">
|
||||
<Alert severity="info">
|
||||
<AlertDescription>
|
||||
Cost controls features will move to AI Governance in v2.37.{" "}
|
||||
<Link
|
||||
href={docs("/ai-coder/ai-gateway/cost-controls")}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Read more here
|
||||
</Link>
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
|
||||
<SettingsHeader>
|
||||
<SettingsHeaderTitle>
|
||||
Spend limits and usage
|
||||
|
||||
Reference in New Issue
Block a user