Skip to content

Commit 34d789a

Browse files
committed
refactor(webapp): concurrency quota editor
1 parent 9eef605 commit 34d789a

2 files changed

Lines changed: 45 additions & 51 deletions

File tree

apps/webapp/app/components/admin/backOffice/ConcurrencyQuotaSection.server.ts

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,11 @@ import { logger } from "~/services/logger.server";
33
import { setExtraConcurrencyQuota } from "~/services/platform.v3.server";
44
import { CONCURRENCY_QUOTA_INTENT } from "./ConcurrencyQuotaSection";
55

6-
const RawSchema = z.object({
6+
const SetConcurrencyQuotaSchema = z.object({
77
intent: z.literal(CONCURRENCY_QUOTA_INTENT),
8-
// Checkbox arrives as "on" / "true" when checked, absent when not.
9-
usePlanDefault: z.string().optional(),
10-
// Empty string when "Use plan default" is checked (the input is disabled).
11-
extraConcurrencyQuota: z.string().optional(),
12-
});
13-
14-
const SetConcurrencyQuotaSchema = RawSchema.transform((raw, ctx) => {
15-
const usePlanDefault = !!raw.usePlanDefault;
16-
if (usePlanDefault) {
17-
return { extraConcurrencyQuota: null as number | null };
18-
}
19-
const trimmed = (raw.extraConcurrencyQuota ?? "").trim();
20-
if (trimmed.length === 0) {
21-
ctx.addIssue({
22-
code: z.ZodIssueCode.custom,
23-
message: "Enter a non-negative integer or check 'Use plan default'.",
24-
path: ["extraConcurrencyQuota"],
25-
});
26-
return z.NEVER;
27-
}
28-
const parsed = Number(trimmed);
29-
if (!Number.isInteger(parsed) || parsed < 0) {
30-
ctx.addIssue({
31-
code: z.ZodIssueCode.custom,
32-
message: "Quota must be a non-negative integer.",
33-
path: ["extraConcurrencyQuota"],
34-
});
35-
return z.NEVER;
36-
}
37-
return { extraConcurrencyQuota: parsed as number | null };
8+
// Capped at PostgreSQL INTEGER max for safety; cloud will reject anything
9+
// unreasonably high on its own (likely with quota_too_high).
10+
extraConcurrencyQuota: z.coerce.number().int().min(0).max(2_147_483_647),
3811
});
3912

4013
export type ConcurrencyQuotaActionResult =
@@ -102,7 +75,7 @@ function mapCodeToMessage(
10275
): string {
10376
switch (code) {
10477
case "invalid_body":
105-
return "Quota must be a non-negative integer (or check 'Use plan default').";
78+
return "Quota must be a non-negative integer.";
10679
case "quota_too_high":
10780
// Cloud's `error` string embeds the actual ceiling, prefer it verbatim.
10881
return fallback || "Cap is too high.";

apps/webapp/app/components/admin/backOffice/ConcurrencyQuotaSection.tsx

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Form } from "@remix-run/react";
22
import { useEffect, useState } from "react";
33
import { Button } from "~/components/primitives/Buttons";
4-
import { Checkbox } from "~/components/primitives/Checkbox";
54
import { FormError } from "~/components/primitives/FormError";
65
import { Header2 } from "~/components/primitives/Headers";
76
import { Input } from "~/components/primitives/Input";
@@ -36,7 +35,6 @@ export function ConcurrencyQuotaSection({
3635
errors && field in errors ? errors[field]?.[0] : undefined;
3736

3837
const [isEditing, setIsEditing] = useState(hasFieldErrors || !!formError);
39-
const [usePlanDefault, setUsePlanDefault] = useState(false);
4038
const [value, setValue] = useState(String(currentQuota));
4139

4240
useEffect(() => {
@@ -49,10 +47,24 @@ export function ConcurrencyQuotaSection({
4947

5048
const cancelEdit = () => {
5149
setValue(String(currentQuota));
52-
setUsePlanDefault(false);
5350
setIsEditing(false);
5451
};
5552

53+
const trimmedValue = value.trim();
54+
const parsed = Number(trimmedValue);
55+
const isValidPreview =
56+
trimmedValue.length > 0 &&
57+
Number.isInteger(parsed) &&
58+
parsed >= 0;
59+
const delta = isValidPreview ? parsed - currentQuota : 0;
60+
const deltaLabel =
61+
delta > 0
62+
? `+${delta.toLocaleString()}`
63+
: delta < 0
64+
? delta.toLocaleString()
65+
: "no change";
66+
const headroomAfter = isValidPreview ? parsed - purchased : 0;
67+
5668
return (
5769
<section className="flex flex-col gap-3 rounded-md border border-charcoal-700 bg-charcoal-800 p-4">
5870
<div className="flex items-center justify-between">
@@ -111,32 +123,41 @@ export function ConcurrencyQuotaSection({
111123
name="extraConcurrencyQuota"
112124
type="number"
113125
min={0}
114-
value={usePlanDefault ? "" : value}
126+
value={value}
115127
onChange={(e) => setValue(e.target.value)}
116-
disabled={usePlanDefault}
117-
required={!usePlanDefault}
128+
required
118129
/>
119130
<FormError>{fieldError("extraConcurrencyQuota")}</FormError>
120131
</div>
121132

122-
<div className="flex items-center gap-2">
123-
<Checkbox
124-
id="usePlanDefault"
125-
name="usePlanDefault"
126-
value="true"
127-
checked={usePlanDefault}
128-
onChange={(e) => setUsePlanDefault(e.target.checked)}
129-
/>
130-
<Label htmlFor="usePlanDefault">
131-
Use plan default (clears any per-org override)
132-
</Label>
133-
</div>
133+
{isValidPreview && (
134+
<div className="rounded-md border border-charcoal-700 bg-charcoal-900 px-3 py-2">
135+
<Paragraph variant="small">
136+
Cap: {currentQuota.toLocaleString()}{" "}
137+
{parsed.toLocaleString()} ({deltaLabel})
138+
</Paragraph>
139+
<Paragraph variant="small" className="text-text-dimmed">
140+
Already purchased: {purchased.toLocaleString()}
141+
</Paragraph>
142+
{headroomAfter >= 0 ? (
143+
<Paragraph variant="small" className="text-text-dimmed">
144+
After save: {headroomAfter.toLocaleString()} more buyable.
145+
</Paragraph>
146+
) : (
147+
<Paragraph variant="small" className="text-amber-500">
148+
Below already-purchased — org would be{" "}
149+
{(-headroomAfter).toLocaleString()} over the new cap. They'd
150+
keep what they have but couldn't buy more until you raise it.
151+
</Paragraph>
152+
)}
153+
</div>
154+
)}
134155

135156
<div className="flex items-center gap-2">
136157
<Button
137158
type="submit"
138159
variant="primary/medium"
139-
disabled={isSubmitting || (!usePlanDefault && !value.trim())}
160+
disabled={isSubmitting || !value.trim()}
140161
>
141162
Save
142163
</Button>

0 commit comments

Comments
 (0)