ComputeSizeSelector.tsx 4.2 KB

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