Skip to content

Commit 3bc91b2

Browse files
connect dialog: add shared pooler to transaction pooler (supabase#39981)
fix shared pooler in transaction pooler + add link to docs in connect dialog
1 parent 911d646 commit 3bc91b2

File tree

5 files changed

+154
-65
lines changed

5 files changed

+154
-65
lines changed

apps/studio/components/interfaces/Connect/Connect.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ export const Connect = () => {
353353
{connectionTypes.length === 1 ? ` via ${connectionTypes[0].label.toLowerCase()}` : null}
354354
</DialogTitle>
355355
<DialogDescription>
356-
Get the connection strings and environment variables for your app
356+
Get the connection strings and environment variables for your app.
357357
</DialogDescription>
358358
</DialogHeader>
359359

apps/studio/components/interfaces/Connect/ConnectionPanel.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
Collapsible_Shadcn_,
1616
CollapsibleContent_Shadcn_,
1717
CollapsibleTrigger_Shadcn_,
18+
Separator,
1819
WarningIcon,
1920
} from 'ui'
2021
import { Admonition } from 'ui-patterns'
@@ -25,6 +26,7 @@ interface ConnectionPanelProps {
2526
badge?: string
2627
title: string
2728
description: string
29+
contentFooter?: ReactNode
2830
connectionString: string
2931
ipv4Status: {
3032
type: 'error' | 'success'
@@ -105,6 +107,7 @@ export const ConnectionPanel = ({
105107
badge,
106108
title,
107109
description,
110+
contentFooter,
108111
connectionString,
109112
ipv4Status,
110113
notice,
@@ -123,16 +126,24 @@ export const ConnectionPanel = ({
123126

124127
const links = ipv4Status.links ?? []
125128

129+
const isTransactionDedicatedPooler = type === 'transaction' && badge === 'Dedicated Pooler'
130+
126131
return (
127132
<div className="relative text-sm flex flex-col gap-5 lg:grid lg:grid-cols-12 w-full">
128133
<div className="col-span-4 flex flex-col">
129134
<div className="flex items-center gap-x-2 mb-2">
130135
<h1 className="text-sm">{title}</h1>
131-
{!!badge && <Badge>{badge}</Badge>}
136+
{!!badge && !isTransactionDedicatedPooler && <Badge>{badge}</Badge>}
132137
</div>
133138
<p className="text-sm text-foreground-light mb-4">{description}</p>
139+
{contentFooter}
134140
</div>
135141
<div className="col-span-8 flex flex-col gap-2">
142+
{isTransactionDedicatedPooler && (
143+
<div className="text-xs flex items-center text-foreground-light">
144+
Using the Dedicated Pooler:
145+
</div>
146+
)}
136147
<div className="flex flex-col -space-y-px">
137148
{fileTitle && <CodeBlockFileHeader title={fileTitle} />}
138149
{type === 'transaction' && isSessionMode ? (
@@ -177,7 +188,6 @@ export const ConnectionPanel = ({
177188
{parameters.length > 0 && <ConnectionParameters parameters={parameters} />}
178189
</>
179190
)}
180-
{children}
181191
</div>
182192
<div className="flex flex-col -space-y-px w-full">
183193
{IS_PLATFORM && (
@@ -278,6 +288,8 @@ export const ConnectionPanel = ({
278288
</Collapsible_Shadcn_>
279289
)}
280290
</div>
291+
{isTransactionDedicatedPooler && <Separator className="w-full" />}
292+
{children}
281293
</div>
282294
</div>
283295
)

apps/studio/components/interfaces/Connect/ConnectionParameters.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export const ConnectionParameters = ({ parameters }: ConnectionParametersProps)
2828
<Collapsible_Shadcn_ open={isOpen} onOpenChange={setIsOpen} className="group -space-y-px">
2929
<CollapsibleTrigger_Shadcn_
3030
asChild
31-
className="w-full justify-start rounded-t-none !last:rounded-b group-data-[state=open]:rounded-b-none border-light px-3"
31+
className="w-full justify-start rounded-t-none !last:rounded-b group-data-[state=open]:rounded-b-none data-[state=open]:border-light border-light px-3"
3232
>
3333
<Button
3434
type="default"

apps/studio/components/interfaces/Connect/DatabaseConnectionString.tsx

Lines changed: 135 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { ChevronDown, GlobeIcon, InfoIcon } from 'lucide-react'
1+
import { BookOpen, ChevronDown, ChevronRight, ExternalLink } from 'lucide-react'
22
import { parseAsString, useQueryState } from 'nuqs'
33
import { HTMLAttributes, ReactNode, useEffect, useMemo, useState } from 'react'
4+
import Link from 'next/link'
45

56
import { useParams } from 'common'
67
import { getAddons } from 'components/interfaces/Billing/Subscription/Subscription.utils'
@@ -19,6 +20,7 @@ import { pluckObjectFields } from 'lib/helpers'
1920
import { useDatabaseSelectorStateSnapshot } from 'state/database-selector'
2021
import {
2122
Badge,
23+
Button,
2224
CodeBlock,
2325
CollapsibleContent_Shadcn_,
2426
CollapsibleTrigger_Shadcn_,
@@ -30,6 +32,7 @@ import {
3032
SelectValue_Shadcn_,
3133
Select_Shadcn_,
3234
Separator,
35+
TextLink,
3336
cn,
3437
} from 'ui'
3538
import { Admonition } from 'ui-patterns'
@@ -275,55 +278,69 @@ export const DatabaseConnectionString = () => {
275278

276279
return (
277280
<div className="flex flex-col">
278-
<div
279-
className={cn(
280-
'flex flex-col md:flex-row items-stretch md:items-center gap-2 md:gap-3',
281-
DIALOG_PADDING_X
282-
)}
283-
>
284-
<div className="flex">
285-
<span className="flex items-center text-foreground-lighter px-3 rounded-lg rounded-r-none text-xs border border-button border-r-0">
286-
Type
287-
</span>
288-
<Select_Shadcn_ value={selectedTab} onValueChange={handleTabChange}>
289-
<SelectTrigger_Shadcn_ size="small" className="w-auto rounded-l-none">
290-
<SelectValue_Shadcn_ />
291-
</SelectTrigger_Shadcn_>
292-
<SelectContent_Shadcn_>
293-
{DATABASE_CONNECTION_TYPES.map((type) => (
294-
<SelectItem_Shadcn_ key={type.id} value={type.id}>
295-
{type.label}
296-
</SelectItem_Shadcn_>
297-
))}
298-
</SelectContent_Shadcn_>
299-
</Select_Shadcn_>
300-
</div>
301-
<DatabaseSelector
302-
portal={false}
303-
buttonProps={{ size: 'small' }}
304-
onSelectId={handleDatabaseChange}
305-
/>
306-
<div className="flex">
307-
<span className="flex items-center text-foreground-lighter px-3 rounded-lg rounded-r-none text-xs border border-button border-r-0">
308-
Method
309-
</span>
310-
<Select_Shadcn_ value={selectedMethod} onValueChange={handleMethodChange}>
311-
<SelectTrigger_Shadcn_ size="small" className="w-auto rounded-l-none">
312-
<SelectValue_Shadcn_ size="tiny">
313-
{connectionStringMethodOptions[selectedMethod].label}
314-
</SelectValue_Shadcn_>
315-
</SelectTrigger_Shadcn_>
316-
<SelectContent_Shadcn_ className="max-w-sm">
317-
{Object.keys(connectionStringMethodOptions).map((method) => (
318-
<ConnectionStringMethodSelectItem
319-
key={method}
320-
method={method as ConnectionStringMethod}
321-
poolerBadge={poolerBadge}
322-
/>
323-
))}
324-
</SelectContent_Shadcn_>
325-
</Select_Shadcn_>
281+
<div className={cn('w-full flex flex-col items-start gap-2 lg:gap-3', DIALOG_PADDING_X)}>
282+
<div className="flex w-full flex-col md:flex-row items-stretch md:items-center gap-2 md:gap-3">
283+
<div className="flex">
284+
<span className="w-1/2 md:w-auto flex items-center text-foreground-lighter px-3 rounded-lg rounded-r-none text-xs border border-button border-r-0">
285+
Type
286+
</span>
287+
<Select_Shadcn_ value={selectedTab} onValueChange={handleTabChange}>
288+
<SelectTrigger_Shadcn_ size="small" className="w-full md:w-auto rounded-l-none">
289+
<SelectValue_Shadcn_ />
290+
</SelectTrigger_Shadcn_>
291+
<SelectContent_Shadcn_>
292+
{DATABASE_CONNECTION_TYPES.map((type) => (
293+
<SelectItem_Shadcn_ key={type.id} value={type.id}>
294+
{type.label}
295+
</SelectItem_Shadcn_>
296+
))}
297+
</SelectContent_Shadcn_>
298+
</Select_Shadcn_>
299+
</div>
300+
<DatabaseSelector
301+
portal={false}
302+
buttonProps={{
303+
size: 'small',
304+
className: 'w-full justify-between pr-2.5 [&_svg]:h-4',
305+
}}
306+
className="w-full md:w-auto [&>span]:w-1/2 [&>span]:md:w-auto"
307+
onSelectId={handleDatabaseChange}
308+
/>
309+
<div className="flex">
310+
<span className="w-1/2 md:w-auto flex items-center text-foreground-lighter px-3 rounded-lg rounded-r-none text-xs border border-button border-r-0">
311+
Method
312+
</span>
313+
<Select_Shadcn_ value={selectedMethod} onValueChange={handleMethodChange}>
314+
<SelectTrigger_Shadcn_ size="small" className="w-full md:w-auto rounded-l-none">
315+
<SelectValue_Shadcn_ size="tiny">
316+
{connectionStringMethodOptions[selectedMethod].label}
317+
</SelectValue_Shadcn_>
318+
</SelectTrigger_Shadcn_>
319+
<SelectContent_Shadcn_ className="max-w-sm">
320+
{Object.keys(connectionStringMethodOptions).map((method) => (
321+
<ConnectionStringMethodSelectItem
322+
key={method}
323+
method={method as ConnectionStringMethod}
324+
poolerBadge={method === 'transaction' ? poolerBadge : undefined}
325+
/>
326+
))}
327+
</SelectContent_Shadcn_>
328+
</Select_Shadcn_>
329+
</div>
326330
</div>
331+
<p className="text-xs inline-flex items-center gap-1 text-foreground-lighter">
332+
<BookOpen size={12} strokeWidth={1.5} className="-mb-px" /> Learn how to connect to your
333+
Postgres databases.
334+
<Link
335+
href="https://supabase.com/docs/guides/database/connecting-to-postgres"
336+
className="underline transition hover:text-foreground inline-flex items-center gap-1"
337+
target="_blank"
338+
rel="noreferrer"
339+
title="Read docs"
340+
>
341+
Read docs <ExternalLink size={12} strokeWidth={1.5} />
342+
</Link>
343+
</p>
327344
</div>
328345

329346
{isLoading && (
@@ -458,7 +475,49 @@ export const DatabaseConnectionString = () => {
458475
{ ...CONNECTION_PARAMETERS.pool_mode, value: 'transaction' },
459476
]}
460477
onCopyCallback={() => handleCopy(selectedTab, 'transaction_pooler')}
461-
/>
478+
>
479+
{!sharedPoolerPreferred && !ipv4Addon && (
480+
<Collapsible_Shadcn_ className="group">
481+
<CollapsibleTrigger_Shadcn_
482+
asChild
483+
className="w-full justify-start !last:rounded-b group-data-[state=open]:rounded-b-none border-light px-3"
484+
>
485+
<Button
486+
type="default"
487+
size="large"
488+
iconRight={
489+
<ChevronDown className="transition group-data-[state=open]:rotate-180" />
490+
}
491+
className="text-foreground !bg-dash-sidebar justify-between"
492+
>
493+
<div className="text-xs flex items-center py-2 px-1">
494+
<span>Using the Shared Pooler</span>
495+
<Badge variant={'brand'} size={'small'} className="ml-2">
496+
IPv4 compatible
497+
</Badge>
498+
</div>
499+
</Button>
500+
</CollapsibleTrigger_Shadcn_>
501+
<CollapsibleContent_Shadcn_ className="bg-dash-sidebar rounded-b border text-xs">
502+
<CodeBlock
503+
wrapperClassName={cn(
504+
'[&_pre]:border-x-0 [&_pre]:border-t-0 [&_pre]:px-4 [&_pre]:py-3',
505+
'[&_pre]:rounded-t-none'
506+
)}
507+
language={lang}
508+
value={supavisorConnectionStrings['pooler'][selectedTab]}
509+
className="[&_code]:text-[12px] [&_code]:text-foreground"
510+
hideLineNumbers
511+
onCopyCallback={() => handleCopy(selectedTab, 'transaction_pooler')}
512+
/>
513+
<p className="px-3 py-2 text-foreground-light">
514+
Only recommended when your network does not support IPv6. Added latency
515+
compared to dedicated pooler.
516+
</p>
517+
</CollapsibleContent_Shadcn_>
518+
</Collapsible_Shadcn_>
519+
)}
520+
</ConnectionPanel>
462521
)}
463522

464523
{selectedMethod === 'session' && IS_PLATFORM && (
@@ -587,14 +646,30 @@ const ConnectionStringMethodSelectItem = ({
587646
poolerBadge,
588647
}: {
589648
method: ConnectionStringMethod
590-
poolerBadge: string
591-
}) => (
592-
<SelectItem_Shadcn_ value={method} className="[&>span:first-child]:top-3.5">
593-
<div className="flex flex-col w-full py-1">
594-
<div>{connectionStringMethodOptions[method].label}</div>
595-
<div className="text-foreground-lighter text-xs">
596-
{connectionStringMethodOptions[method].description}
649+
poolerBadge?: string
650+
}) => {
651+
const badges: ReactNode[] = []
652+
653+
if (method !== 'direct') {
654+
badges.push(<Badge className="flex gap-x-1">Shared Pooler</Badge>)
655+
}
656+
if (poolerBadge === 'Dedicated Pooler') {
657+
badges.push(<Badge className="flex gap-x-1">{poolerBadge}</Badge>)
658+
}
659+
660+
return (
661+
<SelectItem_Shadcn_ value={method} className="[&>span:first-child]:top-3.5">
662+
<div className="flex flex-col w-full py-1">
663+
<div className="flex gap-x-2 items-center">
664+
{connectionStringMethodOptions[method].label}
665+
</div>
666+
<div className="text-foreground-lighter text-xs">
667+
{connectionStringMethodOptions[method].description}
668+
</div>
669+
<div className="flex items-center gap-0.5 flex-wrap mt-1.5">
670+
{badges.map((badge) => badge)}
671+
</div>
597672
</div>
598-
</div>
599-
</SelectItem_Shadcn_>
600-
)
673+
</SelectItem_Shadcn_>
674+
)
675+
}

apps/studio/components/ui/DatabaseSelector.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ interface DatabaseSelectorProps {
3838
onSelectId?: (id: string) => void // Optional callback
3939
onCreateReplicaClick?: () => void
4040
portal?: boolean
41+
className?: string
4142
}
4243

4344
const DatabaseSelector = ({
@@ -48,6 +49,7 @@ const DatabaseSelector = ({
4849
buttonProps,
4950
onCreateReplicaClick = noop,
5051
portal = true,
52+
className,
5153
}: DatabaseSelectorProps) => {
5254
const router = useRouter()
5355
const { ref: projectRef } = useParams()
@@ -79,7 +81,7 @@ const DatabaseSelector = ({
7981
return (
8082
<Popover_Shadcn_ open={open} onOpenChange={setOpen} modal={false}>
8183
<PopoverTrigger_Shadcn_ asChild>
82-
<div className="flex cursor-pointer">
84+
<div className={cn('flex cursor-pointer', className)}>
8385
<span className="flex items-center text-foreground-lighter px-3 rounded-lg rounded-r-none text-xs border border-button border-r-0">
8486
Source
8587
</span>

0 commit comments

Comments
 (0)