mirror of
https://github.com/supabase/supabase.git
synced 2026-10-14 05:39:11 +03:00
feat(studio): relocate read replica modules under Infrastructure (#49043)
## What kind of change does this PR introduce? Feature. Stack 1 of 5 for [PIPE-1007](https://linear.app/supabase/issue/PIPE-1007/move-read-replicas-out-of-replication-into-infrastructure). ## What is the current behavior? Read replica UI lives under Database / Replication. ## What is the new behavior? Moves replica form, row, and modals into Settings/Infrastructure and extracts `REPLICA_STATUS` plus path helpers. URLs and user-facing behaviour are unchanged. ## Additional context Keep `infrastructure:read_replicas` off in prod until the full stack lands. Stack: this PR → [#49044](https://github.com/supabase/supabase/pull/49044) → [#49045](https://github.com/supabase/supabase/pull/49045) → [#49046](https://github.com/supabase/supabase/pull/49046) → [#48921](https://github.com/supabase/supabase/pull/48921) ## To test Open [Database / Replication](https://studio-staging-git-danny-pipe-1007-01-relocate-701014-supabase.vercel.app/dashboard/project/_/database/replication?destinationType=Read+Replica). Confirm add replica still works as today. No new Infrastructure section yet. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added navigation for viewing a specific read replica and starting the add-replica setup flow. - Improved read-replica setup validation, including unsupported regions and invalid PostgreSQL versions. - **Bug Fixes** - Corrected default region and success messaging behavior. - Prevented incomplete pricing labels and clarified eligibility warnings. - Improved display handling for localized pricing values. - **Tests** - Added coverage for read-replica navigation paths and fallback behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
1 parent
67d4fed40d
commit
2c8cc7ec8a
23 files changed
+93
-46
No files matched your search
+1
-1
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
@@ -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'
|
||||
|
||||
+31
-1
@@ -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')
|
||||
})
|
||||
})
|
||||
@@ -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`
|
||||
+1
-1
@@ -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'
|
||||
|
||||
|
||||
+1
-1
@@ -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'
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
+1
-1
@@ -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'
|
||||
|
||||
+1
-1
@@ -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'
|
||||
+1
-1
@@ -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'
|
||||
+2
@@ -244,4 +244,6 @@ export const ReadReplicaEligibilityWarnings = () => {
|
||||
</Admonition>
|
||||
)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
+3
-1
@@ -99,7 +99,9 @@ export const ReadReplicaPricingDialog = () => {
|
||||
<TableRow>
|
||||
<TableCell>Throughput</TableCell>
|
||||
<TableCell>{throughput.label}</TableCell>
|
||||
<TableCell className="text-right font-mono">{throughput.cost}</TableCell>
|
||||
<TableCell className="text-right font-mono" translate="no">
|
||||
{throughput.cost}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
+4
-3
@@ -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<string>(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)
|
||||
+5
-7
@@ -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,
|
||||
+9
-3
@@ -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),
|
||||
},
|
||||
}
|
||||
+1
-1
@@ -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'
|
||||
+11
@@ -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',
|
||||
}
|
||||
+1
-1
@@ -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 = ({
|
||||
+1
-1
@@ -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'
|
||||
@@ -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'
|
||||
|
||||
+3
-3
@@ -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 }),
|
||||
Reference in new issue
Block a user