ComputeSizeSelector.tsx108 lines · main
1import { UseFormReturn } from 'react-hook-form'
2import { CloudProvider } from 'shared-data'
3import {
4 FormField,
5 Select,
6 SelectContent,
7 SelectGroup,
8 SelectItem,
9 SelectTrigger,
10 SelectValue,
11} from 'ui'
12import { ComputeBadge } from 'ui-patterns'
13import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
14
15import { sizes } from './ProjectCreation.constants'
16import { CreateProjectForm } from './ProjectCreation.schema'
17import { InlineLink } from '@/components/ui/InlineLink'
18import Panel from '@/components/ui/Panel'
19import { instanceSizeSpecs } from '@/data/projects/new-project.constants'
20import { getCloudProviderArchitecture } from '@/lib/cloudprovider-utils'
21import { DOCS_URL } from '@/lib/constants'
22
23interface ComputeSizeSelectorProps {
24 form: UseFormReturn<CreateProjectForm>
25}
26
27export const ComputeSizeSelector = ({ form }: ComputeSizeSelectorProps) => {
28 return (
29 <Panel.Content>
30 <FormField
31 control={form.control}
32 name="instanceSize"
33 render={({ field }) => (
34 <FormItemLayout
35 layout="horizontal"
36 label="Compute size"
37 description={
38 <>
39 <p>
40 The size for your dedicated database. You can change this later. Learn more about{' '}
41 <InlineLink href={`${DOCS_URL}/guides/platform/compute-add-ons`}>
42 compute add-ons
43 </InlineLink>{' '}
44 and{' '}
45 <InlineLink href={`${DOCS_URL}/guides/platform/manage-your-usage/compute`}>
46 compute billing
47 </InlineLink>
48 .
49 </p>
50 </>
51 }
52 >
53 <Select value={field.value} onValueChange={(value) => field.onChange(value)}>
54 <SelectTrigger className="[&>span>div>div>[data-field=instance-details]]:hidden">
55 <SelectValue placeholder="Select a compute size" />
56 </SelectTrigger>
57 <SelectContent>
58 <SelectGroup>
59 {sizes
60 .filter((option) =>
61 instanceSizeSpecs[option].cloud_providers.includes(
62 form.getValues('cloudProvider') as CloudProvider
63 )
64 )
65 .map((option) => {
66 return (
67 <SelectItem key={option} value={option}>
68 <div className="flex flex-row gap-4 items-center">
69 <div className="w-14 flex items-center">
70 <ComputeBadge infraComputeSize={option} />
71 </div>
72
73 <div className="text-sm">
74 <span className="text-foreground">
75 {instanceSizeSpecs[option].ram} RAM /{' '}
76 {instanceSizeSpecs[option].cpu}{' '}
77 {getCloudProviderArchitecture(
78 form.getValues('cloudProvider') as CloudProvider
79 )}{' '}
80 CPU
81 </span>
82 <p
83 translate="no"
84 className="text-xs text-foreground-light"
85 data-field="instance-details"
86 >
87 ${instanceSizeSpecs[option].priceHourly}/hour (~$
88 {instanceSizeSpecs[option].priceMonthly}/month)
89 </p>
90 </div>
91 </div>
92 </SelectItem>
93 )
94 })}
95 <SelectItem key={'disabled'} value={'disabled'} disabled>
96 <div className="flex items-center justify-center w-full">
97 <span>Larger instance sizes available after creation</span>
98 </div>
99 </SelectItem>
100 </SelectGroup>
101 </SelectContent>
102 </Select>
103 </FormItemLayout>
104 )}
105 />
106 </Panel.Content>
107 )
108}