Files
Danny White c856de8fda fix(studio): polish pipeline creation copy and actions (#50956)
## Problem

The current pipeline creation sheet describes destination type with two
disconnected sentences. The enablement callout repeats itself, while
three Pipelines action menus have undersized triggers.

## Solution

Use a complete destination-specific description for each release stage.
Present the Enable Pipelines callout as a note with an action title, a
short explanation, and one button. Clarify the enablement dialog copy
and align the three action-menu triggers with a consistent button width
and hit area.

| Before | After |
| --- | --- |
| <img width="1024" height="759" alt="Pipelines Database Sandals Field
Lab Supabase"
src="https://github.com/user-attachments/assets/fac744dd-2701-40ae-a65d-0801a1a86e6f"
/> | <img width="1024" height="759" alt="Pipelines Database Sandals
Field Lab Supabase"
src="https://github.com/user-attachments/assets/075bf609-5b65-40ca-8aaf-d27335d48838"
/> |
| <img width="1024" height="759" alt="18436"
src="https://github.com/user-attachments/assets/92f8c63b-f9b9-4dd6-b9b6-26ede932c172"
/> | <img width="1076" height="759" alt="93893"
src="https://github.com/user-attachments/assets/3c6f26b0-130c-4508-bf6b-d2c641805426"
/> |
| <img width="1024" height="759" alt="16935"
src="https://github.com/user-attachments/assets/63e75045-412a-4bcc-9cf9-20245ac60871"
/> | <img width="1024" height="759" alt="75021"
src="https://github.com/user-attachments/assets/09771e1e-2e89-466d-8f60-22c5bacc9956"
/> |

## Review instructions

1. Open [Database > Pipelines in the Studio
preview](https://studio-staging-git-dnywh-fixpipelines-creation-polish-supabase.vercel.app/dashboard/project/_/database/pipelines),
click **Add pipeline**, and select BigQuery or Snowflake. Confirm the
Type description reads as a complete sentence.
2. On a project where Pipelines is not enabled, open the creation sheet.
Confirm the note has no extra padding or Docs link, then click
**Enable** and check the dialog copy. The list menu's **Enable
Pipelines** action opens the same dialog.
3. Check the action-menu triggers on the Pipelines list, pipeline detail
page, and table row for consistent sizing and click targets.

## Checklist

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **User Experience**
* Replication setup now displays a loading state while access and
organization details are checked, then shows the appropriate access
request, enablement notice, or destination form.
* Access notices use clearer, responsive messaging with a primary
“Request access” link.
* Enablement messaging now reflects whether your plan includes access,
and the success notification is shorter.
* Destination-type notices now identify the selected type and clarify
that it cannot be changed after creation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-28 17:34:10 +10:00

128 lines
4.2 KiB
TypeScript

import { useParams } from 'common'
import { useState } from 'react'
import { toast } from 'sonner'
import {
Button,
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogSection,
DialogSectionSeparator,
DialogTitle,
DialogTrigger,
} from 'ui'
import { Admonition } from 'ui-patterns/Admonition'
import { DestinationType } from './DestinationPanel/DestinationPanel.types'
import { InlineLink } from '@/components/ui/InlineLink'
import { UpgradePlanButton } from '@/components/ui/UpgradePlanButton'
import { useCreateTenantSourceMutation } from '@/data/replication/create-tenant-source-mutation'
import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
import { DOCS_URL } from '@/lib/constants'
type EnablePipelinesModalProps =
| { open: boolean; onOpenChange: (open: boolean) => void }
| { open?: never; onOpenChange?: never }
export const EnablePipelinesModal = ({
open: extOpen,
onOpenChange,
}: EnablePipelinesModalProps) => {
const { ref: projectRef } = useParams()
const [_open, _setOpen] = useState(false)
const open = extOpen ?? _open
const setOpen = onOpenChange ?? _setOpen
const hideTrigger = extOpen !== undefined && onOpenChange !== undefined
const { hasAccess } = useCheckEntitlements('replication.etl')
const { mutate: createTenantSource, isPending: creatingTenantSource } =
useCreateTenantSourceMutation({
onSuccess: () => {
toast.success('Pipelines enabled')
setOpen(false)
},
onError: (error) => {
toast.error(`Failed to enable Pipelines: ${error.message}`)
},
})
const onEnablePipelines = async () => {
if (!projectRef) return console.error('Project ref is required')
createTenantSource({ projectRef })
}
return (
<Dialog open={open} onOpenChange={setOpen}>
{!hideTrigger && (
<DialogTrigger asChild>
<Button variant="primary">Enable</Button>
</DialogTrigger>
)}
<DialogContent size="small">
<DialogHeader>
<DialogTitle>Enable Pipelines</DialogTitle>
</DialogHeader>
<DialogSectionSeparator />
<DialogSection className="flex flex-col gap-y-3">
{hasAccess ? (
<>
<p className="text-sm text-foreground-light">
Pipelines bills for configured pipeline hours and Postgres row data processed during
initial sync and ongoing replication. Review{' '}
<InlineLink href={`${DOCS_URL}/guides/platform/manage-your-usage/pipelines`}>
Pipelines pricing
</InlineLink>{' '}
before enabling.
</p>
<p className="text-sm text-foreground-light">
Pipelines is in public alpha and may change.
</p>
</>
) : (
<p className="text-sm text-foreground-light">Pipelines requires the Pro plan.</p>
)}
</DialogSection>
<DialogFooter>
<Button disabled={creatingTenantSource} onClick={() => setOpen(false)}>
Cancel
</Button>
{hasAccess ? (
<Button variant="primary" loading={creatingTenantSource} onClick={onEnablePipelines}>
Enable Pipelines
</Button>
) : (
<UpgradePlanButton source="replication" featureProposition="use replication" />
)}
</DialogFooter>
</DialogContent>
</Dialog>
)
}
export const EnablePipelinesCallout = ({ type }: { type?: DestinationType | null }) => {
const { hasAccess } = useCheckEntitlements('replication.etl')
return (
<Admonition
type="note"
layout="responsive"
title={hasAccess ? 'Enable Pipelines' : 'Upgrade to Pro for Pipelines'}
description={
hasAccess
? `Pipelines must be enabled before this project can replicate database changes to ${type ?? 'external destinations'}.`
: `The Pro plan is required to replicate database changes to ${type ?? 'external destinations'} with Pipelines.`
}
actions={
hasAccess ? (
<EnablePipelinesModal />
) : (
<UpgradePlanButton source="replication" featureProposition="use replication" />
)
}
/>
)
}