Skip to content

Usage billing alerts #2323

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jul 30, 2025
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
4 changes: 2 additions & 2 deletions apps/webapp/app/components/billing/UpgradePrompt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ export function UpgradePrompt() {
<Icon icon={ExclamationCircleIcon} className="h-5 w-5 text-error" />
<Paragraph variant="small" className="text-error">
You have exceeded the monthly $
{(plan.v3Subscription?.plan?.limits.includedUsage ?? 500) / 100} free credits. No runs
will execute in Prod until{" "}
{(plan.v3Subscription?.plan?.limits.includedUsage ?? 500) / 100} free credits. Existing
runs will be queued and new runs won't be created until{" "}
<DateTime date={nextMonth} includeTime={false} timeZone="utc" />, or you upgrade.
</Paragraph>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
BellAlertIcon,
ChartBarIcon,
Cog8ToothIcon,
CreditCardIcon,
Expand All @@ -12,6 +13,7 @@ import {
organizationSettingsPath,
organizationTeamPath,
rootPath,
v3BillingAlertsPath,
v3BillingPath,
v3UsagePath,
} from "~/utils/pathBuilder";
Expand Down Expand Up @@ -67,27 +69,34 @@ export function OrganizationSettingsSideMenu({
<SideMenuHeader title="Organization" />
</div>
{isManagedCloud && (
<SideMenuItem
name="Usage"
icon={ChartBarIcon}
activeIconColor="text-indigo-500"
to={v3UsagePath(organization)}
data-action="usage"
/>
)}
{isManagedCloud && (
<SideMenuItem
name="Billing"
icon={CreditCardIcon}
activeIconColor="text-emerald-500"
to={v3BillingPath(organization)}
data-action="billing"
badge={
currentPlan?.v3Subscription?.isPaying ? (
<Badge variant="extra-small">{currentPlan?.v3Subscription?.plan?.title}</Badge>
) : undefined
}
/>
<>
<SideMenuItem
name="Usage"
icon={ChartBarIcon}
activeIconColor="text-indigo-500"
to={v3UsagePath(organization)}
data-action="usage"
/>
<SideMenuItem
name="Billing"
icon={CreditCardIcon}
activeIconColor="text-emerald-500"
to={v3BillingPath(organization)}
data-action="billing"
badge={
currentPlan?.v3Subscription?.isPaying ? (
<Badge variant="extra-small">{currentPlan?.v3Subscription?.plan?.title}</Badge>
) : undefined
}
/>
<SideMenuItem
name="Billing alerts"
icon={BellAlertIcon}
activeIconColor="text-rose-500"
to={v3BillingAlertsPath(organization)}
data-action="billing-alerts"
/>
</>
)}
<SideMenuItem
name="Team"
Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/app/components/primitives/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const containerBase =
"has-[:focus-visible]:outline-none has-[:focus-visible]:ring-1 has-[:focus-visible]:ring-charcoal-650 has-[:focus-visible]:ring-offset-0 has-[:focus]:border-ring has-[:focus]:outline-none has-[:focus]:ring-1 has-[:focus]:ring-ring has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50 ring-offset-background transition cursor-text";

const inputBase =
"h-full w-full text-text-bright bg-transparent file:border-0 file:bg-transparent file:text-base file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-0 disabled:cursor-not-allowed outline-none ring-0 border-none";
"h-full w-full text-text-bright bg-transparent file:border-0 file:bg-transparent file:text-base file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-0 disabled:cursor-not-allowed outline-none ring-0 border-none [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-inner-spin-button]:m-0 [&]:[-moz-appearance:textfield]";

const variants = {
large: {
Expand Down
15 changes: 15 additions & 0 deletions apps/webapp/app/presenters/v3/EnvironmentQueuePresenter.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export type Environment = {
queued: number;
concurrencyLimit: number;
burstFactor: number;
runsEnabled: boolean;
};

export class EnvironmentQueuePresenter extends BasePresenter {
Expand All @@ -23,11 +24,25 @@ export class EnvironmentQueuePresenter extends BasePresenter {
const running = (engineV1Executing ?? 0) + (engineV2Executing ?? 0);
const queued = (engineV1Queued ?? 0) + (engineV2Queued ?? 0);

const organization = await this._replica.organization.findFirst({
where: {
id: environment.organizationId,
},
select: {
runsEnabled: true,
},
});

if (!organization) {
throw new Error("Organization not found");
}

return {
running,
queued,
concurrencyLimit: environment.maximumConcurrencyLimit,
burstFactor: environment.concurrencyLimitBurstFactor.toNumber(),
runsEnabled: environment.type === "DEVELOPMENT" || organization.runsEnabled,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ export default function Page() {
>
View runs
</LinkButton>
<EnvironmentPauseResumeButton env={env} />
{environment.runsEnabled ? <EnvironmentPauseResumeButton env={env} /> : null}
</div>
}
valueClassName={env.paused ? "text-warning" : undefined}
Expand Down
Loading