diff --git a/apps/studio/components/interfaces/ConnectSheet/ConnectStepsSection.tsx b/apps/studio/components/interfaces/ConnectSheet/ConnectStepsSection.tsx index 5eee915f9dd..717a0db9b16 100644 --- a/apps/studio/components/interfaces/ConnectSheet/ConnectStepsSection.tsx +++ b/apps/studio/components/interfaces/ConnectSheet/ConnectStepsSection.tsx @@ -15,6 +15,10 @@ import type { StepContentProps, } from './Connect.types' import { ConnectSheetStep } from './ConnectSheetStep' +import { + shouldFetchDataApiConfig, + shouldShowDataApiDisabledWarning, +} from './ConnectStepsSection.utils' import { CopyPromptAdmonition } from './CopyPromptAdmonition' import { buildConnectionStringPooler, getConnectionStrings } from './DatabaseSettings.utils' import { getAddons } from '@/components/interfaces/Billing/Subscription/Subscription.utils' @@ -25,6 +29,7 @@ import { useSupavisorConfigurationQuery } from '@/data/database/supavisor-config import { useProjectAddonsQuery } from '@/data/subscriptions/project-addons-query' import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements' import { useDeploymentMode } from '@/hooks/misc/useDeploymentMode' +import { useIsDataApiEnabled } from '@/hooks/misc/useIsDataApiEnabled' import { DOCS_URL } from '@/lib/constants' import { pluckObjectFields } from '@/lib/helpers' @@ -225,6 +230,23 @@ export function ConnectStepsSection({ steps, state, projectKeys }: ConnectStepsS const showSelfHostedMcpNotice = deploymentMode.isSelfHosted && state.mode === 'mcp' + const shouldFetchDataApiStatus = shouldFetchDataApiConfig({ + mode: state.mode, + }) + const { + isEnabled: isDataApiEnabled, + isPending: isDataApiConfigPending, + isError: isDataApiConfigError, + } = useIsDataApiEnabled({ + projectRef: ref, + enabled: shouldFetchDataApiStatus, + }) + const showDataApiDisabledWarning = shouldShowDataApiDisabledWarning({ + mode: state.mode, + isDataApiEnabled, + isPending: isDataApiConfigPending, + isError: isDataApiConfigError, + }) if (steps.length === 0) return null return ( @@ -232,6 +254,20 @@ export function ConnectStepsSection({ steps, state, projectKeys }: ConnectStepsS

Connect your app

+ {showDataApiDisabledWarning && ( + + Enable Data API + , + ]} + /> + )} + {showIpv4AddonNotice && ( { + test('returns true for framework mode', () => { + expect(shouldFetchDataApiConfig({ mode: 'framework' })).toBe(true) + }) + + test.each(['direct', 'orm', 'server', 'mcp'] as const)('returns false for %s mode', (mode) => { + expect(shouldFetchDataApiConfig({ mode })).toBe(false) + }) + + test('returns false for mcp even when database tools are selected', () => { + expect(shouldFetchDataApiConfig(MCP_WITH_DATABASE_TOOLS)).toBe(false) + }) +}) + +describe('shouldShowDataApiDisabledWarning', () => { + test.each(ALL_MODES)('returns false while pending for %s mode', (mode) => { + expect( + shouldShowDataApiDisabledWarning({ + mode, + isDataApiEnabled: false, + isPending: true, + isError: false, + }) + ).toBe(false) + }) + + test('returns false when config query errored', () => { + expect( + shouldShowDataApiDisabledWarning({ + mode: 'framework', + isDataApiEnabled: false, + isPending: false, + isError: true, + }) + ).toBe(false) + }) + + test('returns true for framework when Data API is disabled', () => { + expect( + shouldShowDataApiDisabledWarning({ + mode: 'framework', + isDataApiEnabled: false, + isPending: false, + isError: false, + }) + ).toBe(true) + }) + + test.each(['direct', 'orm', 'server', 'mcp'] as const)( + 'returns false for %s when Data API is disabled', + (mode) => { + expect( + shouldShowDataApiDisabledWarning({ + mode, + isDataApiEnabled: false, + isPending: false, + isError: false, + }) + ).toBe(false) + } + ) + + test('returns false for mcp with database tools selected when Data API is disabled', () => { + expect( + shouldShowDataApiDisabledWarning({ + ...MCP_WITH_DATABASE_TOOLS, + isDataApiEnabled: false, + isPending: false, + isError: false, + }) + ).toBe(false) + }) + + test('returns false when framework mode has Data API enabled', () => { + expect( + shouldShowDataApiDisabledWarning({ + mode: 'framework', + isDataApiEnabled: true, + isPending: false, + isError: false, + }) + ).toBe(false) + }) +}) diff --git a/apps/studio/components/interfaces/ConnectSheet/ConnectStepsSection.utils.ts b/apps/studio/components/interfaces/ConnectSheet/ConnectStepsSection.utils.ts new file mode 100644 index 00000000000..95998f7a513 --- /dev/null +++ b/apps/studio/components/interfaces/ConnectSheet/ConnectStepsSection.utils.ts @@ -0,0 +1,20 @@ +import type { ConnectMode } from './Connect.types' + +export function shouldFetchDataApiConfig({ mode }: { mode: ConnectMode }): boolean { + return mode === 'framework' +} + +export function shouldShowDataApiDisabledWarning({ + mode, + isDataApiEnabled, + isPending, + isError, +}: { + mode: ConnectMode + isDataApiEnabled: boolean + isPending: boolean + isError: boolean +}): boolean { + if (isPending || isError || isDataApiEnabled) return false + return shouldFetchDataApiConfig({ mode }) +} diff --git a/apps/studio/hooks/misc/useIsDataApiEnabled.ts b/apps/studio/hooks/misc/useIsDataApiEnabled.ts index cb3662c8bd2..0e09180694f 100644 --- a/apps/studio/hooks/misc/useIsDataApiEnabled.ts +++ b/apps/studio/hooks/misc/useIsDataApiEnabled.ts @@ -6,8 +6,14 @@ import { useProjectPostgrestConfigQuery } from '@/data/config/project-postgrest- * The Data API is considered enabled when the PostgREST `db_schema` config * contains at least one non-empty schema name. */ -export const useIsDataApiEnabled = ({ projectRef }: { projectRef?: string }) => { - const { data: config, ...rest } = useProjectPostgrestConfigQuery({ projectRef }) +export const useIsDataApiEnabled = ({ + projectRef, + enabled = true, +}: { + projectRef?: string + enabled?: boolean +}) => { + const { data: config, ...rest } = useProjectPostgrestConfigQuery({ projectRef }, { enabled }) const isEnabled = !!config?.db_schema?.trim()