import { ChevronRight, FileCode, X } from 'lucide-react'
import Link from 'next/link'
import { PropsWithChildren, ReactNode } from 'react'
import { useParams } from 'common'
import { useSupavisorConfigurationQuery } from 'data/database/supavisor-configuration-query'
import { IS_PLATFORM } from 'lib/constants'
import { useDatabaseSelectorStateSnapshot } from 'state/database-selector'
import {
Badge,
Button,
cn,
CodeBlock,
CodeBlockLang,
Collapsible_Shadcn_,
CollapsibleContent_Shadcn_,
CollapsibleTrigger_Shadcn_,
WarningIcon,
} from 'ui'
import { Admonition } from 'ui-patterns'
import { ConnectionParameters } from './ConnectionParameters'
import { DirectConnectionIcon, TransactionIcon } from './PoolerIcons'
interface ConnectionPanelProps {
type?: 'direct' | 'transaction' | 'session'
badge?: string
title: string
description: string
connectionString: string
ipv4Status: {
type: 'error' | 'success'
title: string
description?: string | ReactNode
links?: { text: string; url: string }[]
}
notice?: string[]
parameters?: Array<{
key: string
value: string
description?: string
}>
contentType?: 'input' | 'code'
lang?: CodeBlockLang
fileTitle?: string
onCopyCallback: () => void
}
const IPv4StatusIcon = ({ className, active }: { className?: string; active: boolean }) => {
return (
)
}
export const CodeBlockFileHeader = ({ title }: { title: string }) => {
return (
)
}
export const ConnectionPanel = ({
type = 'direct',
badge,
title,
description,
connectionString,
ipv4Status,
notice,
parameters = [],
lang = 'bash',
fileTitle,
children,
onCopyCallback,
}: PropsWithChildren) => {
const { ref: projectRef } = useParams()
const state = useDatabaseSelectorStateSnapshot()
const { data: poolingInfo } = useSupavisorConfigurationQuery({ projectRef })
const poolingConfiguration = poolingInfo?.find((x) => x.identifier === state.selectedDatabaseId)
const isSessionMode = poolingConfiguration?.pool_mode === 'session'
const links = ipv4Status.links ?? []
return (
{title}
{!!badge && {badge}}
{description}
{fileTitle &&
}
{type === 'transaction' && isSessionMode ? (
) : (
<>
{notice && (
{notice?.map((text: string) => (
{text}
))}
)}
{parameters.length > 0 &&
}
>
)}
{children}
{type !== 'session' && (
<>
{type === 'transaction' ? : }
{type === 'transaction'
? 'Suitable for a large number of connected clients'
: 'Suitable for long-lived, persistent connections'}
{type === 'transaction'
? 'Clients share a connection pool'
: 'Each client has a dedicated connection to Postgres'}
>
)}
{IS_PLATFORM && (
{ipv4Status.title}
{ipv4Status.description &&
(typeof ipv4Status.description === 'string' ? (
{ipv4Status.description}
) : (
ipv4Status.description
))}
{links.length > 0 && (
{links.map((link) => (
))}
)}
)}
{type === 'session' && (
Only use on a IPv4 network
Use Direct Connection if connecting via an IPv6 network
)}
{IS_PLATFORM && ipv4Status.type === 'error' && (
}
>
Some platforms are IPv4-only:
A few major platforms are IPv4-only and may not work with a Direct Connection:
Vercel
GitHub Actions
Render
Retool
If you wish to use a Direct Connection with these, please purchase{' '}
IPv4 support
.
You may also use the{' '}
Session Pooler or{' '}
Transaction Pooler if you are on
a IPv4 network.
)}
)
}