mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
Remove connectDialogUpdate flag and clean up old connection string components (#32613)
* Remove connectDialogUpdate flag and clean up old connection string components * Fix
This commit is contained in:
1 parent
4eca1ecbb7
commit
1331cc8b63
10 files changed
+20
-925
No files matched your search
@@ -1,16 +1,13 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import { ExternalLink, Plug } from 'lucide-react'
|
||||
import { parseAsBoolean, useQueryState } from 'nuqs'
|
||||
import { useState } from 'react'
|
||||
|
||||
import { DatabaseConnectionString } from 'components/interfaces/Connect/DatabaseConnectionString'
|
||||
import { DatabaseConnectionString as OldDatabaseConnectionString } from 'components/interfaces/Settings/Database/DatabaseSettings/DatabaseConnectionString'
|
||||
|
||||
import Panel from 'components/ui/Panel'
|
||||
import { getAPIKeys, useProjectSettingsV2Query } from 'data/config/project-settings-v2-query'
|
||||
import { useCheckPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import { useFlag } from 'hooks/ui/useFlag'
|
||||
import { parseAsBoolean, useQueryState } from 'nuqs'
|
||||
import {
|
||||
Button,
|
||||
DIALOG_PADDING_X,
|
||||
@@ -34,7 +31,6 @@ import ConnectTabContent from './ConnectTabContent'
|
||||
|
||||
const Connect = () => {
|
||||
const { ref: projectRef } = useParams()
|
||||
const connectDialogUpdate = useFlag('connectDialogUpdate')
|
||||
|
||||
const [showConnect, setShowConnect] = useQueryState(
|
||||
'showConnect',
|
||||
@@ -154,11 +150,7 @@ const Connect = () => {
|
||||
return (
|
||||
<Dialog open={showConnect} onOpenChange={(open) => setShowConnect(!open ? null : open)}>
|
||||
<DialogTrigger asChild>
|
||||
<Button
|
||||
type={connectDialogUpdate ? 'default' : 'primary'}
|
||||
className={cn(connectDialogUpdate && 'rounded-full')}
|
||||
icon={<Plug className="rotate-90" />}
|
||||
>
|
||||
<Button type="default" className="rounded-full" icon={<Plug className="rotate-90" />}>
|
||||
<span>Connect</span>
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
@@ -196,13 +188,7 @@ const Connect = () => {
|
||||
className={cn('!mt-0', 'p-0', 'flex flex-col gap-6')}
|
||||
>
|
||||
<div className={DIALOG_PADDING_Y}>
|
||||
{connectDialogUpdate ? (
|
||||
<DatabaseConnectionString />
|
||||
) : (
|
||||
<div className="px-7">
|
||||
<OldDatabaseConnectionString appearance="minimal" />
|
||||
</div>
|
||||
)}
|
||||
<DatabaseConnectionString />
|
||||
</div>
|
||||
</TabsContent_Shadcn_>
|
||||
)
|
||||
|
||||
@@ -2,13 +2,13 @@ import dynamic from 'next/dynamic'
|
||||
import { forwardRef, HTMLAttributes, useMemo } from 'react'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import { getConnectionStrings } from 'components/interfaces/Settings/Database/DatabaseSettings/DatabaseSettings.utils'
|
||||
import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
|
||||
import { useProjectSettingsV2Query } from 'data/config/project-settings-v2-query'
|
||||
import { usePoolingConfigurationQuery } from 'data/database/pooling-configuration-query'
|
||||
import { pluckObjectFields } from 'lib/helpers'
|
||||
import { cn } from 'ui'
|
||||
import type { projectKeys } from './Connect.types'
|
||||
import { getConnectionStrings as getConnectionStringsV2 } from './DatabaseSettings.utils'
|
||||
|
||||
interface ConnectContentTabProps extends HTMLAttributes<HTMLDivElement> {
|
||||
projectKeys: projectKeys
|
||||
@@ -20,7 +20,7 @@ interface ConnectContentTabProps extends HTMLAttributes<HTMLDivElement> {
|
||||
connectionStringDirect?: string
|
||||
}
|
||||
|
||||
const ConnectTabContentNew = forwardRef<HTMLDivElement, ConnectContentTabProps>(
|
||||
const ConnectTabContent = forwardRef<HTMLDivElement, ConnectContentTabProps>(
|
||||
({ projectKeys, filePath, ...props }, ref) => {
|
||||
const { ref: projectRef } = useParams()
|
||||
|
||||
@@ -32,20 +32,13 @@ const ConnectTabContentNew = forwardRef<HTMLDivElement, ConnectContentTabProps>(
|
||||
const connectionInfo = pluckObjectFields(settings || emptyState, DB_FIELDS)
|
||||
const poolingConfiguration = poolingInfo?.find((x) => x.database_type === 'PRIMARY')
|
||||
|
||||
const connectionStringsPooler =
|
||||
const connectionStrings =
|
||||
poolingConfiguration !== undefined
|
||||
? getConnectionStrings(connectionInfo, poolingConfiguration, {
|
||||
projectRef,
|
||||
usePoolerConnection: true,
|
||||
})
|
||||
: { uri: '' }
|
||||
const connectionStringsDirect =
|
||||
poolingConfiguration !== undefined
|
||||
? getConnectionStrings(connectionInfo, poolingConfiguration, {
|
||||
projectRef,
|
||||
usePoolerConnection: false,
|
||||
})
|
||||
: { uri: '' }
|
||||
? getConnectionStringsV2(connectionInfo, poolingConfiguration, { projectRef })
|
||||
: { direct: { uri: '' }, pooler: { uri: '' } }
|
||||
const connectionStringsPooler = connectionStrings.pooler
|
||||
const connectionStringsDirect = connectionStrings.direct
|
||||
|
||||
const connectionStringPoolerTransaction = connectionStringsPooler.uri
|
||||
const connectionStringPoolerSession = connectionStringsPooler.uri.replace('6543', '5432')
|
||||
|
||||
@@ -75,6 +68,6 @@ const ConnectTabContentNew = forwardRef<HTMLDivElement, ConnectContentTabProps>(
|
||||
}
|
||||
)
|
||||
|
||||
ConnectTabContentNew.displayName = 'ConnectTabContentNew'
|
||||
ConnectTabContent.displayName = 'ConnectTabContent'
|
||||
|
||||
export default ConnectTabContentNew
|
||||
export default ConnectTabContent
|
||||
@@ -1,13 +1,13 @@
|
||||
import { useParams } from 'common'
|
||||
import { AlertTriangle, ExternalLink } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import { useState } from 'react'
|
||||
|
||||
import { useOrgSubscriptionQuery } from 'data/subscriptions/org-subscription-query'
|
||||
import { useResourceWarningsQuery } from 'data/usage/resource-warnings-query'
|
||||
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
|
||||
import { useState } from 'react'
|
||||
import { AlertDescription_Shadcn_, AlertTitle_Shadcn_, Alert_Shadcn_, Button } from 'ui'
|
||||
import ConfirmDisableReadOnlyModeModal from './DatabaseSettings/ConfirmDisableReadOnlyModal'
|
||||
import { AlertTriangle, ExternalLink } from 'lucide-react'
|
||||
|
||||
export const DatabaseReadOnlyAlert = () => {
|
||||
const { ref: projectRef } = useParams()
|
||||
|
||||
-327
@@ -1,327 +0,0 @@
|
||||
import { ChevronDown } from 'lucide-react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import { getAddons } from 'components/interfaces/Billing/Subscription/Subscription.utils'
|
||||
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
|
||||
import AlertError from 'components/ui/AlertError'
|
||||
import DatabaseSelector from 'components/ui/DatabaseSelector'
|
||||
import { DocsButton } from 'components/ui/DocsButton'
|
||||
import Panel from 'components/ui/Panel'
|
||||
import ShimmeringLoader from 'components/ui/ShimmeringLoader'
|
||||
import { usePoolingConfigurationQuery } from 'data/database/pooling-configuration-query'
|
||||
import { useReadReplicasQuery } from 'data/read-replicas/replicas-query'
|
||||
import { useProjectAddonsQuery } from 'data/subscriptions/project-addons-query'
|
||||
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
|
||||
import { useSelectedProject } from 'hooks/misc/useSelectedProject'
|
||||
import { pluckObjectFields } from 'lib/helpers'
|
||||
import { useDatabaseSelectorStateSnapshot } from 'state/database-selector'
|
||||
import { useDatabaseSettingsStateSnapshot } from 'state/database-settings'
|
||||
import {
|
||||
CollapsibleContent_Shadcn_,
|
||||
CollapsibleTrigger_Shadcn_,
|
||||
Collapsible_Shadcn_,
|
||||
Input,
|
||||
Separator,
|
||||
Tabs,
|
||||
TooltipContent_Shadcn_,
|
||||
TooltipTrigger_Shadcn_,
|
||||
Tooltip_Shadcn_,
|
||||
cn,
|
||||
} from 'ui'
|
||||
import {
|
||||
DefaultSessionModeNotice,
|
||||
IPv4AddonDirectConnectionNotice,
|
||||
IPv4DeprecationNotice,
|
||||
} from '../DatabaseConnectionNotices'
|
||||
import { UsePoolerCheckbox } from '../UsePoolerCheckbox'
|
||||
import {
|
||||
constructConnStringSyntax,
|
||||
getConnectionStrings,
|
||||
getPoolerTld,
|
||||
} from './DatabaseSettings.utils'
|
||||
import { TelemetryActions } from 'lib/constants/telemetry'
|
||||
|
||||
const CONNECTION_TYPES = [
|
||||
{ id: 'uri', label: 'URI' },
|
||||
{ id: 'psql', label: 'PSQL' },
|
||||
{ id: 'golang', label: 'Golang' },
|
||||
{ id: 'jdbc', label: 'JDBC' },
|
||||
{ id: 'dotnet', label: '.NET' },
|
||||
{ id: 'nodejs', label: 'Node.js' },
|
||||
{ id: 'php', label: 'PHP' },
|
||||
{ id: 'python', label: 'Python' },
|
||||
]
|
||||
|
||||
interface DatabaseConnectionStringProps {
|
||||
appearance: 'default' | 'minimal'
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Will be removed once `connectDialogUpdate` flag is persisted
|
||||
*/
|
||||
export const DatabaseConnectionString = ({ appearance }: DatabaseConnectionStringProps) => {
|
||||
const project = useSelectedProject()
|
||||
const { ref: projectRef, connectionString } = useParams()
|
||||
const snap = useDatabaseSettingsStateSnapshot()
|
||||
const state = useDatabaseSelectorStateSnapshot()
|
||||
const { project: projectDetails, isLoading: isProjectLoading } = useProjectContext()
|
||||
|
||||
const connectionStringsRef = useRef<HTMLDivElement>(null)
|
||||
const [poolingMode, setPoolingMode] = useState<'transaction' | 'session'>('transaction')
|
||||
const [selectedTab, setSelectedTab] = useState<
|
||||
'uri' | 'psql' | 'golang' | 'jdbc' | 'dotnet' | 'nodejs' | 'php' | 'python'
|
||||
>('uri')
|
||||
|
||||
const { data: poolingInfo, isSuccess: isSuccessPoolingInfo } = usePoolingConfigurationQuery({
|
||||
projectRef,
|
||||
})
|
||||
const poolingConfiguration = poolingInfo?.find((x) => x.identifier === state.selectedDatabaseId)
|
||||
const defaultPoolingMode = poolingConfiguration?.pool_mode
|
||||
|
||||
const {
|
||||
data: databases,
|
||||
error: readReplicasError,
|
||||
isLoading: isLoadingReadReplicas,
|
||||
isError: isErrorReadReplicas,
|
||||
isSuccess: isSuccessReadReplicas,
|
||||
} = useReadReplicasQuery({ projectRef })
|
||||
|
||||
const selectedDatabase = (databases ?? []).find(
|
||||
(db) => db.identifier === state.selectedDatabaseId
|
||||
)
|
||||
|
||||
const { data: addons, isSuccess: isSuccessAddons } = useProjectAddonsQuery({ projectRef })
|
||||
const { ipv4: ipv4Addon } = getAddons(addons?.selected_addons ?? [])
|
||||
|
||||
const { mutate: sendEvent } = useSendEventMutation()
|
||||
|
||||
const DB_FIELDS = ['db_host', 'db_name', 'db_port', 'db_user', 'inserted_at']
|
||||
const emptyState = { db_user: '', db_host: '', db_port: '', db_name: '' }
|
||||
const connectionInfo = pluckObjectFields(selectedDatabase || emptyState, DB_FIELDS)
|
||||
const connectionTld =
|
||||
projectDetails?.restUrl !== undefined
|
||||
? new URL(projectDetails?.restUrl ?? '').hostname.split('.').pop() ?? 'co'
|
||||
: 'co'
|
||||
|
||||
const handleCopy = (id: string) => {
|
||||
const connectionType = CONNECTION_TYPES.find((type) => type.id === id)?.label
|
||||
sendEvent({ action: TelemetryActions.CONNECTION_STRING_COPIED, properties: { connectionType } })
|
||||
}
|
||||
|
||||
const connectionStrings =
|
||||
isSuccessPoolingInfo && poolingConfiguration !== undefined
|
||||
? getConnectionStrings(connectionInfo, poolingConfiguration, {
|
||||
projectRef,
|
||||
usePoolerConnection: snap.usePoolerConnection,
|
||||
})
|
||||
: { uri: '', psql: '', golang: '', jdbc: '', dotnet: '', nodejs: '', php: '', python: '' }
|
||||
const poolerTld =
|
||||
isSuccessPoolingInfo && poolingConfiguration !== undefined
|
||||
? getPoolerTld(poolingConfiguration?.connectionString)
|
||||
: 'com'
|
||||
const poolerConnStringSyntax =
|
||||
isSuccessPoolingInfo && poolingConfiguration !== undefined
|
||||
? constructConnStringSyntax(poolingConfiguration?.connectionString, {
|
||||
selectedTab,
|
||||
usePoolerConnection: snap.usePoolerConnection,
|
||||
ref: projectRef as string,
|
||||
cloudProvider: isProjectLoading ? '' : project?.cloud_provider || '',
|
||||
region: isProjectLoading ? '' : project?.region || '',
|
||||
tld: snap.usePoolerConnection ? poolerTld : connectionTld,
|
||||
portNumber: snap.usePoolerConnection
|
||||
? poolingMode === 'transaction'
|
||||
? poolingConfiguration?.db_port.toString()
|
||||
: '5432'
|
||||
: connectionInfo.db_port.toString(),
|
||||
})
|
||||
: []
|
||||
|
||||
useEffect(() => {
|
||||
if (connectionString !== undefined && connectionStringsRef.current !== undefined) {
|
||||
state.setSelectedDatabaseId(connectionString)
|
||||
connectionStringsRef.current?.scrollIntoView({ block: 'center', behavior: 'smooth' })
|
||||
}
|
||||
}, [connectionString])
|
||||
|
||||
useEffect(() => {
|
||||
if (poolingConfiguration?.pool_mode === 'session') {
|
||||
setPoolingMode(poolingConfiguration.pool_mode)
|
||||
}
|
||||
}, [poolingConfiguration?.pool_mode])
|
||||
|
||||
return (
|
||||
<div id="connection-string" className="w-full">
|
||||
<Panel
|
||||
className={cn(
|
||||
'!m-0 [&>div:nth-child(1)]:!border-0 [&>div:nth-child(1)]:!p-0',
|
||||
appearance === 'minimal' && 'border-0 shadow-none bg-transparent'
|
||||
)}
|
||||
titleClasses={cn(appearance === 'minimal' && 'bg-transparent')}
|
||||
title={
|
||||
<div
|
||||
ref={connectionStringsRef}
|
||||
className={cn('w-full flex flex-col', appearance === 'default' ? 'pt-4' : 'pt-0')}
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
'flex items-center justify-between mb-2',
|
||||
appearance === 'default' && 'px-6'
|
||||
)}
|
||||
>
|
||||
{appearance === 'default' && (
|
||||
<h5 key="panel-title" className="mb-0">
|
||||
Connection string
|
||||
</h5>
|
||||
)}
|
||||
<div
|
||||
className={cn(
|
||||
'flex items-center gap-x-2 ml-auto',
|
||||
appearance === 'minimal' ? 'absolute -top-1 right-0' : ''
|
||||
)}
|
||||
>
|
||||
<DatabaseSelector />
|
||||
<DocsButton href="https://supabase.com/docs/guides/database/connecting-to-postgres" />
|
||||
</div>
|
||||
</div>
|
||||
<Tabs
|
||||
type="underlined"
|
||||
size="tiny"
|
||||
activeId={selectedTab}
|
||||
baseClassNames={cn(
|
||||
'!space-y-0 px-6 -mb-[1px]',
|
||||
appearance === 'minimal' && '-mt-1 px-0'
|
||||
)}
|
||||
onChange={setSelectedTab}
|
||||
>
|
||||
{CONNECTION_TYPES.map((type) => (
|
||||
<Tabs.Panel key={type.id} id={type.id} label={type.label} />
|
||||
))}
|
||||
</Tabs>
|
||||
<Separator />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Panel.Content className={appearance === 'minimal' && 'px-0'}>
|
||||
{isLoadingReadReplicas && <ShimmeringLoader className="h-8 w-full" />}
|
||||
{isErrorReadReplicas && (
|
||||
<AlertError error={readReplicasError} subject="Failed to retrieve database settings" />
|
||||
)}
|
||||
{isSuccessReadReplicas && (
|
||||
<div className="flex flex-col gap-y-4 pt-2">
|
||||
<UsePoolerCheckbox
|
||||
id="connection-string"
|
||||
checked={snap.usePoolerConnection}
|
||||
poolingMode={poolingMode}
|
||||
ipv4AddonAdded={!!ipv4Addon}
|
||||
onCheckedChange={snap.setUsePoolerConnection}
|
||||
onSelectPoolingMode={setPoolingMode}
|
||||
/>
|
||||
{defaultPoolingMode === 'session' && poolingMode === 'transaction' && (
|
||||
<DefaultSessionModeNotice />
|
||||
)}
|
||||
{isSuccessAddons &&
|
||||
poolingMode === 'session' &&
|
||||
ipv4Addon !== undefined &&
|
||||
snap.usePoolerConnection && <IPv4AddonDirectConnectionNotice />}
|
||||
{ipv4Addon === undefined && !snap.usePoolerConnection && <IPv4DeprecationNotice />}
|
||||
<Input
|
||||
copy
|
||||
readOnly
|
||||
disabled
|
||||
className="input-mono [&>div>div>div>input]:text-xs [&>div>div>div>input]:opacity-100"
|
||||
value={
|
||||
poolingMode === 'transaction'
|
||||
? connectionStrings[selectedTab]
|
||||
: connectionStrings[selectedTab].replace('6543', '5432')
|
||||
}
|
||||
onCopy={() => handleCopy(selectedTab)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</Panel.Content>
|
||||
{poolerConnStringSyntax.length > 0 && (
|
||||
<>
|
||||
<Separator />
|
||||
<Panel.Content className={cn('!py-3 space-y-2', appearance === 'minimal' && 'px-0')}>
|
||||
<Collapsible_Shadcn_>
|
||||
<CollapsibleTrigger_Shadcn_ className="group [&[data-state=open]>div>svg]:!-rotate-180">
|
||||
<div className="flex items-center gap-x-2 w-full">
|
||||
<p className="text-xs text-foreground-light group-hover:text-foreground transition">
|
||||
How to connect to a different database or switch to another user
|
||||
</p>
|
||||
<ChevronDown
|
||||
className="transition-transform duration-200"
|
||||
strokeWidth={1.5}
|
||||
size={14}
|
||||
/>
|
||||
</div>
|
||||
</CollapsibleTrigger_Shadcn_>
|
||||
<CollapsibleContent_Shadcn_ className="my-2">
|
||||
<div className="text-foreground-light">
|
||||
<p className="text-xs">
|
||||
You can use the following URI format to switch to a different database or user
|
||||
{snap.usePoolerConnection ? ' when using connection pooling' : ''}.
|
||||
</p>
|
||||
<p className="text-sm tracking-tight text-foreground-lighter">
|
||||
{poolerConnStringSyntax.map((x, idx) => {
|
||||
if (x.tooltip) {
|
||||
return (
|
||||
<Tooltip_Shadcn_ key={`syntax-${idx}`}>
|
||||
<TooltipTrigger_Shadcn_ asChild>
|
||||
<span className="text-foreground text-xs font-mono">{x.value}</span>
|
||||
</TooltipTrigger_Shadcn_>
|
||||
<TooltipContent_Shadcn_ side="bottom">
|
||||
{x.tooltip}
|
||||
</TooltipContent_Shadcn_>
|
||||
</Tooltip_Shadcn_>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<span key={`syntax-${idx}`} className="text-xs font-mono">
|
||||
{x.value}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
</CollapsibleContent_Shadcn_>
|
||||
</Collapsible_Shadcn_>
|
||||
|
||||
{selectedTab === 'python' && (
|
||||
<Collapsible_Shadcn_>
|
||||
<CollapsibleTrigger_Shadcn_ className="group [&[data-state=open]>div>svg]:!-rotate-180">
|
||||
<div className="flex items-center gap-x-2 w-full">
|
||||
<p className="text-xs text-foreground-light group-hover:text-foreground transition">
|
||||
Connecting to SQL Alchemy
|
||||
</p>
|
||||
<ChevronDown
|
||||
className="transition-transform duration-200"
|
||||
strokeWidth={1.5}
|
||||
size={14}
|
||||
/>
|
||||
</div>
|
||||
</CollapsibleTrigger_Shadcn_>
|
||||
<CollapsibleContent_Shadcn_ className="my-2">
|
||||
<div className="text-foreground-light text-xs grid gap-2">
|
||||
<p>
|
||||
Please use <code>postgresql://</code> instead of <code>postgres://</code> as
|
||||
your dialect when connecting via SQLAlchemy.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
<code>create_engine("postgresql+psycopg2://...")</code>
|
||||
</p>
|
||||
<p className="text-sm font-mono tracking-tight text-foreground-lighter"></p>
|
||||
</div>
|
||||
</CollapsibleContent_Shadcn_>
|
||||
</Collapsible_Shadcn_>
|
||||
)}
|
||||
</Panel.Content>
|
||||
</>
|
||||
)}
|
||||
</Panel>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
-223
@@ -1,223 +0,0 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import { getAddons } from 'components/interfaces/Billing/Subscription/Subscription.utils'
|
||||
import AlertError from 'components/ui/AlertError'
|
||||
import DatabaseSelector from 'components/ui/DatabaseSelector'
|
||||
import Panel from 'components/ui/Panel'
|
||||
import ShimmeringLoader from 'components/ui/ShimmeringLoader'
|
||||
import { usePoolingConfigurationQuery } from 'data/database/pooling-configuration-query'
|
||||
import { useReadReplicasQuery } from 'data/read-replicas/replicas-query'
|
||||
import { useProjectAddonsQuery } from 'data/subscriptions/project-addons-query'
|
||||
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
|
||||
import { pluckObjectFields } from 'lib/helpers'
|
||||
import { useDatabaseSelectorStateSnapshot } from 'state/database-selector'
|
||||
import { useDatabaseSettingsStateSnapshot } from 'state/database-settings'
|
||||
import { AlertDescription_Shadcn_, AlertTitle_Shadcn_, Alert_Shadcn_, Input, WarningIcon } from 'ui'
|
||||
import {
|
||||
DefaultSessionModeNotice,
|
||||
IPv4AddonDirectConnectionNotice,
|
||||
IPv4DeprecationNotice,
|
||||
} from '../DatabaseConnectionNotices'
|
||||
import { UsePoolerCheckbox } from '../UsePoolerCheckbox'
|
||||
|
||||
/**O
|
||||
* @deprecated Will be removed once `connectDialogUpdate` flag is persisted
|
||||
*/
|
||||
const DatabaseSettings = () => {
|
||||
const { ref: projectRef, connectionString } = useParams()
|
||||
const snap = useDatabaseSettingsStateSnapshot()
|
||||
const state = useDatabaseSelectorStateSnapshot()
|
||||
|
||||
const connectionStringsRef = useRef<HTMLDivElement>(null)
|
||||
const [poolingMode, setPoolingMode] = useState<'transaction' | 'session'>('transaction')
|
||||
|
||||
const {
|
||||
data: poolingInfo,
|
||||
error: poolingInfoError,
|
||||
isLoading: isLoadingPoolingInfo,
|
||||
isError: isErrorPoolingInfo,
|
||||
isSuccess: isSuccessPoolingInfo,
|
||||
} = usePoolingConfigurationQuery({
|
||||
projectRef,
|
||||
})
|
||||
const {
|
||||
data: databases,
|
||||
error: readReplicasError,
|
||||
isLoading: isLoadingReadReplicas,
|
||||
isError: isErrorReadReplicas,
|
||||
isSuccess: isSuccessReadReplicas,
|
||||
} = useReadReplicasQuery({ projectRef })
|
||||
const {
|
||||
data: addons,
|
||||
error: addOnsError,
|
||||
isLoading: isLoadingAddons,
|
||||
isError: isErrorAddons,
|
||||
isSuccess: isSuccessAddons,
|
||||
} = useProjectAddonsQuery({ projectRef })
|
||||
const { mutate: sendEvent } = useSendEventMutation()
|
||||
|
||||
const error = readReplicasError || poolingInfoError || addOnsError
|
||||
const isLoading = isLoadingReadReplicas || isLoadingPoolingInfo || isLoadingAddons
|
||||
const isError = isErrorReadReplicas || isErrorPoolingInfo || isErrorAddons
|
||||
const isSuccess = isSuccessReadReplicas && isSuccessPoolingInfo && isSuccessAddons
|
||||
|
||||
const selectedDatabase = (databases ?? []).find(
|
||||
(db) => db.identifier === state.selectedDatabaseId
|
||||
)
|
||||
const primaryConfig = poolingInfo?.find((x) => x.identifier === state.selectedDatabaseId)
|
||||
const defaultPoolingMode = primaryConfig?.pool_mode
|
||||
const { ipv4: ipv4Addon } = getAddons(addons?.selected_addons ?? [])
|
||||
const isMd5 = primaryConfig?.connectionString.includes('?options=reference')
|
||||
|
||||
const DB_FIELDS = ['db_host', 'db_name', 'db_port', 'db_user']
|
||||
const emptyState = { db_user: '', db_host: '', db_port: '', db_name: '' }
|
||||
const dbConnectionInfo = pluckObjectFields(selectedDatabase || emptyState, DB_FIELDS)
|
||||
|
||||
const connectionInfo = snap.usePoolerConnection
|
||||
? {
|
||||
db_host: primaryConfig?.db_host,
|
||||
db_name: primaryConfig?.db_name,
|
||||
db_port: primaryConfig?.db_port,
|
||||
db_user: primaryConfig?.db_user,
|
||||
}
|
||||
: dbConnectionInfo
|
||||
|
||||
useEffect(() => {
|
||||
if (connectionString !== undefined && connectionStringsRef.current !== undefined) {
|
||||
state.setSelectedDatabaseId(connectionString)
|
||||
connectionStringsRef.current?.scrollIntoView({ block: 'center', behavior: 'smooth' })
|
||||
}
|
||||
}, [connectionString])
|
||||
|
||||
useEffect(() => {
|
||||
if (primaryConfig?.pool_mode === 'session') {
|
||||
setPoolingMode(primaryConfig.pool_mode)
|
||||
}
|
||||
}, [primaryConfig?.pool_mode])
|
||||
|
||||
return (
|
||||
<section id="direct-connection">
|
||||
<Panel
|
||||
className="!m-0"
|
||||
title={
|
||||
<div className="w-full flex items-center justify-between">
|
||||
<div className="flex items-center gap-x-2">
|
||||
<h5 className="mb-0">Connection parameters</h5>
|
||||
</div>
|
||||
<DatabaseSelector />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Panel.Content className="space-y-6">
|
||||
{isLoading &&
|
||||
Array.from({ length: 5 }).map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="grid gap-2 items-center md:grid md:grid-cols-12 md:gap-x-4 w-full"
|
||||
>
|
||||
<ShimmeringLoader className="h-4 w-1/3 col-span-4" delayIndex={i} />
|
||||
<ShimmeringLoader className="h-8 w-full col-span-8" delayIndex={i} />
|
||||
</div>
|
||||
))}
|
||||
{isError && <AlertError error={error} subject="Failed to retrieve databases" />}
|
||||
{isSuccess && (
|
||||
<>
|
||||
<div className="space-y-4">
|
||||
<UsePoolerCheckbox
|
||||
id="connection-params"
|
||||
checked={snap.usePoolerConnection}
|
||||
ipv4AddonAdded={!!ipv4Addon}
|
||||
poolingMode={poolingMode}
|
||||
onCheckedChange={snap.setUsePoolerConnection}
|
||||
onSelectPoolingMode={setPoolingMode}
|
||||
/>
|
||||
{defaultPoolingMode === 'session' && poolingMode === 'transaction' && (
|
||||
<DefaultSessionModeNotice />
|
||||
)}
|
||||
{ipv4Addon !== undefined &&
|
||||
poolingMode === 'session' &&
|
||||
snap.usePoolerConnection && <IPv4AddonDirectConnectionNotice />}
|
||||
{ipv4Addon === undefined && !snap.usePoolerConnection && <IPv4DeprecationNotice />}
|
||||
{isMd5 && (
|
||||
<Alert_Shadcn_>
|
||||
<WarningIcon />
|
||||
<AlertTitle_Shadcn_>
|
||||
If you are connecting to your database via a GUI client, use the{' '}
|
||||
<span tabIndex={0}>connection string</span> above instead
|
||||
</AlertTitle_Shadcn_>
|
||||
<AlertDescription_Shadcn_>
|
||||
GUI clients only support database connections for Postgres 13 via a connection
|
||||
string.
|
||||
</AlertDescription_Shadcn_>
|
||||
</Alert_Shadcn_>
|
||||
)}
|
||||
</div>
|
||||
<Input
|
||||
className="input-mono"
|
||||
layout="horizontal"
|
||||
readOnly
|
||||
copy
|
||||
disabled
|
||||
value={connectionInfo.db_host}
|
||||
label="Host"
|
||||
/>
|
||||
<Input
|
||||
className="input-mono"
|
||||
layout="horizontal"
|
||||
readOnly
|
||||
copy
|
||||
disabled
|
||||
value={connectionInfo.db_name}
|
||||
label="Database name"
|
||||
/>
|
||||
<Input
|
||||
className="input-mono"
|
||||
layout="horizontal"
|
||||
readOnly
|
||||
copy
|
||||
disabled
|
||||
value={poolingMode === 'transaction' ? connectionInfo.db_port : '5432'}
|
||||
label="Port"
|
||||
/>
|
||||
{isMd5 && snap.usePoolerConnection && (
|
||||
<Input
|
||||
className="input-mono"
|
||||
layout="horizontal"
|
||||
readOnly
|
||||
copy
|
||||
disabled
|
||||
value={`reference=${projectRef}`}
|
||||
label="Options"
|
||||
/>
|
||||
)}
|
||||
<Input
|
||||
layout="horizontal"
|
||||
className="input-mono table-input-cell text-base"
|
||||
readOnly
|
||||
copy
|
||||
disabled
|
||||
value={connectionInfo.db_user}
|
||||
label="User"
|
||||
/>
|
||||
<Input
|
||||
className="input-mono"
|
||||
layout="horizontal"
|
||||
disabled
|
||||
readOnly
|
||||
value={
|
||||
state.selectedDatabaseId !== projectRef
|
||||
? '[The password for your primary database]'
|
||||
: '[The password for your database]'
|
||||
}
|
||||
label="Password"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Panel.Content>
|
||||
</Panel>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
export default DatabaseSettings
|
||||
-310
@@ -1,310 +0,0 @@
|
||||
import type { PoolingConfiguration } from 'data/database/pooling-configuration-query'
|
||||
|
||||
export const getConnectionStrings = (
|
||||
connectionInfo: {
|
||||
db_user: string
|
||||
db_port: number
|
||||
db_host: string
|
||||
db_name: string
|
||||
},
|
||||
poolingInfo: PoolingConfiguration,
|
||||
metadata: {
|
||||
usePoolerConnection: boolean
|
||||
projectRef?: string
|
||||
pgVersion?: string
|
||||
}
|
||||
) => {
|
||||
const isMd5 = poolingInfo.connectionString.includes('options=reference')
|
||||
const { usePoolerConnection, projectRef } = metadata
|
||||
|
||||
const user = usePoolerConnection ? poolingInfo.db_user : connectionInfo.db_user
|
||||
const port = usePoolerConnection ? poolingInfo?.db_port : connectionInfo.db_port
|
||||
const host = usePoolerConnection ? poolingInfo.db_host : connectionInfo.db_host
|
||||
const name = usePoolerConnection ? poolingInfo?.db_name : connectionInfo.db_name
|
||||
const password = '[YOUR-PASSWORD]'
|
||||
const showOptions = usePoolerConnection && isMd5
|
||||
|
||||
const uriConnString = usePoolerConnection
|
||||
? poolingInfo?.connectionString
|
||||
: `postgresql://${user}:${password}@` + `${host}:${port}` + `/${name}`
|
||||
const golangConnString = `user=${user} password=${password} host=${host} port=${port} dbname=${name}${showOptions ? ` options=reference=${projectRef}` : ''}`
|
||||
const psqlConnString = isMd5
|
||||
? `psql "postgresql://${user}:${password}@${host}:${port}/${name}${usePoolerConnection ? `?options=reference%3D${projectRef}` : ''}"`
|
||||
: `psql -h ${host} -p ` + `${port} -d ${name} ` + `-U ${user}`
|
||||
const jdbcConnString = `jdbc:postgresql://${host}:${port}/${name}?user=${user}&password=${password}${showOptions ? `&options=reference%3D${projectRef}` : ''}`
|
||||
const dotNetConnString = `User Id=${user};Password=${password};Server=${host};Port=${port};Database=${name};${showOptions ? `Options='reference=${projectRef}'` : ''}`
|
||||
|
||||
return {
|
||||
psql: psqlConnString,
|
||||
uri: uriConnString,
|
||||
golang: golangConnString,
|
||||
jdbc: jdbcConnString,
|
||||
dotnet: dotNetConnString,
|
||||
nodejs: uriConnString,
|
||||
php: golangConnString,
|
||||
python: golangConnString,
|
||||
}
|
||||
}
|
||||
|
||||
const DB_USER_DESC = 'Database user (e.g postgres)'
|
||||
const DB_PASS_DESC = 'Database password'
|
||||
const DB_NAME_DESC = 'Database name (e.g postgres)'
|
||||
const PROJECT_REF_DESC = "Project's reference ID"
|
||||
const PORT_NUMBER_DESC = 'Port number (Use 5432 if using prepared statements)'
|
||||
|
||||
// [Joshen] This is to the best of interpreting the syntax from the API response
|
||||
// // There's different format for PG13 (depending on authentication method being md5) and PG14
|
||||
export const constructConnStringSyntax = (
|
||||
connString: string,
|
||||
{
|
||||
selectedTab,
|
||||
usePoolerConnection,
|
||||
ref,
|
||||
cloudProvider,
|
||||
region,
|
||||
tld,
|
||||
portNumber,
|
||||
}: {
|
||||
selectedTab: 'uri' | 'psql' | 'golang' | 'jdbc' | 'dotnet' | 'nodejs' | 'php' | 'python'
|
||||
usePoolerConnection: boolean
|
||||
ref: string
|
||||
cloudProvider: string
|
||||
region: string
|
||||
tld: string
|
||||
portNumber: string
|
||||
}
|
||||
) => {
|
||||
const isMd5 = connString.includes('options=reference')
|
||||
const poolerHostDetails = [
|
||||
{ value: cloudProvider.toLocaleLowerCase(), tooltip: 'Cloud provider' },
|
||||
{ value: '-0-', tooltip: undefined },
|
||||
{ value: region, tooltip: "Project's region" },
|
||||
{ value: `.pooler.supabase.${tld}`, tooltip: undefined },
|
||||
]
|
||||
const dbHostDetails = [
|
||||
{ value: 'db.', tooltip: undefined },
|
||||
{ value: ref, tooltip: PROJECT_REF_DESC },
|
||||
{ value: `.supabase.${tld}`, tooltip: undefined },
|
||||
]
|
||||
|
||||
if (selectedTab === 'uri' || selectedTab === 'nodejs') {
|
||||
if (isMd5) {
|
||||
return [
|
||||
{ value: 'postgresql://', tooltip: undefined },
|
||||
{ value: '[user]', tooltip: DB_USER_DESC },
|
||||
{ value: ':', tooltip: undefined },
|
||||
{ value: '[password]', tooltip: DB_PASS_DESC },
|
||||
{ value: '@', tooltip: undefined },
|
||||
...(usePoolerConnection ? poolerHostDetails : dbHostDetails),
|
||||
{ value: ':', tooltip: undefined },
|
||||
{ value: portNumber, tooltip: PORT_NUMBER_DESC },
|
||||
{ value: '/', tooltip: undefined },
|
||||
{ value: '[db-name]', tooltip: DB_NAME_DESC },
|
||||
...(usePoolerConnection
|
||||
? [
|
||||
{ value: `?options=reference%3D`, tooltip: undefined },
|
||||
{ value: ref, tooltip: PROJECT_REF_DESC },
|
||||
]
|
||||
: []),
|
||||
]
|
||||
} else {
|
||||
return [
|
||||
{ value: 'postgresql://', tooltip: undefined },
|
||||
{ value: '[user]', tooltip: DB_USER_DESC },
|
||||
...(usePoolerConnection
|
||||
? [
|
||||
{ value: '.', tooltip: undefined },
|
||||
{ value: ref, tooltip: PROJECT_REF_DESC },
|
||||
]
|
||||
: []),
|
||||
{ value: ':', tooltip: undefined },
|
||||
{ value: '[password]', tooltip: DB_PASS_DESC },
|
||||
{ value: '@', tooltip: undefined },
|
||||
...(usePoolerConnection ? poolerHostDetails : dbHostDetails),
|
||||
{ value: ':', tooltip: undefined },
|
||||
{ value: portNumber, tooltip: PORT_NUMBER_DESC },
|
||||
{ value: '/', tooltip: undefined },
|
||||
{ value: '[db-name]', tooltip: DB_NAME_DESC },
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedTab === 'psql') {
|
||||
if (isMd5) {
|
||||
return [
|
||||
{ value: 'psql "postgresql://', tooltip: undefined },
|
||||
{ value: '[user]', tooltip: DB_USER_DESC },
|
||||
{ value: ':', tooltip: undefined },
|
||||
{ value: '[password]', tooltip: DB_PASS_DESC },
|
||||
{ value: '@', tooltip: undefined },
|
||||
...(usePoolerConnection ? poolerHostDetails : dbHostDetails),
|
||||
{ value: ':', tooltip: undefined },
|
||||
{ value: portNumber, tooltip: PORT_NUMBER_DESC },
|
||||
{ value: '/', tooltip: undefined },
|
||||
{ value: '[db-name]', tooltip: DB_NAME_DESC },
|
||||
...(usePoolerConnection
|
||||
? [
|
||||
{ value: '?options=reference%3D', tooltip: undefined },
|
||||
{ value: ref, tooltip: PROJECT_REF_DESC },
|
||||
]
|
||||
: []),
|
||||
]
|
||||
} else {
|
||||
return [
|
||||
{ value: 'psql -h ', tooltip: undefined },
|
||||
...(usePoolerConnection ? poolerHostDetails : dbHostDetails),
|
||||
{ value: ' -p ', tooltip: undefined },
|
||||
{ value: portNumber, tooltip: PORT_NUMBER_DESC },
|
||||
{ value: ' -d ', tooltip: undefined },
|
||||
{ value: '[db-name]', tooltip: DB_NAME_DESC },
|
||||
{ value: ' -U ', tooltip: undefined },
|
||||
{ value: '[user]', tooltip: DB_USER_DESC },
|
||||
...(usePoolerConnection
|
||||
? [
|
||||
{ value: '.', tooltip: undefined },
|
||||
{ value: ref, tooltip: PROJECT_REF_DESC },
|
||||
]
|
||||
: []),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedTab === 'golang' || selectedTab === 'php' || selectedTab === 'python') {
|
||||
if (isMd5) {
|
||||
return [
|
||||
{ value: 'user=', tooltip: undefined },
|
||||
{ value: '[user]', tooltip: DB_USER_DESC },
|
||||
{ value: ' password=', tooltip: undefined },
|
||||
{ value: '[password]', tooltip: DB_PASS_DESC },
|
||||
{ value: ' host=', tooltip: undefined },
|
||||
...(usePoolerConnection ? poolerHostDetails : dbHostDetails),
|
||||
{ value: ' port=', tooltip: undefined },
|
||||
{ value: portNumber, tooltip: PORT_NUMBER_DESC },
|
||||
{ value: ' dbname=', tooltip: undefined },
|
||||
{ value: '[db-name]', tooltip: DB_NAME_DESC },
|
||||
...(usePoolerConnection
|
||||
? [
|
||||
{ value: ' options=reference=', tooltip: undefined },
|
||||
{ value: ref, tooltip: PROJECT_REF_DESC },
|
||||
]
|
||||
: []),
|
||||
]
|
||||
} else {
|
||||
return [
|
||||
{ value: 'user=', tooltip: undefined },
|
||||
{ value: '[user]', tooltip: DB_USER_DESC },
|
||||
...(usePoolerConnection
|
||||
? [
|
||||
{ value: '.', tooltip: undefined },
|
||||
{ value: ref, tooltip: PROJECT_REF_DESC },
|
||||
]
|
||||
: []),
|
||||
{ value: ' password=', tooltip: undefined },
|
||||
{ value: '[password]', tooltip: DB_PASS_DESC },
|
||||
{ value: ' host=', tooltip: undefined },
|
||||
...(usePoolerConnection ? poolerHostDetails : dbHostDetails),
|
||||
{ value: ' port=', tooltip: undefined },
|
||||
{ value: portNumber, tooltip: PORT_NUMBER_DESC },
|
||||
{ value: ' dbname=', tooltip: undefined },
|
||||
{ value: '[db-name]', tooltip: DB_NAME_DESC },
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedTab === 'jdbc') {
|
||||
if (isMd5) {
|
||||
return [
|
||||
{ value: 'jdbc:postgresql://', tooltip: undefined },
|
||||
...(usePoolerConnection ? poolerHostDetails : dbHostDetails),
|
||||
{ value: ':', tooltip: undefined },
|
||||
{ value: portNumber, tooltip: PORT_NUMBER_DESC },
|
||||
{ value: '/', tooltip: undefined },
|
||||
{ value: '[db-name]', tooltip: DB_NAME_DESC },
|
||||
{ value: '?user=', tooltip: undefined },
|
||||
{ value: '[user]', tooltip: DB_USER_DESC },
|
||||
{ value: '&password=', tooltip: undefined },
|
||||
{ value: '[password]', tooltip: DB_PASS_DESC },
|
||||
...(usePoolerConnection
|
||||
? [
|
||||
{ value: '&options=reference%3D', tooltip: undefined },
|
||||
{ value: ref, tooltip: PROJECT_REF_DESC },
|
||||
]
|
||||
: []),
|
||||
]
|
||||
} else {
|
||||
return [
|
||||
{ value: 'jdbc:postgresql://', tooltip: undefined },
|
||||
...(usePoolerConnection ? poolerHostDetails : dbHostDetails),
|
||||
{ value: `:`, tooltip: undefined },
|
||||
{ value: portNumber, tooltip: PORT_NUMBER_DESC },
|
||||
{ value: '/', tooltip: undefined },
|
||||
{ value: '[db-name]', tooltip: DB_NAME_DESC },
|
||||
{ value: '?user=', tooltip: undefined },
|
||||
{ value: '[user]', tooltip: DB_USER_DESC },
|
||||
...(usePoolerConnection
|
||||
? [
|
||||
{ value: '.', tooltip: undefined },
|
||||
{ value: ref, tooltip: PROJECT_REF_DESC },
|
||||
]
|
||||
: []),
|
||||
{ value: '&password=', tooltip: undefined },
|
||||
{ value: '[password]', tooltip: DB_PASS_DESC },
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedTab === 'dotnet') {
|
||||
if (isMd5) {
|
||||
return [
|
||||
{ value: 'User Id=', tooltip: undefined },
|
||||
{ value: '[user]', tooltip: DB_USER_DESC },
|
||||
{ value: ';Password=', tooltip: undefined },
|
||||
{ value: '[password]', tooltip: DB_PASS_DESC },
|
||||
{ value: ';Server=', tooltip: undefined },
|
||||
...(usePoolerConnection ? poolerHostDetails : dbHostDetails),
|
||||
{ value: ';Port=', tooltip: undefined },
|
||||
{ value: portNumber, tooltip: PORT_NUMBER_DESC },
|
||||
{ value: ';Database=', tooltip: undefined },
|
||||
{ value: '[db-name]', tooltip: DB_NAME_DESC },
|
||||
...(usePoolerConnection
|
||||
? [
|
||||
{ value: ";Options='reference=", tooltip: undefined },
|
||||
{ value: ref, tooltip: PROJECT_REF_DESC },
|
||||
{ value: "'", tooltip: undefined },
|
||||
]
|
||||
: []),
|
||||
]
|
||||
} else {
|
||||
return [
|
||||
{ value: 'User Id=', tooltip: undefined },
|
||||
{ value: '[user]', tooltip: DB_USER_DESC },
|
||||
...(usePoolerConnection
|
||||
? [
|
||||
{ value: '.', tooltip: undefined },
|
||||
{ value: ref, tooltip: PROJECT_REF_DESC },
|
||||
]
|
||||
: []),
|
||||
{ value: ';Password=', tooltip: undefined },
|
||||
{ value: '[password]', tooltip: DB_PASS_DESC },
|
||||
{ value: ';Server=', tooltip: undefined },
|
||||
...(usePoolerConnection ? poolerHostDetails : dbHostDetails),
|
||||
{ value: ';Port=', tooltip: undefined },
|
||||
{ value: portNumber, tooltip: PORT_NUMBER_DESC },
|
||||
{ value: ';Database=', tooltip: undefined },
|
||||
{ value: '[db-name]', tooltip: DB_NAME_DESC },
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
|
||||
export const getPoolerTld = (connString: string) => {
|
||||
try {
|
||||
const segment = connString.split('pooler.supabase.')[1]
|
||||
const tld = segment.split(':6543')[0]
|
||||
return tld
|
||||
} catch {
|
||||
return 'com'
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,2 @@
|
||||
export { ConnectionPooling } from './ConnectionPooling/ConnectionPooling'
|
||||
export { default as NetworkRestrictions } from './NetworkRestrictions/NetworkRestrictions'
|
||||
export { default as DatabaseSettings } from './DatabaseSettings/DatabaseSettings'
|
||||
@@ -1,8 +1,8 @@
|
||||
import Link from 'next/link'
|
||||
import { ReactNode, useMemo } from 'react'
|
||||
|
||||
import Connect from 'components/interfaces/Connect/Connect'
|
||||
import { useParams } from 'common'
|
||||
import Connect from 'components/interfaces/Connect/Connect'
|
||||
import AssistantButton from 'components/layouts/AppLayout/AssistantButton'
|
||||
import BranchDropdown from 'components/layouts/AppLayout/BranchDropdown'
|
||||
import EnableBranchingButton from 'components/layouts/AppLayout/EnableBranchingButton/EnableBranchingButton'
|
||||
@@ -13,7 +13,6 @@ import { useOrgSubscriptionQuery } from 'data/subscriptions/org-subscription-que
|
||||
import { useOrgUsageQuery } from 'data/usage/org-usage-query'
|
||||
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
|
||||
import { useSelectedProject } from 'hooks/misc/useSelectedProject'
|
||||
import { useFlag } from 'hooks/ui/useFlag'
|
||||
import { IS_PLATFORM } from 'lib/constants'
|
||||
import { Badge, cn } from 'ui'
|
||||
import BreadcrumbsView from './BreadcrumbsView'
|
||||
@@ -60,8 +59,6 @@ const LayoutHeader = ({
|
||||
const selectedOrganization = useSelectedOrganization()
|
||||
const isBranchingEnabled = selectedProject?.is_branch_enabled === true
|
||||
|
||||
const connectDialogUpdate = useFlag('connectDialogUpdate')
|
||||
|
||||
const { data: subscription } = useOrgSubscriptionQuery({
|
||||
orgSlug: selectedOrganization?.slug,
|
||||
})
|
||||
@@ -128,7 +125,7 @@ const LayoutHeader = ({
|
||||
</div>
|
||||
|
||||
<div className="ml-3 flex items-center gap-x-3">
|
||||
{connectDialogUpdate && <Connect />}
|
||||
<Connect />
|
||||
{!isBranchingEnabled && <EnableBranchingButton />}
|
||||
</div>
|
||||
</>
|
||||
@@ -159,4 +156,5 @@ const LayoutHeader = ({
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default LayoutHeader
|
||||
@@ -1,7 +1,6 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import Connect from 'components/interfaces/Connect/Connect'
|
||||
import { ClientLibrary, ExampleProject } from 'components/interfaces/Home'
|
||||
import { CLIENT_LIBRARIES, EXAMPLE_PROJECTS } from 'components/interfaces/Home/Home.constants'
|
||||
import ProjectUsageSection from 'components/interfaces/Home/ProjectUsageSection'
|
||||
@@ -14,7 +13,6 @@ import { InlineLink } from 'components/ui/InlineLink'
|
||||
import ProjectUpgradeFailedBanner from 'components/ui/ProjectUpgradeFailedBanner'
|
||||
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
|
||||
import { useIsOrioleDb, useSelectedProject } from 'hooks/misc/useSelectedProject'
|
||||
import { useFlag } from 'hooks/ui/useFlag'
|
||||
import { IS_PLATFORM, PROJECT_STATUS } from 'lib/constants'
|
||||
import { useAppStateSnapshot } from 'state/app-state'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
@@ -30,11 +28,8 @@ import {
|
||||
} from 'ui'
|
||||
|
||||
const Home: NextPageWithLayout = () => {
|
||||
const connectDialogUpdate = useFlag('connectDialogUpdate')
|
||||
|
||||
const organization = useSelectedOrganization()
|
||||
const project = useSelectedProject()
|
||||
|
||||
const isOrioleDb = useIsOrioleDb()
|
||||
const snap = useAppStateSnapshot()
|
||||
const { enableBranching } = useParams()
|
||||
@@ -85,9 +80,6 @@ const Home: NextPageWithLayout = () => {
|
||||
<div className="flex items-center gap-x-3">
|
||||
{project?.status === PROJECT_STATUS.ACTIVE_HEALTHY && <SecurityStatus />}
|
||||
{IS_PLATFORM && project?.status === PROJECT_STATUS.ACTIVE_HEALTHY && <ServiceStatus />}
|
||||
{IS_PLATFORM &&
|
||||
project?.status === PROJECT_STATUS.ACTIVE_HEALTHY &&
|
||||
!connectDialogUpdate && <Connect />}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import { DiskManagementPanelForm } from 'components/interfaces/DiskManagement/DiskManagementPanelForm'
|
||||
import {
|
||||
ConnectionPooling,
|
||||
DatabaseSettings,
|
||||
NetworkRestrictions,
|
||||
} from 'components/interfaces/Settings/Database'
|
||||
import { ConnectionPooling, NetworkRestrictions } from 'components/interfaces/Settings/Database'
|
||||
import BannedIPs from 'components/interfaces/Settings/Database/BannedIPs'
|
||||
import { ConnectionStringMoved } from 'components/interfaces/Settings/Database/ConnectionStringMoved'
|
||||
import { DatabaseReadOnlyAlert } from 'components/interfaces/Settings/Database/DatabaseReadOnlyAlert'
|
||||
import { DatabaseConnectionString } from 'components/interfaces/Settings/Database/DatabaseSettings/DatabaseConnectionString'
|
||||
import ResetDbPassword from 'components/interfaces/Settings/Database/DatabaseSettings/ResetDbPassword'
|
||||
import DiskSizeConfiguration from 'components/interfaces/Settings/Database/DiskSizeConfiguration'
|
||||
import { PoolingModesModal } from 'components/interfaces/Settings/Database/PoolingModesModal'
|
||||
@@ -20,7 +15,6 @@ import type { NextPageWithLayout } from 'types'
|
||||
|
||||
const ProjectSettings: NextPageWithLayout = () => {
|
||||
const diskManagementV2 = useFlag('diskManagementV2')
|
||||
const connectDialogUpdate = useFlag('connectDialogUpdate')
|
||||
const project = useSelectedProject()
|
||||
|
||||
const showNewDiskManagementUI = diskManagementV2 && project?.cloud_provider === 'AWS'
|
||||
@@ -36,14 +30,7 @@ const ProjectSettings: NextPageWithLayout = () => {
|
||||
<div className="space-y-10">
|
||||
<div className="flex flex-col gap-y-10">
|
||||
<DatabaseReadOnlyAlert />
|
||||
{connectDialogUpdate ? (
|
||||
<ConnectionStringMoved />
|
||||
) : (
|
||||
<>
|
||||
<DatabaseConnectionString appearance="default" />
|
||||
<DatabaseSettings />
|
||||
</>
|
||||
)}
|
||||
<ConnectionStringMoved />
|
||||
<ResetDbPassword />
|
||||
<ConnectionPooling />
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user