diff --git a/apps/studio/components/interfaces/Connect/Connect.tsx b/apps/studio/components/interfaces/Connect/Connect.tsx index b71285793b2..92a592fe15e 100644 --- a/apps/studio/components/interfaces/Connect/Connect.tsx +++ b/apps/studio/components/interfaces/Connect/Connect.tsx @@ -1,9 +1,5 @@ import { PermissionAction } from '@supabase/shared-types/out/constants' import { IS_PLATFORM, useParams } from 'common' -import { ExternalLink } from 'lucide-react' -import { parseAsString, useQueryState } from 'nuqs' -import { useEffect, useMemo, useState } from 'react' - import { ApiKeysTabContent } from 'components/interfaces/Connect/ApiKeysTabContent' import { DatabaseConnectionString } from 'components/interfaces/Connect/DatabaseConnectionString' import { McpTabContent } from 'components/interfaces/Connect/McpTabContent' @@ -13,7 +9,11 @@ import { useProjectSettingsV2Query } from 'data/config/project-settings-v2-query import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions' import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled' import { BASE_PATH } from 'lib/constants' +import { ExternalLink } from 'lucide-react' +import Link from 'next/link' import { useRouter } from 'next/router' +import { parseAsBoolean, parseAsString, useQueryState } from 'nuqs' +import { useEffect, useMemo, useState } from 'react' import { Button, DIALOG_PADDING_X, @@ -30,18 +30,13 @@ import { Tabs_Shadcn_, cn, } from 'ui' + import { CONNECTION_TYPES, ConnectionType, FRAMEWORKS, MOBILES, ORMS } from './Connect.constants' import { getContentFilePath, inferConnectTabFromParentKey } from './Connect.utils' import { ConnectDropdown } from './ConnectDropdown' import { ConnectTabContent } from './ConnectTabContent' -import Link from 'next/link' -interface ConnectProps { - open: boolean - onOpenChange: (open: boolean) => void -} - -export const Connect = ({ open, onOpenChange }: ConnectProps) => { +export const Connect = () => { const router = useRouter() const { ref: projectRef } = useParams() @@ -82,6 +77,7 @@ export const Connect = ({ open, onOpenChange }: ConnectProps) => { } } + const [open, setOpen] = useQueryState('showConnect', parseAsBoolean.withDefault(false)) const [tab, setTab] = useQueryState('connectTab', parseAsString.withDefault('direct')) const [queryFramework, setQueryFramework] = useQueryState('framework', parseAsString) const [queryUsing, setQueryUsing] = useQueryState('using', parseAsString) @@ -253,12 +249,12 @@ export const Connect = ({ open, onOpenChange }: ConnectProps) => { setQueryMethod(null) } - const handleDialogChange = (nextOpen: boolean) => { - if (!nextOpen) { + const handleDialogChange = (dialogOpen: boolean) => { + if (!dialogOpen) { setTab(null) resetQueryStates() } - onOpenChange(nextOpen) + setOpen(dialogOpen) } useEffect(() => { diff --git a/apps/studio/components/interfaces/ConnectButton/ConnectButton.tsx b/apps/studio/components/interfaces/ConnectButton/ConnectButton.tsx index bce3a8e27f3..61a111e4c06 100644 --- a/apps/studio/components/interfaces/ConnectButton/ConnectButton.tsx +++ b/apps/studio/components/interfaces/ConnectButton/ConnectButton.tsx @@ -1,86 +1,39 @@ -import { Connect } from 'components/interfaces/Connect/Connect' -import { ConnectSheet } from 'components/interfaces/ConnectSheet/ConnectSheet' import { ButtonTooltip } from 'components/ui/ButtonTooltip' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' -import { usePHFlag } from 'hooks/ui/useFlag' -import { PROJECT_STATUS } from 'lib/constants' import { Plug } from 'lucide-react' -import { parseAsBoolean, parseAsString, useQueryState } from 'nuqs' +import { parseAsBoolean, useQueryState } from 'nuqs' import { ComponentProps } from 'react' import { Button } from 'ui' +import { PROJECT_STATUS } from '@/lib/constants' + interface ConnectButtonProps { buttonType?: ComponentProps['type'] - renderDialog?: boolean } -export const ConnectButton = ({ - buttonType = 'default', - renderDialog = true, -}: ConnectButtonProps) => { - const connectSheetFlag = usePHFlag('connectSheet') - const isFlagResolved = connectSheetFlag !== undefined - const isConnectSheetEnabled = connectSheetFlag === true || connectSheetFlag === 'variation' - +export const ConnectButton = ({ buttonType = 'default' }: ConnectButtonProps) => { const { data: selectedProject } = useSelectedProjectQuery() const isActiveHealthy = selectedProject?.status === PROJECT_STATUS.ACTIVE_HEALTHY - const [showConnect, setShowConnect] = useQueryState( - 'showConnect', - parseAsBoolean.withDefault(false) - ) - const [connectTab, setConnectTab] = useQueryState('connectTab', parseAsString) - - const handleOpenChange = (open: boolean) => { - if (!open) { - setShowConnect(null) - setConnectTab(null) - return - } - - setShowConnect(true) - } - - if (!isActiveHealthy) { - return ( - } - tooltip={{ - content: { - side: 'bottom', - text: 'Project is currently not active and cannot be connected', - }, - }} - > - Connect - - ) - } + const [_, setShowConnect] = useQueryState('showConnect', parseAsBoolean.withDefault(false)) return ( - <> - - {renderDialog && isFlagResolved ? ( - isConnectSheetEnabled ? ( - - ) : ( - - ) - ) : null} - + } + onClick={() => setShowConnect(true)} + tooltip={{ + content: { + side: 'bottom', + text: !isActiveHealthy + ? 'Project is currently not active and cannot be connected' + : undefined, + }, + }} + > + Connect + ) } diff --git a/apps/studio/components/interfaces/ConnectSheet/ConnectSheet.tsx b/apps/studio/components/interfaces/ConnectSheet/ConnectSheet.tsx index e2064944460..737be71a55d 100644 --- a/apps/studio/components/interfaces/ConnectSheet/ConnectSheet.tsx +++ b/apps/studio/components/interfaces/ConnectSheet/ConnectSheet.tsx @@ -1,14 +1,22 @@ +import { parseAsBoolean, parseAsString, useQueryState } from 'nuqs' import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, cn } from 'ui' -interface ConnectSheetProps { - open: boolean - onOpenChange: (open: boolean) => void - connectTab?: string | null -} +export const ConnectSheet = () => { + const [showConnect, setShowConnect] = useQueryState( + 'showConnect', + parseAsBoolean.withDefault(false) + ) + const [connectTab, setConnectTab] = useQueryState('connectTab', parseAsString) + + const handleOpenChange = (sheetOpen: boolean) => { + if (!sheetOpen) { + setConnectTab(null) + } + setShowConnect(sheetOpen) + } -export const ConnectSheet = ({ open, onOpenChange, connectTab }: ConnectSheetProps) => { return ( - +
diff --git a/apps/studio/components/interfaces/Home/NewProjectPanel/APIKeys.tsx b/apps/studio/components/interfaces/Home/NewProjectPanel/APIKeys.tsx index ce8271e5d82..f014e3ec747 100644 --- a/apps/studio/components/interfaces/Home/NewProjectPanel/APIKeys.tsx +++ b/apps/studio/components/interfaces/Home/NewProjectPanel/APIKeys.tsx @@ -208,7 +208,7 @@ export const APIKeys = () => { Connect to your project from a variety of frameworks, ORMs, an MCP server, or even directly via connection string.

- +
diff --git a/apps/studio/components/interfaces/HomeNew/GettingStarted/GettingStartedSection.tsx b/apps/studio/components/interfaces/HomeNew/GettingStarted/GettingStartedSection.tsx index c4585d9dd36..d5c61766ffd 100644 --- a/apps/studio/components/interfaces/HomeNew/GettingStarted/GettingStartedSection.tsx +++ b/apps/studio/components/interfaces/HomeNew/GettingStarted/GettingStartedSection.tsx @@ -1,16 +1,15 @@ -import { Code, Table2 } from 'lucide-react' -import { useCallback, useMemo, useState } from 'react' - -import { ConnectButton } from '@/components/interfaces/ConnectButton/ConnectButton' import { useParams } from 'common' import { SIDEBAR_KEYS } from 'components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider' import { useSendEventMutation } from 'data/telemetry/send-event-mutation' import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { BASE_PATH } from 'lib/constants' +import { Code, Table2 } from 'lucide-react' +import { useCallback, useMemo, useState } from 'react' import { useAiAssistantStateSnapshot } from 'state/ai-assistant-state' import { useSidebarManagerSnapshot } from 'state/sidebar-manager-state' import { Button, Card, CardContent, ToggleGroup, ToggleGroupItem } from 'ui' + import { GettingStarted } from './GettingStarted' import { GettingStartedAction, @@ -19,6 +18,7 @@ import { } from './GettingStarted.types' import { getCodeWorkflowSteps, getNoCodeWorkflowSteps } from './GettingStarted.utils' import { useGettingStartedProgress } from './useGettingStartedProgress' +import { ConnectButton } from '@/components/interfaces/ConnectButton/ConnectButton' interface GettingStartedSectionProps { value: GettingStartedState @@ -50,7 +50,7 @@ export function GettingStartedSection({ value, onChange }: GettingStartedSection return [ { label: 'Connect', - component: , + component: , }, ] }, []) diff --git a/apps/studio/components/layouts/ProjectLayout/LayoutHeader/LayoutHeader.tsx b/apps/studio/components/layouts/ProjectLayout/LayoutHeader/LayoutHeader.tsx index 4e972e16119..1279540e9e2 100644 --- a/apps/studio/components/layouts/ProjectLayout/LayoutHeader/LayoutHeader.tsx +++ b/apps/studio/components/layouts/ProjectLayout/LayoutHeader/LayoutHeader.tsx @@ -1,9 +1,3 @@ -import { AnimatePresence, motion } from 'framer-motion' -import { ChevronLeft } from 'lucide-react' -import Link from 'next/link' -import { ReactNode, useMemo } from 'react' - -import { ConnectButton } from '@/components/interfaces/ConnectButton/ConnectButton' import { LOCAL_STORAGE_KEYS, useParams } from 'common' import { useIsBranching2Enabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { LocalDropdown } from 'components/interfaces/LocalDropdown' @@ -16,20 +10,29 @@ import { OrganizationDropdown } from 'components/layouts/AppLayout/OrganizationD import { ProjectDropdown } from 'components/layouts/AppLayout/ProjectDropdown' import { getResourcesExceededLimitsOrg } from 'components/ui/OveragesBanner/OveragesBanner.utils' import { useOrgUsageQuery } from 'data/usage/org-usage-query' +import { AnimatePresence, motion } from 'framer-motion' import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage' import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' import { IS_PLATFORM } from 'lib/constants' +import { ChevronLeft } from 'lucide-react' +import Link from 'next/link' import { useRouter } from 'next/router' +import { ReactNode, useMemo } from 'react' import { useAppStateSnapshot } from 'state/app-state' import { Badge, cn } from 'ui' import { CommandMenuTriggerInput } from 'ui-patterns' + import { BreadcrumbsView } from './BreadcrumbsView' import { FeedbackDropdown } from './FeedbackDropdown/FeedbackDropdown' import { HelpPopover } from './HelpPopover' import { HomeIcon } from './HomeIcon' import { LocalVersionPopover } from './LocalVersionPopover' import MergeRequestButton from './MergeRequestButton' +import { Connect } from '@/components/interfaces/Connect/Connect' +import { ConnectButton } from '@/components/interfaces/ConnectButton/ConnectButton' +import { ConnectSheet } from '@/components/interfaces/ConnectSheet/ConnectSheet' +import { usePHFlag } from '@/hooks/ui/useFlag' const LayoutHeaderDivider = ({ className, ...props }: React.HTMLProps) => ( @@ -64,13 +67,17 @@ export const LayoutHeader = ({ showProductMenu, backToDashboardURL, }: LayoutHeaderProps) => { - const { ref: projectRef, slug } = useParams() const router = useRouter() + const { ref: projectRef, slug } = useParams() const { data: selectedProject } = useSelectedProjectQuery() const { data: selectedOrganization } = useSelectedOrganizationQuery() const { setMobileMenuOpen } = useAppStateSnapshot() const gitlessBranching = useIsBranching2Enabled() + const connectSheetFlag = usePHFlag('connectSheet') + const isFlagResolved = connectSheetFlag !== undefined + const isConnectSheetEnabled = connectSheetFlag === true || connectSheetFlag === 'variation' + const [commandMenuEnabled] = useLocalStorageQuery(LOCAL_STORAGE_KEYS.HOTKEY_COMMAND_MENU, true) const isAccountPage = router.pathname.startsWith('/account') @@ -265,6 +272,8 @@ export const LayoutHeader = ({ + + {isFlagResolved ? isConnectSheetEnabled ? : : null} ) }