@@ -21,7 +21,10 @@ import {
2121 FormLabel,
2222 FormMessage,
2323} from "@/components/ui/form";
24- import { Input } from "@/components/ui/input";
24+ import {
25+ createConverter,
26+ NumberInputWithSteps,
27+ } from "@/components/ui/number-input";
2528import {
2629 Tooltip,
2730 TooltipContent,
@@ -30,6 +33,23 @@ import {
3033} from "@/components/ui/tooltip";
3134import { api } from "@/utils/api";
3235
36+ const CPU_STEP = 0.25;
37+ const MEMORY_STEP_MB = 256;
38+
39+ const formatNumber = (value: number, decimals = 2): string =>
40+ Number.isInteger(value) ? String(value) : value.toFixed(decimals);
41+
42+ const cpuConverter = createConverter(1_000_000_000, (cpu) =>
43+ cpu <= 0 ? "" : `${formatNumber(cpu)} CPU`,
44+ );
45+
46+ const memoryConverter = createConverter(1024 * 1024, (mb) => {
47+ if (mb <= 0) return "";
48+ return mb >= 1024
49+ ? `${formatNumber(mb / 1024)} GB`
50+ : `${formatNumber(mb)} MB`;
51+ });
52+
3353const addResourcesSchema = z.object({
3454 memoryReservation: z.string().optional(),
3555 cpuLimit: z.string().optional(),
@@ -51,6 +71,7 @@ interface Props {
5171}
5272
5373type AddResources = z.infer<typeof addResourcesSchema>;
74+
5475export const ShowResources = ({ id, type }: Props) => {
5576 const queryMap = {
5677 postgres: () =>
@@ -163,16 +184,20 @@ export const ShowResources = ({ id, type }: Props) => {
163184 <TooltipContent>
164185 <p>
165186 Memory hard limit in bytes. Example: 1GB =
166- 1073741824 bytes
187+ 1073741824 bytes. Use +/- buttons to adjust by
188+ 256 MB.
167189 </p>
168190 </TooltipContent>
169191 </Tooltip>
170192 </TooltipProvider>
171193 </div>
172194 <FormControl>
173- <Input
195+ <NumberInputWithSteps
196+ value={field.value}
197+ onChange={field.onChange}
174198 placeholder="1073741824 (1GB in bytes)"
175- {...field}
199+ step={MEMORY_STEP_MB}
200+ converter={memoryConverter}
176201 />
177202 </FormControl>
178203 <FormMessage />
@@ -198,16 +223,20 @@ export const ShowResources = ({ id, type }: Props) => {
198223 <TooltipContent>
199224 <p>
200225 Memory soft limit in bytes. Example: 256MB =
201- 268435456 bytes
226+ 268435456 bytes. Use +/- buttons to adjust by 256
227+ MB.
202228 </p>
203229 </TooltipContent>
204230 </Tooltip>
205231 </TooltipProvider>
206232 </div>
207233 <FormControl>
208- <Input
234+ <NumberInputWithSteps
235+ value={field.value}
236+ onChange={field.onChange}
209237 placeholder="268435456 (256MB in bytes)"
210- {...field}
238+ step={MEMORY_STEP_MB}
239+ converter={memoryConverter}
211240 />
212241 </FormControl>
213242 <FormMessage />
@@ -234,17 +263,20 @@ export const ShowResources = ({ id, type }: Props) => {
234263 <TooltipContent>
235264 <p>
236265 CPU quota in units of 10^-9 CPUs. Example: 2
237- CPUs = 2000000000
266+ CPUs = 2000000000. Use +/- buttons to adjust by
267+ 0.25 CPU.
238268 </p>
239269 </TooltipContent>
240270 </Tooltip>
241271 </TooltipProvider>
242272 </div>
243273 <FormControl>
244- <Input
274+ <NumberInputWithSteps
275+ value={field.value}
276+ onChange={field.onChange}
245277 placeholder="2000000000 (2 CPUs)"
246- {...field }
247- value={field.value?.toString() || "" }
278+ step={CPU_STEP }
279+ converter={cpuConverter }
248280 />
249281 </FormControl>
250282 <FormMessage />
@@ -271,14 +303,21 @@ export const ShowResources = ({ id, type }: Props) => {
271303 <TooltipContent>
272304 <p>
273305 CPU shares (relative weight). Example: 1 CPU =
274- 1000000000
306+ 1000000000. Use +/- buttons to adjust by 0.25
307+ CPU.
275308 </p>
276309 </TooltipContent>
277310 </Tooltip>
278311 </TooltipProvider>
279312 </div>
280313 <FormControl>
281- <Input placeholder="1000000000 (1 CPU)" {...field} />
314+ <NumberInputWithSteps
315+ value={field.value}
316+ onChange={field.onChange}
317+ placeholder="1000000000 (1 CPU)"
318+ step={CPU_STEP}
319+ converter={cpuConverter}
320+ />
282321 </FormControl>
283322 <FormMessage />
284323 </FormItem>
0 commit comments