| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- import { useParams } from 'common'
- import { useState } from 'react'
- import { AWS_REGIONS, AWS_REGIONS_KEYS } from 'shared-data'
- import { toast } from 'sonner'
- import {
- Button,
- InfoIcon,
- Select,
- SelectContent,
- SelectItem,
- SelectTrigger,
- SelectValue,
- SheetFooter,
- SheetSection,
- } from 'ui'
- import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
- import { ReadReplicaEligibilityWarnings } from './ReadReplicaEligibilityWarnings'
- import { ReadReplicaPricingDialog } from './ReadReplicaPricingDialog'
- import { useCheckEligibilityDeployReplica } from './useCheckEligibilityDeployReplica'
- import { useGetReplicaCost } from './useGetReplicaCost'
- import { AVAILABLE_REPLICA_REGIONS } from '@/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceConfiguration.constants'
- import { Region, useReadReplicaSetUpMutation } from '@/data/read-replicas/replica-setup-mutation'
- import { useReadReplicasQuery } from '@/data/read-replicas/replicas-query'
- import { AWS_REGIONS_DEFAULT, BASE_PATH } from '@/lib/constants'
- interface ReadReplicaFormProps {
- onSuccess: () => void
- onClose: () => void
- }
- export const ReadReplicaForm = ({ onSuccess, onClose }: ReadReplicaFormProps) => {
- const { ref: projectRef } = useParams()
- const { data } = useReadReplicasQuery({ projectRef })
- const [defaultRegion] = Object.entries(AWS_REGIONS).find(
- ([_, name]) => name === AWS_REGIONS_DEFAULT
- ) ?? ['ap-southeast-1']
- const { totalCost } = useGetReplicaCost()
- const { can: canDeployReplica } = useCheckEligibilityDeployReplica()
- const [selectedRegion, setSelectedRegion] = useState<string>(defaultRegion)
- const { mutate: setUpReplica, isPending: isSettingUp } = useReadReplicaSetUpMutation({
- onSuccess: () => {
- const region = AVAILABLE_REPLICA_REGIONS.find((r) => r.key === selectedRegion)?.name
- toast.success(`Spinning up new replica in ${region ?? ' Unknown'}...`)
- onSuccess?.()
- onClose()
- },
- })
- const availableRegions =
- process.env.NEXT_PUBLIC_ENVIRONMENT === 'staging'
- ? AVAILABLE_REPLICA_REGIONS.filter((x) =>
- ['SOUTHEAST_ASIA', 'CENTRAL_EU', 'EAST_US'].includes(x.key)
- )
- : AVAILABLE_REPLICA_REGIONS
- const onSubmit = async () => {
- const regionKey = AWS_REGIONS[selectedRegion as AWS_REGIONS_KEYS].code
- if (!projectRef) return console.error('Project is required')
- if (!regionKey) return toast.error('Unable to deploy replica: Unsupported region selected')
- const primary = data?.find((db) => db.identifier === projectRef)
- setUpReplica({ projectRef, region: regionKey as Region, size: primary?.size ?? 't4g.small' })
- }
- return (
- <>
- {!canDeployReplica && (
- <SheetSection>
- <ReadReplicaEligibilityWarnings />
- </SheetSection>
- )}
- <SheetSection className="grow overflow-auto px-0 py-0">
- <FormItemLayout
- isReactForm={false}
- layout="horizontal"
- className="p-5 [&>div]:gap-y-1 [&>div>span]:text-foreground-lighter"
- label="Region"
- labelOptional="Select a region to deploy your replica in"
- >
- <Select
- value={selectedRegion}
- onValueChange={setSelectedRegion}
- disabled={!canDeployReplica}
- >
- <SelectTrigger>
- <SelectValue placeholder="Select a region" />
- </SelectTrigger>
- <SelectContent>
- {availableRegions.map((region) => (
- <SelectItem key={region.key} value={region.key}>
- <div className="flex gap-x-3 items-center">
- <img
- alt="region icon"
- className="w-5 rounded-xs"
- src={`${BASE_PATH}/img/regions/${region.region}.svg`}
- />
- <p className="flex items-center gap-x-2">
- <span>{region.name}</span>
- <span className="text-xs text-foreground-lighter font-mono">
- {region.region}
- </span>
- </p>
- </div>
- </SelectItem>
- ))}
- </SelectContent>
- </Select>
- </FormItemLayout>
- </SheetSection>
- <SheetFooter className="justify-between!">
- <div className="flex items-center gap-x-4">
- <InfoIcon className="h-5 w-5" />
- <p className="text-sm">
- New replica will cost an additional <span translate="no">{totalCost}/month</span>
- </p>
- <ReadReplicaPricingDialog />
- </div>
- <div className="flex items-center gap-x-2">
- <Button disabled={isSettingUp} type="default" onClick={onClose}>
- Cancel
- </Button>
- <Button disabled={!canDeployReplica} loading={isSettingUp} onClick={onSubmit}>
- Deploy replica
- </Button>
- </div>
- </SheetFooter>
- </>
- )
- }
|