Skip to content

Commit

Permalink
Ability to disable organization runs + more obvious if you're over th…
Browse files Browse the repository at this point in the history
…e free limit (#848)

* Fix for typo in error when a Job invoke fails

* Can disable runs for an Organization

* Don’t perform runs if runsEnabled === false for an Org

* Exceeded runs messages made into errors, they were very subtle

* Return the runsEnabled property for each org

* More obvious message if you’re over the free run limit

* Added a red border to the free usage panel if you’re over your run limit

* Added missing property to Storybook for the FreePlanUsage component
  • Loading branch information
matt-aitken authored Jan 17, 2024
1 parent a93b554 commit f209a3b
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 19 deletions.
9 changes: 8 additions & 1 deletion apps/webapp/app/components/billing/FreePlanUsage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,15 @@ export function FreePlanUsage({ to, percentage }: { to: string; percentage: numb
["#22C55E", "#22C55E", "#F59E0B", "#F43F5E", "#F43F5E"]
);

const hasHitLimit = cappedPercentage >= 1;

return (
<div className="rounded border border-slate-900 bg-[#101722] p-2.5">
<div
className={cn(
"rounded border border-slate-900 bg-[#101722] p-2.5",
hasHitLimit && "border-rose-800/60"
)}
>
<div className="flex items-center justify-between gap-2">
<div className="flex items-center gap-1">
<ArrowUpCircleIcon className="h-5 w-5 text-dimmed" />
Expand Down
35 changes: 21 additions & 14 deletions apps/webapp/app/components/billing/UpgradePrompt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { formatNumberCompact } from "~/utils/numberFormatter";
import { plansPath } from "~/utils/pathBuilder";
import { LinkButton } from "../primitives/Buttons";
import { Paragraph } from "../primitives/Paragraph";
import { Callout } from "../primitives/Callout";

type UpgradePromptProps = {
organization: MatchedOrganization;
Expand All @@ -18,19 +19,25 @@ export function UpgradePrompt({ organization }: UpgradePromptProps) {
}

return (
<div className="flex h-full w-full items-center gap-4 bg-gradient-to-r from-transparent to-indigo-900/50 pr-1.5">
<Paragraph variant="extra-small" className="text-rose-500">
You have exceeded the monthly {formatNumberCompact(currentPlan.usage.runCountCap)} runs
limit
</Paragraph>
<LinkButton
variant={"primary/small"}
LeadingIcon={ArrowUpCircleIcon}
leadingIconClassName="px-0"
to={plansPath(organization)}
>
Upgrade
</LinkButton>
</div>
<Callout variant="error" className="flex h-full items-center rounded-none px-1 py-0">
<div className="flex items-center justify-between gap-3">
<Paragraph variant="extra-small" className="text-white">
{organization.runsEnabled
? `You have exceeded the monthly ${formatNumberCompact(
currentPlan.usage.runCountCap
)} runs
limit`
: `No runs are executing because you have exceeded the free limit`}
</Paragraph>
<LinkButton
variant={"primary/small"}
LeadingIcon={ArrowUpCircleIcon}
leadingIconClassName="px-0"
to={plansPath(organization)}
>
Upgrade
</LinkButton>
</div>
</Callout>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const mockOrganization: MatchedOrganization = {
],
hasUnconfiguredIntegrations: false,
memberCount: 1,
runsEnabled: true,
};

export const ProgressBar: Story = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export class OrganizationsPresenter {
})),
hasUnconfiguredIntegrations: org._count.integrations > 0,
memberCount: org._count.members,
runsEnabled: org.runsEnabled,
};
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export default function Page() {
<div className="flex flex-col gap-5 rounded border border-border p-6">
{hitsRunLimit && (
<Callout
variant={"pricing"}
variant={"error"}
cta={
<LinkButton
variant="primary/small"
Expand All @@ -108,7 +108,7 @@ export default function Page() {
</LinkButton>
}
>
<Paragraph variant="small">
<Paragraph variant="small" className="text-white">
You have exceeded the monthly{" "}
{formatNumberCompact(currentPlan?.subscription?.limits.runs ?? 0)} runs limit.
Upgrade to a paid plan before{" "}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default function Page() {
</Callout>
)}
{hitRunLimit && (
<Callout variant={"pricing"}>
<Callout variant={"error"}>
{`You have exceeded the monthly
${formatNumberCompact(currentPlan!.subscription!.limits.runs!)} runs limit. Upgrade so you
can continue to perform runs.`}
Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/app/routes/api.v1.jobs.$jobSlug.invoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export async function action({ request, params }: ActionFunctionArgs) {
);

if (!run) {
return json({ error: "Job count not be invoked" }, { status: 500 });
return json({ error: "Job could not be invoked" }, { status: 500 });
}

return json({ id: run.id });
Expand Down
6 changes: 6 additions & 0 deletions apps/webapp/app/services/runs/createRun.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { $transaction, PrismaClientOrTransaction } from "~/db.server";
import { prisma } from "~/db.server";
import { workerQueue } from "~/services/worker.server";
import type { AuthenticatedEnvironment } from "../apiAuth.server";
import { logger } from "../logger.server";

export class CreateRunService {
#prismaClient: PrismaClientOrTransaction;
Expand All @@ -25,6 +26,11 @@ export class CreateRunService {
},
options: { callbackUrl?: string } = {}
) {
if (!environment.organization.runsEnabled) {
logger.debug("Runs are disabled for this organization", environment);
return;
}

const endpoint = await this.#prismaClient.endpoint.findUniqueOrThrow({
where: {
id: version.endpointId,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Organization" ADD COLUMN "runsEnabled" BOOLEAN NOT NULL DEFAULT true;
2 changes: 2 additions & 0 deletions packages/database/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ model Organization {
companySize String?
runsEnabled Boolean @default(true)
environments RuntimeEnvironment[]
connections IntegrationConnection[]
endpoints Endpoint[]
Expand Down

0 comments on commit f209a3b

Please sign in to comment.