mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
chore: Disable some of the Studio features on Multigres projects (#46775)
This PR disables the following features on Multigres projects <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Enhanced replication interface with improved visual states. * **Bug Fixes** * Added validation to prevent incompatible database configuration combinations. * **Changes** * High Availability projects now display informational notices indicating unavailable features: Realtime, Replication, and PITR backups. * **Removed** * Removed redundant UI component from the application. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com>
This commit is contained in:
1 parent
dfc2dede05
commit
e1ccc31fcc
7 files changed
+188
-68
No files matched your search
+57
@@ -0,0 +1,57 @@
|
||||
import { Background, ColorMode, ReactFlow, ReactFlowProvider } from '@xyflow/react'
|
||||
import { useTheme } from 'next-themes'
|
||||
|
||||
import { PrimaryDatabaseNode, ReadReplicaNode, ReplicationNode } from './Nodes'
|
||||
|
||||
import '@xyflow/react/dist/style.css'
|
||||
|
||||
import { SmoothstepEdge } from './Edges'
|
||||
|
||||
export const EmptyReplicationDiagram = () => {
|
||||
return (
|
||||
<ReactFlowProvider>
|
||||
<ReplicationDiagramContent />
|
||||
</ReactFlowProvider>
|
||||
)
|
||||
}
|
||||
|
||||
const nodeTypes = {
|
||||
primary: PrimaryDatabaseNode,
|
||||
replication: ReplicationNode,
|
||||
readReplica: ReadReplicaNode,
|
||||
}
|
||||
|
||||
const edgeTypes = { smoothstep: SmoothstepEdge }
|
||||
|
||||
const ReplicationDiagramContent = () => {
|
||||
const { resolvedTheme } = useTheme()
|
||||
|
||||
const backgroundPatternColor =
|
||||
resolvedTheme === 'dark' ? 'rgba(255, 255, 255, 0.3)' : 'rgba(0, 0, 0, 0.4)'
|
||||
|
||||
return (
|
||||
<div className="nowheel relative min-h-[350px]">
|
||||
<ReactFlow
|
||||
// FIXME: https://github.com/xyflow/xyflow/issues/4876
|
||||
colorMode={'' as unknown as ColorMode}
|
||||
fitView
|
||||
fitViewOptions={{ minZoom: 0.8, maxZoom: 0.9 }}
|
||||
className="bg"
|
||||
zoomOnPinch={false}
|
||||
zoomOnScroll={false}
|
||||
nodesDraggable={false}
|
||||
nodesConnectable={false}
|
||||
zoomOnDoubleClick={false}
|
||||
edgesFocusable={false}
|
||||
edgesReconnectable={false}
|
||||
defaultNodes={[]}
|
||||
defaultEdges={[]}
|
||||
nodeTypes={nodeTypes}
|
||||
edgeTypes={edgeTypes}
|
||||
proOptions={{ hideAttribution: true }}
|
||||
>
|
||||
<Background color={backgroundPatternColor} />
|
||||
</ReactFlow>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -44,7 +44,10 @@ export const FormSchema = z
|
||||
useOrioleDb: z.boolean(),
|
||||
})
|
||||
.superRefine(
|
||||
({ dbPassStrength, dbPassStrengthWarning, highAvailability, cloudProvider }, ctx) => {
|
||||
(
|
||||
{ dbPassStrength, dbPassStrengthWarning, highAvailability, cloudProvider, useOrioleDb },
|
||||
ctx
|
||||
) => {
|
||||
if (dbPassStrength < DEFAULT_MINIMUM_PASSWORD_STRENGTH) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
@@ -59,6 +62,19 @@ export const FormSchema = z
|
||||
message: 'High availability is only supported on AWS (Revamped)',
|
||||
})
|
||||
}
|
||||
|
||||
if (highAvailability && useOrioleDb) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
path: ['highAvailability'],
|
||||
message: 'High availability is not supported with OrioleDB images',
|
||||
})
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
path: ['useOrioleDb'],
|
||||
message: 'High availability is not supported with OrioleDB images',
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { Realtime } from 'icons'
|
||||
import { ExternalLink } from 'lucide-react'
|
||||
import Head from 'next/head'
|
||||
import { useRouter } from 'next/router'
|
||||
import type { PropsWithChildren } from 'react'
|
||||
import { Button } from 'ui'
|
||||
|
||||
import { ProjectLayout } from '../ProjectLayout'
|
||||
import { generateRealtimeMenu } from './RealtimeMenu.utils'
|
||||
@@ -31,6 +35,42 @@ export const RealtimeLayout = ({ title, children }: PropsWithChildren<RealtimeLa
|
||||
const page = router.pathname.split('/')[4]
|
||||
const menu = generateRealtimeMenu(project)
|
||||
|
||||
if (!!project?.high_availability) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{title}</title>
|
||||
<meta name="description" content="Supabase Studio" />
|
||||
</Head>
|
||||
<main
|
||||
id="panel-project-content"
|
||||
className="h-full w-full xl:min-w-[600px] flex items-center justify-center overflow-y-auto overflow-x-hidden bg-dash-sidebar p-6 @container"
|
||||
>
|
||||
<div className="flex max-w-md flex-col items-center gap-y-5 text-center">
|
||||
<div className="flex h-12 w-12 items-center justify-center rounded-lg border border-strong bg-surface-100 text-foreground-light">
|
||||
<Realtime size={22} strokeWidth={1.5} />
|
||||
</div>
|
||||
<div className="flex flex-col gap-y-2">
|
||||
<h3 className="text-base text-foreground">
|
||||
Realtime is not available for High Availability projects
|
||||
</h3>
|
||||
<p className="text-sm text-foreground-light">
|
||||
Realtime is not currently available for projects with High Availability. Reach out
|
||||
to our support team if you're interested in using this feature with your High
|
||||
Availability project.
|
||||
</p>
|
||||
</div>
|
||||
<Button asChild type="default" icon={<ExternalLink />}>
|
||||
<a href="https://supabase.com/support" target="_blank" rel="noopener noreferrer">
|
||||
Contact support
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<ProjectLayout
|
||||
product="Realtime"
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import { BookOpenText } from 'lucide-react'
|
||||
|
||||
import { ButtonTooltip } from './ButtonTooltip'
|
||||
import { useTrack } from '@/lib/telemetry/track'
|
||||
import { useAppStateSnapshot } from '@/state/app-state'
|
||||
|
||||
interface APIDocsButtonProps {
|
||||
section?: string[]
|
||||
source: string
|
||||
label?: string
|
||||
tooltip?: string
|
||||
}
|
||||
|
||||
export const APIDocsButton = ({ section, source, label, tooltip }: APIDocsButtonProps) => {
|
||||
const snap = useAppStateSnapshot()
|
||||
const track = useTrack()
|
||||
|
||||
return (
|
||||
<ButtonTooltip
|
||||
size="tiny"
|
||||
type="default"
|
||||
onClick={() => {
|
||||
if (section) snap.setActiveDocsSection(section)
|
||||
snap.setShowProjectApiDocs(true)
|
||||
|
||||
track('api_docs_opened', { source })
|
||||
}}
|
||||
icon={<BookOpenText />}
|
||||
className={label ? undefined : 'w-7'}
|
||||
tooltip={{
|
||||
content: {
|
||||
side: 'bottom',
|
||||
text: tooltip ?? 'API Docs',
|
||||
},
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</ButtonTooltip>
|
||||
)
|
||||
}
|
||||
@@ -101,6 +101,18 @@ const PITR = () => {
|
||||
)
|
||||
}
|
||||
|
||||
if (project?.high_availability) {
|
||||
return (
|
||||
<Admonition
|
||||
type="default"
|
||||
title="Database backups are not available for High Availability projects"
|
||||
description="High Availability projects do not support Point-in-Time Recovery (PITR) backups"
|
||||
>
|
||||
<DocsButton abbrev={false} className="mt-2" href={DOCS_URL} />
|
||||
</Admonition>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{isLoading && <GenericSkeletonLoader />}
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
import { useParams } from 'common'
|
||||
import { Admonition } from 'ui-patterns/admonition'
|
||||
import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
|
||||
|
||||
import { Destinations } from '@/components/interfaces/Database/Replication/Destinations'
|
||||
import { ReplicationDiagram } from '@/components/interfaces/Database/Replication/ReplicationDiagram'
|
||||
import { EmptyReplicationDiagram } from '@/components/interfaces/Database/Replication/ReplicationDiagram/EmptyReplicationDiagram'
|
||||
import DatabaseLayout from '@/components/layouts/DatabaseLayout/DatabaseLayout'
|
||||
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { ScaffoldContainer, ScaffoldSection } from '@/components/layouts/Scaffold'
|
||||
import { UnknownInterface } from '@/components/ui/UnknownInterface'
|
||||
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { PipelineRequestStatusProvider } from '@/state/replication-pipeline-request-status'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
|
||||
const DatabaseReplicationPage: NextPageWithLayout = () => {
|
||||
const { ref } = useParams()
|
||||
const { data: selectedProject, isPending } = useSelectedProjectQuery()
|
||||
const showPgReplicate = useIsFeatureEnabled('database:replication')
|
||||
|
||||
if (!showPgReplicate) {
|
||||
return <UnknownInterface urlBack={`/project/${ref}/database/schemas`} />
|
||||
return <UnknownInterface urlBack={`/project/${selectedProject?.ref}/database/schemas`} />
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -34,13 +37,45 @@ const DatabaseReplicationPage: NextPageWithLayout = () => {
|
||||
</ScaffoldSection>
|
||||
</ScaffoldContainer>
|
||||
|
||||
<ReplicationDiagram />
|
||||
{isPending ? (
|
||||
<ScaffoldContainer>
|
||||
<GenericSkeletonLoader />
|
||||
</ScaffoldContainer>
|
||||
) : selectedProject?.high_availability ? (
|
||||
<>
|
||||
<EmptyReplicationDiagram />
|
||||
|
||||
<ScaffoldContainer>
|
||||
<ScaffoldSection isFullWidth className="pt-6!">
|
||||
<Destinations />
|
||||
</ScaffoldSection>
|
||||
</ScaffoldContainer>
|
||||
<ScaffoldContainer>
|
||||
<ScaffoldSection isFullWidth className="pt-6!">
|
||||
<Admonition
|
||||
variant="default"
|
||||
title="Replication is not available for High Availability projects"
|
||||
>
|
||||
Replication is not currently available for projects with High Availability. Please
|
||||
contact{' '}
|
||||
<a
|
||||
href="https://supabase.com/support"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-primary underline"
|
||||
>
|
||||
support
|
||||
</a>{' '}
|
||||
if you are interested in using this feature with your High Availability project.
|
||||
</Admonition>
|
||||
</ScaffoldSection>
|
||||
</ScaffoldContainer>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<ReplicationDiagram />
|
||||
<ScaffoldContainer>
|
||||
<ScaffoldSection isFullWidth className="pt-6!">
|
||||
<Destinations />
|
||||
</ScaffoldSection>
|
||||
</ScaffoldContainer>
|
||||
</>
|
||||
)}
|
||||
</PipelineRequestStatusProvider>
|
||||
)
|
||||
}
|
||||
|
||||
Generated
+18
-18
@@ -16739,8 +16739,8 @@ packages:
|
||||
resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
tslib@2.6.2:
|
||||
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
|
||||
tslib@2.6.3:
|
||||
resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==}
|
||||
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
@@ -19117,7 +19117,7 @@ snapshots:
|
||||
'@dnd-kit/utilities': 3.2.2(react@19.2.6)
|
||||
react: 19.2.6
|
||||
react-dom: 19.2.6(react@19.2.6)
|
||||
tslib: 2.6.2
|
||||
tslib: 2.8.1
|
||||
|
||||
'@dnd-kit/modifiers@9.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)':
|
||||
dependencies:
|
||||
@@ -19131,12 +19131,12 @@ snapshots:
|
||||
'@dnd-kit/core': 6.3.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@dnd-kit/utilities': 3.2.2(react@19.2.6)
|
||||
react: 19.2.6
|
||||
tslib: 2.6.2
|
||||
tslib: 2.8.1
|
||||
|
||||
'@dnd-kit/utilities@3.2.2(react@19.2.6)':
|
||||
dependencies:
|
||||
react: 19.2.6
|
||||
tslib: 2.6.2
|
||||
tslib: 2.8.1
|
||||
|
||||
'@dotenvx/dotenvx@1.51.0':
|
||||
dependencies:
|
||||
@@ -19571,7 +19571,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0)
|
||||
graphql: 16.11.0
|
||||
tslib: 2.6.2
|
||||
tslib: 2.6.3
|
||||
|
||||
'@graphql-codegen/cli@5.0.5(@parcel/watcher@2.5.6)(@types/node@22.13.14)(encoding@0.1.13)(graphql-sock@1.0.1(graphql@16.11.0))(graphql@16.11.0)(supports-color@8.1.1)(typescript@6.0.2)':
|
||||
dependencies:
|
||||
@@ -19642,7 +19642,7 @@ snapshots:
|
||||
'@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0)
|
||||
graphql: 16.11.0
|
||||
graphql-sock: 1.0.1(graphql@16.11.0)
|
||||
tslib: 2.6.2
|
||||
tslib: 2.6.3
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
@@ -19652,7 +19652,7 @@ snapshots:
|
||||
'@graphql-tools/schema': 10.0.23(graphql@16.11.0)
|
||||
'@graphql-tools/utils': 10.8.6(graphql@16.11.0)
|
||||
graphql: 16.11.0
|
||||
tslib: 2.6.2
|
||||
tslib: 2.6.3
|
||||
|
||||
'@graphql-codegen/gql-tag-operations@4.0.17(encoding@0.1.13)(graphql@16.11.0)':
|
||||
dependencies:
|
||||
@@ -19661,7 +19661,7 @@ snapshots:
|
||||
'@graphql-tools/utils': 10.8.6(graphql@16.11.0)
|
||||
auto-bind: 4.0.0
|
||||
graphql: 16.11.0
|
||||
tslib: 2.6.2
|
||||
tslib: 2.6.3
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
@@ -19673,14 +19673,14 @@ snapshots:
|
||||
graphql: 16.11.0
|
||||
import-from: 4.0.0
|
||||
lodash: 4.18.1
|
||||
tslib: 2.6.2
|
||||
tslib: 2.6.3
|
||||
|
||||
'@graphql-codegen/schema-ast@4.1.0(graphql@16.11.0)':
|
||||
dependencies:
|
||||
'@graphql-codegen/plugin-helpers': 5.1.0(graphql@16.11.0)
|
||||
'@graphql-tools/utils': 10.8.6(graphql@16.11.0)
|
||||
graphql: 16.11.0
|
||||
tslib: 2.6.2
|
||||
tslib: 2.6.3
|
||||
|
||||
'@graphql-codegen/typed-document-node@5.1.1(encoding@0.1.13)(graphql@16.11.0)':
|
||||
dependencies:
|
||||
@@ -19689,7 +19689,7 @@ snapshots:
|
||||
auto-bind: 4.0.0
|
||||
change-case-all: 1.0.15
|
||||
graphql: 16.11.0
|
||||
tslib: 2.6.2
|
||||
tslib: 2.6.3
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
@@ -19701,7 +19701,7 @@ snapshots:
|
||||
auto-bind: 4.0.0
|
||||
graphql: 16.11.0
|
||||
graphql-sock: 1.0.1(graphql@16.11.0)
|
||||
tslib: 2.6.2
|
||||
tslib: 2.6.3
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
@@ -19714,7 +19714,7 @@ snapshots:
|
||||
auto-bind: 4.0.0
|
||||
graphql: 16.11.0
|
||||
graphql-sock: 1.0.1(graphql@16.11.0)
|
||||
tslib: 2.6.2
|
||||
tslib: 2.6.3
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
@@ -19725,7 +19725,7 @@ snapshots:
|
||||
'@graphql-codegen/visitor-plugin-common': 5.8.0(encoding@0.1.13)(graphql@16.11.0)
|
||||
auto-bind: 4.0.0
|
||||
graphql: 16.11.0
|
||||
tslib: 2.6.2
|
||||
tslib: 2.6.3
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
@@ -19741,7 +19741,7 @@ snapshots:
|
||||
graphql: 16.11.0
|
||||
graphql-tag: 2.12.6(graphql@16.11.0)
|
||||
parse-filepath: 1.0.2
|
||||
tslib: 2.6.2
|
||||
tslib: 2.6.3
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
@@ -20045,7 +20045,7 @@ snapshots:
|
||||
'@har-sdk/core': 1.4.5
|
||||
json-pointer: 0.6.2
|
||||
randexp: 0.5.3
|
||||
tslib: 2.6.2
|
||||
tslib: 2.8.1
|
||||
|
||||
'@hcaptcha/loader@2.0.0': {}
|
||||
|
||||
@@ -34997,7 +34997,7 @@ snapshots:
|
||||
minimist: 1.2.8
|
||||
strip-bom: 3.0.0
|
||||
|
||||
tslib@2.6.2: {}
|
||||
tslib@2.6.3: {}
|
||||
|
||||
tslib@2.8.1: {}
|
||||
|
||||
|
||||
Reference in new issue
Block a user