import { UseFormReturn } from 'react-hook-form' import { useFlag, useParams } from 'common' import AlertError from 'components/ui/AlertError' import Panel from 'components/ui/Panel' import { useDefaultRegionQuery } from 'data/misc/get-default-region-query' import { useOrganizationAvailableRegionsQuery } from 'data/organizations/organization-available-regions-query' import type { DesiredInstanceSize } from 'data/projects/new-project.constants' import { BASE_PATH, PROVIDERS } from 'lib/constants' import type { CloudProvider } from 'shared-data' import { Badge, FormField_Shadcn_, SelectContent_Shadcn_, SelectGroup_Shadcn_, SelectItem_Shadcn_, SelectLabel_Shadcn_, SelectSeparator_Shadcn_, SelectTrigger_Shadcn_, SelectValue_Shadcn_, Select_Shadcn_, Tooltip, TooltipContent, TooltipTrigger, cn, } from 'ui' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import { CreateProjectForm } from './ProjectCreation.schema' import { getAvailableRegions } from './ProjectCreation.utils' interface RegionSelectorProps { form: UseFormReturn instanceSize?: DesiredInstanceSize layout?: 'vertical' | 'horizontal' } // [Joshen] Let's use a library to maintain the flag SVGs in the future // I tried using https://flagpack.xyz/docs/development/react/ but couldn't get it to render // ^ can try again next time // Map backend region names to user-friendly display names const getDisplayNameForSmartRegion = (name: string): string => { if (name === 'APAC') { return 'Asia-Pacific' } return name } export const RegionSelector = ({ form, instanceSize, layout = 'horizontal', }: RegionSelectorProps) => { const { slug } = useParams() const cloudProvider = form.getValues('cloudProvider') as CloudProvider const smartRegionEnabled = useFlag('enableSmartRegion') const { isPending: isLoadingDefaultRegion } = useDefaultRegionQuery( { cloudProvider }, { enabled: !smartRegionEnabled } ) const { data: availableRegionsData, isPending: isLoadingAvailableRegions, isError: isErrorAvailableRegions, error: errorAvailableRegions, } = useOrganizationAvailableRegionsQuery( { slug, cloudProvider, desiredInstanceSize: instanceSize }, { enabled: smartRegionEnabled, staleTime: 1000 * 60 * 5 } // 5 minutes ) const smartRegions = availableRegionsData?.all.smartGroup ?? [] const allRegions = availableRegionsData?.all.specific ?? [] const recommendedSmartRegions = new Set( [availableRegionsData?.recommendations.smartGroup.code].filter(Boolean) ) const recommendedSpecificRegions = new Set( availableRegionsData?.recommendations.specific.map((region) => region.code) ) const availableRegions = getAvailableRegions(PROVIDERS[cloudProvider].id) const regionsArray = Object.entries(availableRegions).map(([_key, value]) => { return { code: value.code, name: value.displayName, provider: cloudProvider, status: undefined, } }) const regionOptions = smartRegionEnabled ? allRegions : regionsArray const isLoading = smartRegionEnabled ? isLoadingAvailableRegions : isLoadingDefaultRegion const showNonProdFields = process.env.NEXT_PUBLIC_ENVIRONMENT === 'local' || process.env.NEXT_PUBLIC_ENVIRONMENT === 'staging' const allSelectableRegions = [...smartRegions, ...regionOptions] if (isErrorAvailableRegions) { return } return ( { const selectedRegion = allSelectableRegions.find((region) => { return !!region.name && region.name === field.value }) return (

Select the region closest to your users for the best performance.

{showNonProdFields && (

Only these regions are supported for local/staging projects:

  • East US (North Virginia)
  • Central EU (Frankfurt)
  • Southeast Asia (Singapore)
)} } > {field.value !== undefined && (
{selectedRegion?.code && ( region icon )} {selectedRegion?.name ? getDisplayNameForSmartRegion(selectedRegion.name) : field.value}
)}
{smartRegionEnabled && ( <> General regions {smartRegions.map((value) => { return (
region icon {getDisplayNameForSmartRegion(value.name)}
{recommendedSmartRegions.has(value.code) && ( Recommended )}
) })}
)} Specific regions {regionOptions.map((value) => { return ( :nth-child(2)]:w-full', value.status !== undefined && '!pointer-events-auto' )} disabled={value.status !== undefined} >
region icon
{value.name} {value.code}
{recommendedSpecificRegions.has(value.code) && ( Recommended )} {value.status !== undefined && value.status === 'capacity' && ( Unavailable Temporarily unavailable due to this region being at capacity. )}
) })}
) }} />
) }