diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationPanel.tsx b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationPanel.tsx
index dcc00c7a296..e58c8df34bc 100644
--- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationPanel.tsx
+++ b/apps/studio/components/interfaces/Database/Replication/DestinationPanel/DestinationPanel.tsx
@@ -24,7 +24,7 @@ import { useIsETLPrivateAlpha } from '../useIsETLPrivateAlpha'
import { DestinationForm } from './DestinationForm'
import { DestinationType } from './DestinationPanel.types'
import { DestinationTypeSelection } from './DestinationTypeSelection'
-import { ReadReplicaForm } from './ReadReplicaForm'
+import { ReadReplicaForm } from '@/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm'
import { DiscardChangesConfirmationDialog } from '@/components/ui-patterns/Dialogs/DiscardChangesConfirmationDialog'
import { DocsButton } from '@/components/ui/DocsButton'
import { useReplicationDestinationsQuery } from '@/data/replication/destinations-query'
diff --git a/apps/studio/components/interfaces/Database/Replication/Destinations.tsx b/apps/studio/components/interfaces/Database/Replication/Destinations.tsx
index ea4482fff97..82ea3551774 100644
--- a/apps/studio/components/interfaces/Database/Replication/Destinations.tsx
+++ b/apps/studio/components/interfaces/Database/Replication/Destinations.tsx
@@ -30,7 +30,6 @@ import { DestinationType } from './DestinationPanel/DestinationPanel.types'
import { DestinationRow } from './DestinationRow'
import { DisablePipelinesDialog } from './DisablePipelinesDialog'
import { EnablePipelinesModal } from './EnablePipelinesCallout'
-import { ReadReplicaRow } from './ReadReplicas/ReadReplicaRow'
import { REPLICA_STATUS } from './Replication.constants'
import {
useIsETLBigQueryPrivateAlpha,
@@ -39,6 +38,7 @@ import {
useIsETLIcebergPrivateAlpha,
useIsETLSnowflakePrivateAlpha,
} from './useIsETLPrivateAlpha'
+import { ReadReplicaRow } from '@/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaRow'
import { AlertError } from '@/components/ui/AlertError'
import { DocsButton } from '@/components/ui/DocsButton'
import { DropdownMenuItemTooltip } from '@/components/ui/DropdownMenuItemTooltip'
diff --git a/apps/studio/components/interfaces/Database/Replication/Replication.constants.ts b/apps/studio/components/interfaces/Database/Replication/Replication.constants.ts
index ddefacbe243..2663b675fa3 100644
--- a/apps/studio/components/interfaces/Database/Replication/Replication.constants.ts
+++ b/apps/studio/components/interfaces/Database/Replication/Replication.constants.ts
@@ -1,7 +1,3 @@
-import { components } from 'api-types'
-
-import { PROJECT_STATUS } from '@/lib/constants'
-
export const STATUS_REFRESH_FREQUENCY_MS: number = 10000 // 10 seconds
export enum PipelineStatusName {
@@ -13,10 +9,5 @@ export enum PipelineStatusName {
UNKNOWN = 'unknown',
}
-export const REPLICA_STATUS: {
- [key: string]: components['schemas']['DatabaseStatusResponse']['status']
-} = {
- ...PROJECT_STATUS,
- INIT_READ_REPLICA: 'INIT_READ_REPLICA',
- INIT_READ_REPLICA_FAILED: 'INIT_READ_REPLICA_FAILED',
-}
+/** @deprecated Import from Settings/Infrastructure/ReadReplicas/ReadReplicas.constants */
+export { REPLICA_STATUS } from '@/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicas.constants'
diff --git a/apps/studio/components/interfaces/Database/Replication/ReplicationDiagram/Nodes.tsx b/apps/studio/components/interfaces/Database/Replication/ReplicationDiagram/Nodes.tsx
index 7e3f1e2e371..b4d1afe51a3 100644
--- a/apps/studio/components/interfaces/Database/Replication/ReplicationDiagram/Nodes.tsx
+++ b/apps/studio/components/interfaces/Database/Replication/ReplicationDiagram/Nodes.tsx
@@ -6,9 +6,9 @@ import { cn, Tooltip, TooltipContent, TooltipTrigger } from 'ui'
import { DestinationIcon } from '../DestinationIcon'
import { getStatusName } from '../Pipeline.utils'
-import { getStatusLabel } from '../ReadReplicas/ReadReplicas.utils'
import { STATUS_REFRESH_FREQUENCY_MS } from '../Replication.constants'
import { getReplicationDestinationType } from './Nodes.utils'
+import { getStatusLabel } from '@/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicas.utils'
import { useReadReplicasQuery } from '@/data/read-replicas/replicas-query'
import { formatDatabaseID } from '@/data/read-replicas/replicas.utils'
import { useReplicationDestinationsQuery } from '@/data/replication/destinations-query'
diff --git a/apps/studio/components/interfaces/Settings/Infrastructure/Infrastructure.utils.test.ts b/apps/studio/components/interfaces/Settings/Infrastructure/Infrastructure.utils.test.ts
index 21cea9fd315..805bda19318 100644
--- a/apps/studio/components/interfaces/Settings/Infrastructure/Infrastructure.utils.test.ts
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/Infrastructure.utils.test.ts
@@ -1,6 +1,10 @@
import { describe, expect, it } from 'vitest'
-import { getInfrastructurePath } from './Infrastructure.utils'
+import {
+ getAddReadReplicaPath,
+ getInfrastructurePath,
+ getReadReplicaPath,
+} from './Infrastructure.utils'
describe('getInfrastructurePath', () => {
it('builds the path for a project ref', () => {
@@ -13,3 +17,29 @@ describe('getInfrastructurePath', () => {
expect(getInfrastructurePath()).toBe('/project/_/settings/infrastructure')
})
})
+
+describe('getReadReplicaPath', () => {
+ it('builds the replica detail path', () => {
+ expect(getReadReplicaPath('project-ref', 'replica-1')).toBe(
+ '/project/project-ref/settings/infrastructure/replica/replica-1'
+ )
+ })
+
+ it('falls back to the default project placeholder', () => {
+ expect(getReadReplicaPath(undefined, 'replica-1')).toBe(
+ '/project/_/settings/infrastructure/replica/replica-1'
+ )
+ })
+})
+
+describe('getAddReadReplicaPath', () => {
+ it('opens the add-replica sheet on infrastructure', () => {
+ expect(getAddReadReplicaPath('project-ref')).toBe(
+ '/project/project-ref/settings/infrastructure?addReplica=true'
+ )
+ })
+
+ it('falls back to the default project placeholder', () => {
+ expect(getAddReadReplicaPath()).toBe('/project/_/settings/infrastructure?addReplica=true')
+ })
+})
diff --git a/apps/studio/components/interfaces/Settings/Infrastructure/Infrastructure.utils.ts b/apps/studio/components/interfaces/Settings/Infrastructure/Infrastructure.utils.ts
index 1d816d3151c..fd2a56000dd 100644
--- a/apps/studio/components/interfaces/Settings/Infrastructure/Infrastructure.utils.ts
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/Infrastructure.utils.ts
@@ -1,2 +1,8 @@
export const getInfrastructurePath = (projectRef?: string) =>
`/project/${projectRef ?? '_'}/settings/infrastructure`
+
+export const getReadReplicaPath = (projectRef: string | undefined, replicaId: string) =>
+ `/project/${projectRef ?? '_'}/settings/infrastructure/replica/${replicaId}`
+
+export const getAddReadReplicaPath = (projectRef?: string) =>
+ `/project/${projectRef ?? '_'}/settings/infrastructure?addReplica=true`
diff --git a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/Edge.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/Edge.tsx
index e260871c763..993f2cac35d 100644
--- a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/Edge.tsx
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/Edge.tsx
@@ -4,7 +4,7 @@ import { Loader2 } from 'lucide-react'
import { Tooltip, TooltipContent, TooltipTrigger } from 'ui'
import { EdgeData } from './InstanceConfiguration.constants'
-import { REPLICA_STATUS } from '@/components/interfaces/Database/Replication/Replication.constants'
+import { REPLICA_STATUS } from '@/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicas.constants'
import { useReplicationLagQuery } from '@/data/read-replicas/replica-lag-query'
import { formatDatabaseID } from '@/data/read-replicas/replicas.utils'
diff --git a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceConfiguration.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceConfiguration.tsx
index 5123d172de0..c49a7416010 100644
--- a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceConfiguration.tsx
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceConfiguration.tsx
@@ -21,7 +21,7 @@ import { SmoothstepEdge } from './Edge'
import { addRegionNodes, generateNodes, getDagreGraphLayout } from './InstanceConfiguration.utils'
import { LoadBalancerNode, PrimaryNode, RegionNode, ReplicaNode } from './InstanceNode'
import MapView from './MapView'
-import { REPLICA_STATUS } from '@/components/interfaces/Database/Replication/Replication.constants'
+import { REPLICA_STATUS } from '@/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicas.constants'
import { AlertError } from '@/components/ui/AlertError'
import { useLoadBalancersQuery } from '@/data/read-replicas/load-balancers-query'
import { useReadReplicasQuery } from '@/data/read-replicas/replicas-query'
diff --git a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceNode.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceNode.tsx
index 725260ff620..89fec06b3ac 100644
--- a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceNode.tsx
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceNode.tsx
@@ -33,7 +33,7 @@ import {
} from './InstanceConfiguration.constants'
import { formatSeconds } from './InstanceConfiguration.utils'
import { metricColor } from './InstanceNode.utils'
-import { REPLICA_STATUS } from '@/components/interfaces/Database/Replication/Replication.constants'
+import { REPLICA_STATUS } from '@/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicas.constants'
import { SparkBar } from '@/components/ui/SparkBar'
import {
DatabaseInitEstimations,
diff --git a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/MapView.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/MapView.tsx
index b551b4a707d..7894593313d 100644
--- a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/MapView.tsx
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/MapView.tsx
@@ -27,7 +27,7 @@ import { TimestampInfo } from 'ui-patterns/TimestampInfo'
import { AVAILABLE_REPLICA_REGIONS } from './InstanceConfiguration.constants'
import GeographyData from './MapData.json'
-import { REPLICA_STATUS } from '@/components/interfaces/Database/Replication/Replication.constants'
+import { REPLICA_STATUS } from '@/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicas.constants'
import { useReadReplicasQuery } from '@/data/read-replicas/replicas-query'
import { formatDatabaseID } from '@/data/read-replicas/replicas.utils'
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
diff --git a/apps/studio/components/interfaces/Database/Replication/ReadReplicas/DropReplicaConfirmationModal.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/DropReplicaConfirmationModal.tsx
similarity index 98%
rename from apps/studio/components/interfaces/Database/Replication/ReadReplicas/DropReplicaConfirmationModal.tsx
rename to apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/DropReplicaConfirmationModal.tsx
index 40be7d2e1f6..91f7c2fb97f 100644
--- a/apps/studio/components/interfaces/Database/Replication/ReadReplicas/DropReplicaConfirmationModal.tsx
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/DropReplicaConfirmationModal.tsx
@@ -3,7 +3,7 @@ import { useParams } from 'common'
import { toast } from 'sonner'
import { ConfirmationModal } from 'ui-patterns/Dialogs/ConfirmationModal'
-import { REPLICA_STATUS } from '../Replication.constants'
+import { REPLICA_STATUS } from './ReadReplicas.constants'
import { InlineLink } from '@/components/ui/InlineLink'
import { replicaKeys } from '@/data/read-replicas/keys'
import { useReadReplicaRemoveMutation } from '@/data/read-replicas/replica-remove-mutation'
diff --git a/apps/studio/components/interfaces/Database/Replication/ReadReplicas/ReadReplicaDetails.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaDetails.tsx
similarity index 99%
rename from apps/studio/components/interfaces/Database/Replication/ReadReplicas/ReadReplicaDetails.tsx
rename to apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaDetails.tsx
index 15d9a3916ae..0890b121762 100644
--- a/apps/studio/components/interfaces/Database/Replication/ReadReplicas/ReadReplicaDetails.tsx
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaDetails.tsx
@@ -17,7 +17,7 @@ import { Input } from 'ui-patterns/DataInputs/Input'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
-import { REPLICA_STATUS } from '../Replication.constants'
+import { REPLICA_STATUS } from './ReadReplicas.constants'
import { REPORT_DATERANGE_HELPER_LABELS } from '@/components/interfaces/Reports/Reports.constants'
import { ScaffoldContainer, ScaffoldSection } from '@/components/layouts/Scaffold'
import { useInfraMonitoringAttributesQuery } from '@/data/analytics/infra-monitoring-query'
diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/ReadReplicaEligibilityWarnings.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/ReadReplicaEligibilityWarnings.tsx
similarity index 99%
rename from apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/ReadReplicaEligibilityWarnings.tsx
rename to apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/ReadReplicaEligibilityWarnings.tsx
index f029406a602..e64bda607cf 100644
--- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/ReadReplicaEligibilityWarnings.tsx
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/ReadReplicaEligibilityWarnings.tsx
@@ -244,4 +244,6 @@ export const ReadReplicaEligibilityWarnings = () => {
)
}
+
+ return null
}
diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/ReadReplicaPricingDialog.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/ReadReplicaPricingDialog.tsx
similarity index 97%
rename from apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/ReadReplicaPricingDialog.tsx
rename to apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/ReadReplicaPricingDialog.tsx
index ca4ed2aa46e..bfc10a6f656 100644
--- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/ReadReplicaPricingDialog.tsx
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/ReadReplicaPricingDialog.tsx
@@ -99,7 +99,9 @@ export const ReadReplicaPricingDialog = () => {
Throughput
{throughput.label}
- {throughput.cost}
+
+ {throughput.cost}
+
)}
diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/index.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/index.tsx
similarity index 97%
rename from apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/index.tsx
rename to apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/index.tsx
index 0d43130e4ce..394560a4621 100644
--- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/index.tsx
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/index.tsx
@@ -43,7 +43,7 @@ export const ReadReplicaForm = ({
const [defaultRegion] = Object.entries(AWS_REGIONS).find(
([_, name]) => name === AWS_REGIONS_DEFAULT
- ) ?? ['ap-southeast-1']
+ ) ?? ['SOUTHEAST_ASIA']
const { can: canDeployReplica } = useCheckEligibilityDeployReplica()
const [selectedRegion, setSelectedRegion] = useState(defaultRegion)
@@ -61,7 +61,7 @@ export const ReadReplicaForm = ({
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'}...`)
+ toast.success(`Spinning up new replica in ${region ?? 'Unknown'}...`)
onSuccess?.()
onClose()
},
@@ -75,8 +75,9 @@ export const ReadReplicaForm = ({
: AVAILABLE_REPLICA_REGIONS
const onSubmit = async () => {
- const regionKey = AWS_REGIONS[selectedRegion as AWS_REGIONS_KEYS].code
if (!projectRef) return console.error('Project is required')
+
+ const regionKey = AWS_REGIONS[selectedRegion as AWS_REGIONS_KEYS]?.code
if (!regionKey) return toast.error('Unable to deploy replica: Unsupported region selected')
const primary = data?.find((db) => db.identifier === projectRef)
diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/useCheckEligibilityDeployReplica.ts b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/useCheckEligibilityDeployReplica.ts
similarity index 88%
rename from apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/useCheckEligibilityDeployReplica.ts
rename to apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/useCheckEligibilityDeployReplica.ts
index 42bce7874b5..6e8e7311314 100644
--- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/useCheckEligibilityDeployReplica.ts
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/useCheckEligibilityDeployReplica.ts
@@ -1,5 +1,4 @@
import { useParams } from 'common'
-import { useMemo } from 'react'
import { useOverdueInvoicesQuery } from '@/data/invoices/invoices-overdue-query'
import {
@@ -20,10 +19,7 @@ export const useCheckEligibilityDeployReplica = () => {
const { hasAccess: hasReadReplicaAccess } = useCheckEntitlements('instances.read_replicas')
const isAWSProvider = project?.cloud_provider === 'AWS'
const isWalgEnabled = project?.is_physical_backups_enabled
- const isNotOnHigherPlan = useMemo(
- () => !['team', 'enterprise', 'platform'].includes(org?.plan.id ?? ''),
- [org]
- )
+ const isNotOnHigherPlan = !['team', 'enterprise', 'platform'].includes(org?.plan.id ?? '')
const isProWithSpendCapEnabled = org?.plan.id === 'pro' && !org.usage_billing_enabled
const { data: allOverdueInvoices } = useOverdueInvoicesQuery({
@@ -48,12 +44,14 @@ export const useCheckEligibilityDeployReplica = () => {
const isReachedMaxReplicas =
(databases ?? []).filter((db) => db.identifier !== projectRef).length >= maxNumberOfReplicas
- const currentPgVersion = Number(
+ const parsedPgVersion = Number(
(project?.dbVersion ?? '').split('supabase-postgres-')[1]?.split('.')[0]
)
+ const currentPgVersion = Number.isNaN(parsedPgVersion) ? undefined : parsedPgVersion
const canDeployReplica =
!isReachedMaxReplicas &&
+ currentPgVersion !== undefined &&
currentPgVersion >= 15 &&
isAWSProvider &&
hasReadReplicaAccess &&
@@ -68,7 +66,7 @@ export const useCheckEligibilityDeployReplica = () => {
hasOverdueInvoices,
isAWSProvider,
isAwsK8s,
- isPgVersionBelow15: currentPgVersion < 15,
+ isPgVersionBelow15: currentPgVersion === undefined || currentPgVersion < 15,
isBelowSmallCompute,
isWalgNotEnabled: !isWalgEnabled,
isProWithSpendCapEnabled,
diff --git a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/useGetReplicaCost.ts b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/useGetReplicaCost.ts
similarity index 85%
rename from apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/useGetReplicaCost.ts
rename to apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/useGetReplicaCost.ts
index 01905ca1e2f..610b3b7c72f 100644
--- a/apps/studio/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/useGetReplicaCost.ts
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/useGetReplicaCost.ts
@@ -65,15 +65,21 @@ export const useGetReplicaCost = () => {
},
disk: {
type,
- label: `${((size_gb ?? 0) * 1.25).toLocaleString()} GB (${type})`,
+ label:
+ size_gb !== undefined && size_gb !== null && type !== undefined && type !== null
+ ? `${(size_gb * 1.25).toLocaleString()} GB (${type})`
+ : undefined,
cost: formatCurrency(additionalCostDiskSize),
},
iops: {
- label: `${iops?.toLocaleString()} IOPS`,
+ label: iops !== undefined && iops !== null ? `${iops.toLocaleString()} IOPS` : undefined,
cost: formatCurrency(+additionalCostIOPS),
},
throughput: {
- label: `${throughput_mbps?.toLocaleString()} MB/s`,
+ label:
+ throughput_mbps !== undefined && throughput_mbps !== null
+ ? `${throughput_mbps.toLocaleString()} MB/s`
+ : undefined,
cost: formatCurrency(+additionalCostThroughput),
},
}
diff --git a/apps/studio/components/interfaces/Database/Replication/ReadReplicas/ReadReplicaRow.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaRow.tsx
similarity index 98%
rename from apps/studio/components/interfaces/Database/Replication/ReadReplicas/ReadReplicaRow.tsx
rename to apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaRow.tsx
index 51ee5787cdb..5895abb13d8 100644
--- a/apps/studio/components/interfaces/Database/Replication/ReadReplicas/ReadReplicaRow.tsx
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaRow.tsx
@@ -20,8 +20,8 @@ import {
} from 'ui'
import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
-import { REPLICA_STATUS } from '../Replication.constants'
import { DropReplicaConfirmationModal } from './DropReplicaConfirmationModal'
+import { REPLICA_STATUS } from './ReadReplicas.constants'
import { getIsInTransition, getStatusLabel } from './ReadReplicas.utils'
import { RestartReplicaConfirmationModal } from './RestartReplicaConfirmationModal'
import { useReplicationLagQuery } from '@/data/read-replicas/replica-lag-query'
diff --git a/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicas.constants.ts b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicas.constants.ts
new file mode 100644
index 00000000000..50f8d4f6e7f
--- /dev/null
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicas.constants.ts
@@ -0,0 +1,11 @@
+import { components } from 'api-types'
+
+import { PROJECT_STATUS } from '@/lib/constants'
+
+export const REPLICA_STATUS: {
+ [key: string]: components['schemas']['DatabaseStatusResponse']['status']
+} = {
+ ...PROJECT_STATUS,
+ INIT_READ_REPLICA: 'INIT_READ_REPLICA',
+ INIT_READ_REPLICA_FAILED: 'INIT_READ_REPLICA_FAILED',
+}
diff --git a/apps/studio/components/interfaces/Database/Replication/ReadReplicas/ReadReplicas.utils.ts b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicas.utils.ts
similarity index 96%
rename from apps/studio/components/interfaces/Database/Replication/ReadReplicas/ReadReplicas.utils.ts
rename to apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicas.utils.ts
index 1ecd1538016..2c47ebd6fac 100644
--- a/apps/studio/components/interfaces/Database/Replication/ReadReplicas/ReadReplicas.utils.ts
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicas.utils.ts
@@ -1,4 +1,4 @@
-import { REPLICA_STATUS } from '../Replication.constants'
+import { REPLICA_STATUS } from './ReadReplicas.constants'
import { ReplicaInitializationStatus } from '@/data/read-replicas/replicas-status-query'
export const getIsInTransition = ({
diff --git a/apps/studio/components/interfaces/Database/Replication/ReadReplicas/RestartReplicaConfirmationModal.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/RestartReplicaConfirmationModal.tsx
similarity index 98%
rename from apps/studio/components/interfaces/Database/Replication/ReadReplicas/RestartReplicaConfirmationModal.tsx
rename to apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/RestartReplicaConfirmationModal.tsx
index c8a6c2c5786..bac0a3d85e1 100644
--- a/apps/studio/components/interfaces/Database/Replication/ReadReplicas/RestartReplicaConfirmationModal.tsx
+++ b/apps/studio/components/interfaces/Settings/Infrastructure/ReadReplicas/RestartReplicaConfirmationModal.tsx
@@ -3,7 +3,7 @@ import { useParams } from 'common'
import { toast } from 'sonner'
import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
-import { REPLICA_STATUS } from '../Replication.constants'
+import { REPLICA_STATUS } from './ReadReplicas.constants'
import { useProjectRestartMutation } from '@/data/projects/project-restart-mutation'
import { replicaKeys } from '@/data/read-replicas/keys'
import { Database } from '@/data/read-replicas/replicas-query'
diff --git a/apps/studio/pages/project/[ref]/database/replication/replica/[replicaId].tsx b/apps/studio/pages/project/[ref]/database/replication/replica/[replicaId].tsx
index ffabcbeed20..e129249b1e3 100644
--- a/apps/studio/pages/project/[ref]/database/replication/replica/[replicaId].tsx
+++ b/apps/studio/pages/project/[ref]/database/replication/replica/[replicaId].tsx
@@ -8,14 +8,14 @@ import { AWS_REGIONS } from 'shared-data'
import { Badge, Button } from 'ui'
import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
-import { DropReplicaConfirmationModal } from '@/components/interfaces/Database/Replication/ReadReplicas/DropReplicaConfirmationModal'
-import { ReadReplicaDetails } from '@/components/interfaces/Database/Replication/ReadReplicas/ReadReplicaDetails'
+import { DropReplicaConfirmationModal } from '@/components/interfaces/Settings/Infrastructure/ReadReplicas/DropReplicaConfirmationModal'
+import { ReadReplicaDetails } from '@/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaDetails'
+import { REPLICA_STATUS } from '@/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicas.constants'
import {
getIsInTransition,
getStatusLabel,
-} from '@/components/interfaces/Database/Replication/ReadReplicas/ReadReplicas.utils'
-import { RestartReplicaConfirmationModal } from '@/components/interfaces/Database/Replication/ReadReplicas/RestartReplicaConfirmationModal'
-import { REPLICA_STATUS } from '@/components/interfaces/Database/Replication/Replication.constants'
+} from '@/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicas.utils'
+import { RestartReplicaConfirmationModal } from '@/components/interfaces/Settings/Infrastructure/ReadReplicas/RestartReplicaConfirmationModal'
import DatabaseLayout from '@/components/layouts/DatabaseLayout/DatabaseLayout'
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
import { PageLayout } from '@/components/layouts/PageLayout/PageLayout'
diff --git a/apps/studio/tests/components/Database/Replication/ReadReplicaEligibilityWarnings.test.tsx b/apps/studio/tests/components/Settings/Infrastructure/ReadReplicaEligibilityWarnings.test.tsx
similarity index 91%
rename from apps/studio/tests/components/Database/Replication/ReadReplicaEligibilityWarnings.test.tsx
rename to apps/studio/tests/components/Settings/Infrastructure/ReadReplicaEligibilityWarnings.test.tsx
index 10bce0f7d1c..c9471145d67 100644
--- a/apps/studio/tests/components/Database/Replication/ReadReplicaEligibilityWarnings.test.tsx
+++ b/apps/studio/tests/components/Settings/Infrastructure/ReadReplicaEligibilityWarnings.test.tsx
@@ -1,13 +1,13 @@
import { screen } from '@testing-library/react'
import { describe, expect, it, vi } from 'vitest'
-import { ReadReplicaEligibilityWarnings } from '@/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/ReadReplicaEligibilityWarnings'
-import { useCheckEligibilityDeployReplica } from '@/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/useCheckEligibilityDeployReplica'
+import { ReadReplicaEligibilityWarnings } from '@/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/ReadReplicaEligibilityWarnings'
+import { useCheckEligibilityDeployReplica } from '@/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/useCheckEligibilityDeployReplica'
import { READ_REPLICAS_MAX_COUNT } from '@/data/read-replicas/replicas-query'
import { customRender } from '@/tests/lib/custom-render'
vi.mock(
- '@/components/interfaces/Database/Replication/DestinationPanel/ReadReplicaForm/useCheckEligibilityDeployReplica'
+ '@/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/useCheckEligibilityDeployReplica'
)
vi.mock('@/data/projects/project-detail-query', () => ({
useProjectDetailQuery: () => ({ data: undefined, isSuccess: false }),