Add empty state for database connections page if preview not enabled (#48927)

## Context

Just adds an empty state for the database connections page if the
feature preview isn't enabled. Users can technically still land on the
/connections page irregardless and the docs changes
[here](https://github.com/supabase/supabase/pull/48920) references this
page too - so this just adds an empty state to allow users to enable the
feature preview

<img width="1388" height="573" alt="image"
src="https://github.com/user-attachments/assets/dfd3a0b4-11b4-42b1-b5eb-fce8c03c35e6"
/>


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

* **New Features**
  * Added a feature preview experience for Database Connections.
* Users with the preview enabled can view connection activity, live
updates, refreshed data, and related controls.
* Users without access see a preview badge, an empty state, and an
option to enable the preview.
  * The live status indicator is hidden when the preview is inactive.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Joshen Lim authored and GitHub committed 2026-08-12 10:27:14 +07:00
1 parent 7c4872ad32
commit cd906a176a
1 file changed
+68 -32
@@ -1,8 +1,14 @@
import { LOCAL_STORAGE_KEYS } from 'common'
import dayjs from 'dayjs'
import { CirclePause, CirclePlay } from 'lucide-react'
import { CirclePause, CirclePlay, TextSearch } from 'lucide-react'
import { useEffect, useState } from 'react'
import { Badge, Button, Tooltip, TooltipContent, TooltipTrigger } from 'ui'
import { EmptyStatePresentational } from 'ui-patterns/EmptyStatePresentational'
import {
useFeaturePreviewModal,
useIsDatabaseConnectionsEnabled,
} from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext'
import { Activity } from '@/components/interfaces/Observability/DatabaseConnections/Activity'
import { buildDatabaseConnectionsSummaryPrompt } from '@/components/interfaces/Observability/DatabaseConnections/DatabaseConnections.ai'
import { Overview } from '@/components/interfaces/Observability/DatabaseConnections/Overview'
@@ -11,6 +17,7 @@ import { DefaultLayout } from '@/components/layouts/DefaultLayout'
import ObservabilityLayout from '@/components/layouts/ObservabilityLayout/ObservabilityLayout'
import { SIDEBAR_KEYS } from '@/components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
import { AiAssistantDropdown } from '@/components/ui/AiAssistantDropdown'
import { FeaturePreviewBadge } from '@/components/ui/FeaturePreviewBadge'
import { ShortcutTooltip } from '@/components/ui/ShortcutTooltip'
import { useDatabaseActivityQuery } from '@/data/database/activity-query'
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
@@ -26,6 +33,8 @@ export const DatabaseConnections: NextPageWithLayout = () => {
const { data: project } = useSelectedProjectQuery()
const { openSidebar } = useSidebarManagerSnapshot()
const aiSnap = useAiAssistantStateSnapshot()
const isDatabaseConnectionsEnabled = useIsDatabaseConnectionsEnabled()
const { selectFeaturePreview } = useFeaturePreviewModal()
const [live, setLive] = useState(true)
const [now, setNow] = useState(() => dayjs.utc())
@@ -43,7 +52,11 @@ export const DatabaseConnections: NextPageWithLayout = () => {
projectRef: project?.ref,
connectionString: project?.connectionString,
},
{ refetchOnWindowFocus: live, refetchInterval: live ? 3000 : false }
{
enabled: isDatabaseConnectionsEnabled,
refetchOnWindowFocus: live,
refetchInterval: live ? 3000 : false,
}
)
function handleToggleLive() {
@@ -78,19 +91,20 @@ export const DatabaseConnections: NextPageWithLayout = () => {
// [Joshen] Just to trigger a UI re-render for the duration to be "live"
useEffect(() => {
if (!live) return
if (!live || !isDatabaseConnectionsEnabled) return
const interval = setInterval(() => setNow(dayjs.utc()), 1000)
return () => clearInterval(interval)
}, [live])
}, [live, isDatabaseConnectionsEnabled])
return (
<ReportPadding className="gap-y-12">
<div className="flex items-center justify-between gap-x-4">
<div className="flex items-center gap-x-2">
<h1 className="w-max">Database Connections</h1>
{live && (
<FeaturePreviewBadge featureKey={LOCAL_STORAGE_KEYS.UI_PREVIEW_DATABASE_CONNECTIONS} />
{isDatabaseConnectionsEnabled && live && (
<Tooltip>
<TooltipTrigger>
<TooltipTrigger className="flex items-center">
<Badge variant="success">
<span className="h-1.5 w-1.5 bg-brand rounded-full animate-pulse" />
<span>Live</span>
@@ -100,35 +114,57 @@ export const DatabaseConnections: NextPageWithLayout = () => {
</Tooltip>
)}
</div>
<div className="flex items-center gap-x-2">
<ShortcutTooltip
shortcutId={SHORTCUT_IDS.DATA_TABLE_TOGGLE_LIVE}
label={live ? 'Pause live mode' : 'Refresh data every 3 seconds'}
side="bottom"
>
<Button
variant={live ? 'default' : 'primary'}
onClick={handleToggleLive}
icon={live ? <CirclePause /> : <CirclePlay />}
{isDatabaseConnectionsEnabled && (
<div className="flex items-center gap-x-2">
<ShortcutTooltip
shortcutId={SHORTCUT_IDS.DATA_TABLE_TOGGLE_LIVE}
label={live ? 'Pause live mode' : 'Refresh data every 3 seconds'}
side="bottom"
>
{live ? 'Pause' : 'Live'}
</Button>
</ShortcutTooltip>
<AiAssistantDropdown
label="Summarize activity"
buildPrompt={buildPrompt}
onOpenAssistant={handleSummarizeActivity}
disabled={isLoadingActivity}
loading={isLoadingActivity}
telemetrySource="database_connections"
size="tiny"
variant="default"
/>
</div>
<Button
variant={live ? 'default' : 'primary'}
onClick={handleToggleLive}
icon={live ? <CirclePause /> : <CirclePlay />}
>
{live ? 'Pause' : 'Live'}
</Button>
</ShortcutTooltip>
<AiAssistantDropdown
label="Summarize activity"
buildPrompt={buildPrompt}
onOpenAssistant={handleSummarizeActivity}
disabled={isLoadingActivity}
loading={isLoadingActivity}
telemetrySource="database_connections"
size="tiny"
variant="default"
/>
</div>
)}
</div>
<Overview live={live} />
<Activity live={live} />
{!isDatabaseConnectionsEnabled && (
<EmptyStatePresentational
icon={<TextSearch />}
title="Diagnose stuck and blocked queries"
description="See every session on your database in real time, spot the ones that are slow, idle in a transaction, or blocked, and terminate the one holding things up"
>
<Button
variant="default"
onClick={() => selectFeaturePreview(LOCAL_STORAGE_KEYS.UI_PREVIEW_DATABASE_CONNECTIONS)}
>
Enable feature preview
</Button>
</EmptyStatePresentational>
)}
{isDatabaseConnectionsEnabled && (
<>
<Overview live={live} />
<Activity live={live} />
</>
)}
</ReportPadding>
)
}