mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
Joshenlim/fe 4063 set up incremental default opt in for database connections (#49132)
## Context As per PR title - sets up incremental default opt in for the Database Connections feature preview Database Connections preview banner should still only show up if it's never been dismissed before, but the CTA's changed to "Explore" rather than "Enable" if the user's default opted in Related discussion here: https://github.com/orgs/supabase/discussions/48639 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Database Connections preview is now enabled by default. * Added clearer handling for preview state and initialization. * Banner actions open Database Connections when enabled, or the feature preview when disabled. * **Bug Fixes** * Improved banner and menu visibility while preview settings initialize. * Preserved banner dismissal behavior after a previous preference change. * Improved navigation consistency across Database Connections entry points. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
1 parent
14fe0c0cc8
commit
dfb0603a36
9 files changed
+60
-28
No files matched your search
@@ -13,6 +13,7 @@ import {
|
||||
} from 'react'
|
||||
|
||||
import { useFeaturePreviews } from './useFeaturePreviews'
|
||||
import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
|
||||
import { IS_PLATFORM } from '@/lib/constants'
|
||||
import { EMPTY_OBJ } from '@/lib/void'
|
||||
|
||||
@@ -152,9 +153,18 @@ export const useIsMarketplaceEnabled = () => {
|
||||
}
|
||||
|
||||
export const useIsDatabaseConnectionsEnabled = () => {
|
||||
const { flags } = useFeaturePreviewContext()
|
||||
const isDatabaseConnectionsEnabled = useFlag('topForPostgres')
|
||||
return isDatabaseConnectionsEnabled && flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_DATABASE_CONNECTIONS]
|
||||
const { flags, isInitialized } = useFeaturePreviewContext()
|
||||
const [localStorageFlag] = useLocalStorageQuery<boolean | null>(
|
||||
LOCAL_STORAGE_KEYS.UI_PREVIEW_DATABASE_CONNECTIONS,
|
||||
null
|
||||
)
|
||||
const previouslyToggled = localStorageFlag !== null
|
||||
|
||||
return {
|
||||
enabled: flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_DATABASE_CONNECTIONS],
|
||||
isInitialized,
|
||||
previouslyToggled,
|
||||
}
|
||||
}
|
||||
|
||||
export const useFeaturePreviewModal = () => {
|
||||
|
||||
@@ -133,8 +133,8 @@ export const useFeaturePreviews = (): FeaturePreview[] => {
|
||||
discussionsUrl: 'https://github.com/orgs/supabase/discussions/48639',
|
||||
isNew: true,
|
||||
isPlatformOnly: false,
|
||||
isDefaultOptIn: false,
|
||||
enabled: isDatabaseConnectionsEnabled,
|
||||
isDefaultOptIn: isDatabaseConnectionsEnabled,
|
||||
enabled: true,
|
||||
getRoute: (ref?: string) => `/project/${ref}/observability/connections`,
|
||||
bannerId: 'database-connections-banner',
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { LOCAL_STORAGE_KEYS, useFeatureFlags, useParams } from 'common'
|
||||
import { LOCAL_STORAGE_KEYS, useParams } from 'common'
|
||||
import { usePathname } from 'next/navigation'
|
||||
import { PropsWithChildren, useEffect, useRef } from 'react'
|
||||
|
||||
@@ -24,7 +24,6 @@ const ObservabilityLayoutContent = ({
|
||||
}: PropsWithChildren<ObservabilityLayoutProps>) => {
|
||||
const { ref } = useParams()
|
||||
const pathname = usePathname()
|
||||
const { hasLoaded } = useFeatureFlags()
|
||||
const { addBanner, dismissBanner } = useBannerStack()
|
||||
const { isIndexAdvisorAvailable, isIndexAdvisorEnabled } = useIndexAdvisorStatus()
|
||||
|
||||
@@ -33,7 +32,7 @@ const ObservabilityLayoutContent = ({
|
||||
false
|
||||
)
|
||||
|
||||
const isDatabaseConnectionsEnabled = useIsDatabaseConnectionsEnabled()
|
||||
const { isInitialized, previouslyToggled } = useIsDatabaseConnectionsEnabled()
|
||||
|
||||
const [isDatabaseConnectionsBannerDismissed, , { isSuccess: isLocalStorageReady }] =
|
||||
useLocalStorageQuery(LOCAL_STORAGE_KEYS.DATABASE_CONNECTIONS_BANNER_DISMISSED(ref ?? ''), false)
|
||||
@@ -42,10 +41,10 @@ const ObservabilityLayoutContent = ({
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
!hasLoaded ||
|
||||
!isInitialized ||
|
||||
!isLocalStorageReady ||
|
||||
isDatabaseConnectionsBannerDismissed ||
|
||||
isDatabaseConnectionsEnabled
|
||||
previouslyToggled
|
||||
)
|
||||
return
|
||||
|
||||
@@ -56,11 +55,11 @@ const ObservabilityLayoutContent = ({
|
||||
content: <BannerDatabaseConnections />,
|
||||
})
|
||||
}, [
|
||||
hasLoaded,
|
||||
addBanner,
|
||||
dismissBanner,
|
||||
isInitialized,
|
||||
isDatabaseConnectionsBannerDismissed,
|
||||
isDatabaseConnectionsEnabled,
|
||||
previouslyToggled,
|
||||
isLocalStorageReady,
|
||||
])
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { renderHook } from '@testing-library/react'
|
||||
import { useFlag, useParams } from 'common'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
@@ -9,6 +8,7 @@ import {
|
||||
import { useSupamonitorStatus } from '@/components/interfaces/QueryPerformance/hooks/useSupamonitorStatus'
|
||||
import { useContentQuery } from '@/data/content/content-query'
|
||||
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
|
||||
import { customRenderHook as renderHook } from '@/tests/lib/custom-render'
|
||||
import { routerMock } from '@/tests/lib/route-mock'
|
||||
|
||||
const { REF, mockIsPlatform } = vi.hoisted(() => ({
|
||||
|
||||
@@ -49,7 +49,7 @@ export const useGenerateObservabilityMenu = () => {
|
||||
const { isSupamonitorEnabled } = useSupamonitorStatus()
|
||||
|
||||
const showOverview = useFlag('observabilityOverview')
|
||||
const isDatabaseConnectionsEnabled = useIsDatabaseConnectionsEnabled()
|
||||
const { enabled: isDatabaseConnectionsEnabled } = useIsDatabaseConnectionsEnabled()
|
||||
const storageSupported = useIsFeatureEnabled('project_storage:all')
|
||||
|
||||
const baseUrl = `/project/${ref}/observability`
|
||||
|
||||
@@ -41,7 +41,7 @@ export const SQLEditorMenu = () => {
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const snapV2 = useSqlEditorV2StateSnapshot()
|
||||
|
||||
const isDatabaseConnectionsEnabled = useIsDatabaseConnectionsEnabled()
|
||||
const { enabled: isDatabaseConnectionsEnabled } = useIsDatabaseConnectionsEnabled()
|
||||
const sqlEditorLogsSource = useFlag('sqlEditorLogsSource')
|
||||
const otelLegacyLogs = useFlag('otelLegacyLogs')
|
||||
const canCreateLogsSnippet = sqlEditorLogsSource && otelLegacyLogs
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import { LOCAL_STORAGE_KEYS } from 'common'
|
||||
import { useParams } from 'common/hooks'
|
||||
import Link from 'next/link'
|
||||
import { Badge, Button, WarningIcon } from 'ui'
|
||||
|
||||
import { BannerCard } from '../BannerCard'
|
||||
import { useBannerStack } from '../BannerStackProvider'
|
||||
import { useFeaturePreviewModal } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext'
|
||||
import {
|
||||
useFeaturePreviewModal,
|
||||
useIsDatabaseConnectionsEnabled,
|
||||
} from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext'
|
||||
import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
|
||||
import { useTrack } from '@/lib/telemetry/track'
|
||||
|
||||
@@ -19,6 +23,8 @@ export const BannerDatabaseConnections = () => {
|
||||
false
|
||||
)
|
||||
|
||||
const { enabled: isEnabled } = useIsDatabaseConnectionsEnabled()
|
||||
|
||||
return (
|
||||
<BannerCard
|
||||
onDismiss={() => {
|
||||
@@ -72,16 +78,33 @@ export const BannerDatabaseConnections = () => {
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
variant="default"
|
||||
size="tiny"
|
||||
onClick={() => {
|
||||
track('database_connections_banner_cta_button_clicked', { isEnabled: false })
|
||||
selectFeaturePreview(LOCAL_STORAGE_KEYS.UI_PREVIEW_DATABASE_CONNECTIONS)
|
||||
}}
|
||||
>
|
||||
Enable Database Connections
|
||||
</Button>
|
||||
{isEnabled ? (
|
||||
<Button
|
||||
asChild
|
||||
variant="default"
|
||||
size="tiny"
|
||||
onClick={() => {
|
||||
setIsDismissed(true)
|
||||
dismissBanner('database-connections-banner')
|
||||
track('database_connections_banner_cta_button_clicked', { isEnabled })
|
||||
}}
|
||||
>
|
||||
<Link href={`/project/${ref}/observability/connections`}>
|
||||
Explore Database Connections
|
||||
</Link>
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
variant="default"
|
||||
size="tiny"
|
||||
onClick={() => {
|
||||
selectFeaturePreview(LOCAL_STORAGE_KEYS.UI_PREVIEW_DATABASE_CONNECTIONS)
|
||||
track('database_connections_banner_cta_button_clicked', { isEnabled: false })
|
||||
}}
|
||||
>
|
||||
Enable Database Connections
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</BannerCard>
|
||||
|
||||
@@ -33,7 +33,7 @@ export const DatabaseConnections: NextPageWithLayout = () => {
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const { openSidebar } = useSidebarManagerSnapshot()
|
||||
const aiSnap = useAiAssistantStateSnapshot()
|
||||
const isDatabaseConnectionsEnabled = useIsDatabaseConnectionsEnabled()
|
||||
const { enabled: isDatabaseConnectionsEnabled } = useIsDatabaseConnectionsEnabled()
|
||||
const { selectFeaturePreview } = useFeaturePreviewModal()
|
||||
|
||||
const [live, setLive] = useState(true)
|
||||
|
||||
@@ -66,7 +66,7 @@ export const customRender = (component: React.ReactElement, renderOptions?: Cust
|
||||
})
|
||||
}
|
||||
|
||||
export const customRenderHook = (hook: () => any, renderOptions?: CustomRenderOpts) => {
|
||||
export const customRenderHook = <T,>(hook: () => T, renderOptions?: CustomRenderOpts) => {
|
||||
return renderHook(hook, {
|
||||
wrapper: ({ children }) =>
|
||||
CustomWrapper({
|
||||
|
||||
Reference in new issue
Block a user