diff --git a/apps/studio/components/layouts/AccountLayout/WithSidebar.tsx b/apps/studio/components/layouts/AccountLayout/WithSidebar.tsx index a583416ebb6..8ad5ce3539c 100644 --- a/apps/studio/components/layouts/AccountLayout/WithSidebar.tsx +++ b/apps/studio/components/layouts/AccountLayout/WithSidebar.tsx @@ -3,6 +3,7 @@ import Link from 'next/link' import { PropsWithChildren, ReactNode } from 'react' import { cn, Menu } from 'ui' +import { NavUser } from '../NavigationV2/NavUser' import type { SidebarSection } from './AccountLayout.types' import { useAppStateSnapshot } from '@/state/app-state' @@ -64,79 +65,78 @@ export const SidebarContent = ({ className, }: PropsWithChildren> & { className?: string }) => { return ( - <> -
-
- {backToDashboardURL && ( -
-
- - - Back to dashboard - -
-
- )} - {header && header} -
-
- - {customSidebarContent} - {sections.map((section, idx) => ( -
- {Boolean(section.heading) ? ( - - ) : ( -
-
- {section.links.map((link, i: number) => { - const isActive = link.isActive && !subitems - return ( - - -
-
- {link.label} -
-
- -
- ) - })} -
-
- )} - {idx !== sections.length - 1 && ( -
- )} -
- ))} -
+
+
+ {backToDashboardURL && ( +
+
+ + + Back to dashboard +
+ )} + {header && header} +
+
+ + {customSidebarContent} + {sections.map((section, idx) => ( +
+ {Boolean(section.heading) ? ( + + ) : ( +
+
+ {section.links.map((link, i: number) => { + const isActive = link.isActive && !subitems + return ( + + +
+
+ {link.label} +
+
+ +
+ ) + })} +
+
+ )} + {idx !== sections.length - 1 &&
} +
+ ))} +
+
+
+ +
- +
) } diff --git a/apps/studio/components/layouts/AdvisorsLayout/AdvisorsLayout.tsx b/apps/studio/components/layouts/AdvisorsLayout/AdvisorsLayout.tsx index 8e2b2222410..2fb5dc02a94 100644 --- a/apps/studio/components/layouts/AdvisorsLayout/AdvisorsLayout.tsx +++ b/apps/studio/components/layouts/AdvisorsLayout/AdvisorsLayout.tsx @@ -2,7 +2,7 @@ import { useIsNavigationV2Enabled } from 'components/interfaces/App/FeaturePrevi import { useRouter } from 'next/router' import { PropsWithChildren } from 'react' -import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayoutV2' +import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayout' import { ProjectLayout } from '../ProjectLayout' import { AdvisorsSidebarMenu } from './AdvisorsSidebarMenu' import { withAuth } from '@/hooks/misc/withAuth' diff --git a/apps/studio/components/layouts/AuthLayout/AuthLayout.tsx b/apps/studio/components/layouts/AuthLayout/AuthLayout.tsx index 871b4aa69ee..d2d760d6d7d 100644 --- a/apps/studio/components/layouts/AuthLayout/AuthLayout.tsx +++ b/apps/studio/components/layouts/AuthLayout/AuthLayout.tsx @@ -3,7 +3,7 @@ import { useIsNavigationV2Enabled } from 'components/interfaces/App/FeaturePrevi import { useRouter } from 'next/router' import type { PropsWithChildren } from 'react' -import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayoutV2' +import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayout' import { ProjectLayout } from '../ProjectLayout' import { useGenerateAuthMenu } from './AuthLayout.utils' import { ProductMenu } from '@/components/ui/ProductMenu' diff --git a/apps/studio/components/layouts/DatabaseLayout/DatabaseLayout.tsx b/apps/studio/components/layouts/DatabaseLayout/DatabaseLayout.tsx index d541789c180..5979212d34c 100644 --- a/apps/studio/components/layouts/DatabaseLayout/DatabaseLayout.tsx +++ b/apps/studio/components/layouts/DatabaseLayout/DatabaseLayout.tsx @@ -2,7 +2,7 @@ import { useIsNavigationV2Enabled } from 'components/interfaces/App/FeaturePrevi import { useRouter } from 'next/router' import type { PropsWithChildren } from 'react' -import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayoutV2' +import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayout' import { ProjectLayout } from '../ProjectLayout' import { useGenerateDatabaseMenu } from './DatabaseMenu.utils' import { ProductMenu } from '@/components/ui/ProductMenu' diff --git a/apps/studio/components/layouts/DefaultLayout.tsx b/apps/studio/components/layouts/DefaultLayout.tsx index 2862ec3279b..16572854f7c 100644 --- a/apps/studio/components/layouts/DefaultLayout.tsx +++ b/apps/studio/components/layouts/DefaultLayout.tsx @@ -7,7 +7,7 @@ import { ResizablePanel, ResizablePanelGroup } from 'ui' import { DefaultLayoutProviders } from './DefaultLayoutProviders' import { LayoutHeader } from './Navigation/LayoutHeader/LayoutHeader' import MobileNavigationBar from './Navigation/NavigationBar/MobileNavigationBar' -import { DefaultLayoutV2 } from './NavigationV2/DefaultLayoutV2' +import { DefaultLayoutV2 } from './NavigationV2/DefaultLayout' import { LayoutSidebar } from './ProjectLayout/LayoutSidebar' import { AppBannerWrapper } from '@/components/interfaces/App/AppBannerWrapper' import { Sidebar } from '@/components/interfaces/Sidebar' diff --git a/apps/studio/components/layouts/EdgeFunctionsLayout/EdgeFunctionsLayout.tsx b/apps/studio/components/layouts/EdgeFunctionsLayout/EdgeFunctionsLayout.tsx index d112df44af8..7dbcfcc91b6 100644 --- a/apps/studio/components/layouts/EdgeFunctionsLayout/EdgeFunctionsLayout.tsx +++ b/apps/studio/components/layouts/EdgeFunctionsLayout/EdgeFunctionsLayout.tsx @@ -3,7 +3,7 @@ import { useIsNavigationV2Enabled } from 'components/interfaces/App/FeaturePrevi import { useRouter } from 'next/router' import type { ComponentProps, PropsWithChildren } from 'react' -import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayoutV2' +import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayout' import { ProjectLayout } from '../ProjectLayout' import { ProductMenu } from '@/components/ui/ProductMenu' import { withAuth } from '@/hooks/misc/withAuth' diff --git a/apps/studio/components/layouts/Integrations/layout.tsx b/apps/studio/components/layouts/Integrations/layout.tsx index 947b9d254ef..ea258098e13 100644 --- a/apps/studio/components/layouts/Integrations/layout.tsx +++ b/apps/studio/components/layouts/Integrations/layout.tsx @@ -1,6 +1,6 @@ import { useIsNavigationV2Enabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { useInstalledIntegrations } from 'components/interfaces/Integrations/Landing/useInstalledIntegrations' -import { ProjectLayoutV2 } from 'components/layouts/NavigationV2/ProjectLayoutV2' +import { ProjectLayoutV2 } from 'components/layouts/NavigationV2/ProjectLayout' import { ProjectLayout } from 'components/layouts/ProjectLayout' import AlertError from 'components/ui/AlertError' import { ProductMenu } from 'components/ui/ProductMenu' diff --git a/apps/studio/components/layouts/LogsLayout/LogsLayout.tsx b/apps/studio/components/layouts/LogsLayout/LogsLayout.tsx index 6b432d5b528..f698e9f4658 100644 --- a/apps/studio/components/layouts/LogsLayout/LogsLayout.tsx +++ b/apps/studio/components/layouts/LogsLayout/LogsLayout.tsx @@ -2,7 +2,7 @@ import { PermissionAction } from '@supabase/shared-types/out/constants' import { useIsNavigationV2Enabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import type { PropsWithChildren } from 'react' -import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayoutV2' +import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayout' import { ProjectLayout } from '../ProjectLayout' import { LogsSidebarMenuV2 } from './LogsSidebarMenuV2' import NoPermission from '@/components/ui/NoPermission' diff --git a/apps/studio/components/layouts/Navigation/LayoutHeader/LayoutHeader.tsx b/apps/studio/components/layouts/Navigation/LayoutHeader/LayoutHeader.tsx index 44ea0d757fc..5e94fc3c415 100644 --- a/apps/studio/components/layouts/Navigation/LayoutHeader/LayoutHeader.tsx +++ b/apps/studio/components/layouts/Navigation/LayoutHeader/LayoutHeader.tsx @@ -36,7 +36,7 @@ import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganizati import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import { IS_PLATFORM } from '@/lib/constants' -const LayoutHeaderDivider = ({ className, ...props }: React.HTMLProps) => ( +export const LayoutHeaderDivider = ({ className, ...props }: React.HTMLProps) => ( setOpen(true) : undefined} > - - {selectedOrgInitial} - -
+
{selectedOrganization?.name ?? 'Select organization'}
diff --git a/apps/studio/components/layouts/Navigation/NavigationBar/ProjectBranchSelector.tsx b/apps/studio/components/layouts/Navigation/NavigationBar/ProjectBranchSelector.tsx index 5cdb3e75d26..ebe76408cc8 100644 --- a/apps/studio/components/layouts/Navigation/NavigationBar/ProjectBranchSelector.tsx +++ b/apps/studio/components/layouts/Navigation/NavigationBar/ProjectBranchSelector.tsx @@ -44,12 +44,11 @@ export function ProjectBranchSelector() { ) const selectedBranch = branches?.find((b) => b.project_ref === ref) - const { isMainBranch, branchDisplayName, selectedOrgInitial, organizationHref } = - getProjectBranchSelectorState({ - selectedBranch, - isBranchingEnabled, - selectedOrganization: selectedOrganization ?? undefined, - }) + const { isMainBranch, branchDisplayName, organizationHref } = getProjectBranchSelectorState({ + selectedBranch, + isBranchingEnabled, + selectedOrganization: selectedOrganization ?? undefined, + }) const goToOrganization = () => { setOpen(false) @@ -75,7 +74,7 @@ export function ProjectBranchSelector() { const triggerProps = { displayProjectName: displayProject.name, - selectedOrgInitial, + selectedOrg: selectedOrganization, isBranch, isProductionBranch, branchDisplayName, diff --git a/apps/studio/components/layouts/Navigation/NavigationBar/ProjectBranchSelector.utils.ts b/apps/studio/components/layouts/Navigation/NavigationBar/ProjectBranchSelector.utils.ts index 78b508839ba..681799505a1 100644 --- a/apps/studio/components/layouts/Navigation/NavigationBar/ProjectBranchSelector.utils.ts +++ b/apps/studio/components/layouts/Navigation/NavigationBar/ProjectBranchSelector.utils.ts @@ -5,7 +5,6 @@ export interface ProjectBranchSelectorState { selectedBranch: Branch | undefined isMainBranch: boolean branchDisplayName: string - selectedOrgInitial: string organizationHref: string } @@ -18,7 +17,6 @@ export function getProjectBranchSelectorState(params: { const isMainBranch = !isBranchingEnabled || selectedBranch?.is_default === true const branchDisplayName = isBranchingEnabled ? (selectedBranch?.name ?? 'main') : 'main' - const selectedOrgInitial = selectedOrganization?.name?.trim().charAt(0).toUpperCase() ?? 'O' const organizationHref = selectedOrganization?.slug ? `/org/${selectedOrganization.slug}` : '/organizations' @@ -27,7 +25,10 @@ export function getProjectBranchSelectorState(params: { selectedBranch, isMainBranch, branchDisplayName, - selectedOrgInitial, organizationHref, } } + +export function getSelectedOrgInitial(orgName: string): string { + return orgName.trim().charAt(0).toUpperCase() +} diff --git a/apps/studio/components/layouts/Navigation/NavigationBar/ProjectBranchSelectorPopover.tsx b/apps/studio/components/layouts/Navigation/NavigationBar/ProjectBranchSelectorPopover.tsx index 681150fdcd3..f2f3c56ba70 100644 --- a/apps/studio/components/layouts/Navigation/NavigationBar/ProjectBranchSelectorPopover.tsx +++ b/apps/studio/components/layouts/Navigation/NavigationBar/ProjectBranchSelectorPopover.tsx @@ -17,8 +17,6 @@ import { useEffect, useState } from 'react' import { useAppStateSnapshot } from 'state/app-state' import type { Organization } from 'types' import { - Button, - cn, Command_Shadcn_, CommandEmpty_Shadcn_, CommandGroup_Shadcn_, @@ -113,6 +111,7 @@ export function ProjectBranchSelectorPopover({ onClose }: ProjectBranchSelectorP selectedBranch={selectedBranch} isBranchingEnabled={isBranchingEnabled} isBranchesLoaded={isBranchesSuccess} + projectRef={parentRef ?? ref ?? ''} onSelect={(branch) => { const sanitizedRoute = sanitizeRoute(router.route, router.query) const href = @@ -238,6 +237,7 @@ function BranchColumn({ selectedBranch, isBranchingEnabled, isBranchesLoaded, + projectRef, onSelect, onCreateBranch, onManageBranches, @@ -247,6 +247,7 @@ function BranchColumn({ selectedBranch?: Branch isBranchingEnabled: boolean isBranchesLoaded: boolean + projectRef: string onSelect: (branch: Branch) => void onCreateBranch: () => void onManageBranches: () => void @@ -301,6 +302,7 @@ function BranchColumn({ )} + onClose()}> , keyof ProjectBranchSelectorTriggerProps > ->( - ( - { displayProjectName, selectedOrgInitial, isBranch, branchDisplayName, ...buttonProps }, - ref - ) => { - const isNavigationV2 = useIsNavigationV2Enabled() +>(({ displayProjectName, selectedOrg, isBranch, branchDisplayName, ...buttonProps }, ref) => { + const selectedOrgInitial = getSelectedOrgInitial(selectedOrg?.name ?? 'O') - return ( - -
- {selectedOrgInitial} -
+ return ( + + + +
+ {selectedOrgInitial} +
+
+ {selectedOrg?.name} +
+
-
-
- {displayProjectName} -
-
- - {branchDisplayName} -
+
+ {displayProjectName} +
+
+ + {branchDisplayName}
+
- - - ) - } -) + + + ) +}) ProjectBranchSelectorTrigger.displayName = 'ProjectBranchSelectorTrigger' diff --git a/apps/studio/components/layouts/NavigationV2/AppSidebarV2.tsx b/apps/studio/components/layouts/NavigationV2/AppSidebar.tsx similarity index 92% rename from apps/studio/components/layouts/NavigationV2/AppSidebarV2.tsx rename to apps/studio/components/layouts/NavigationV2/AppSidebar.tsx index 3ea67ea513a..496f61a8563 100644 --- a/apps/studio/components/layouts/NavigationV2/AppSidebarV2.tsx +++ b/apps/studio/components/layouts/NavigationV2/AppSidebar.tsx @@ -1,4 +1,3 @@ -import { usePHFlag } from 'hooks/ui/useFlag' import { IS_PLATFORM } from 'lib/constants' import { Plug, Search } from 'lucide-react' import { parseAsBoolean, useQueryState } from 'nuqs' @@ -11,6 +10,7 @@ import { NavGroup } from './NavGroup' import { NavUser } from './NavUser' import { useAppSidebarNavItems, type AppSidebarScope } from './useAppSidebarNavItems' import { ConnectSheet } from '@/components/interfaces/ConnectSheet/ConnectSheet' +import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' export type { AppSidebarScope } @@ -21,9 +21,7 @@ interface AppSidebarV2Props { export function AppSidebarV2({ scope }: AppSidebarV2Props = {}) { const setCommandMenuOpen = useSetCommandMenuOpen() const [, setShowConnect] = useQueryState('showConnect', parseAsBoolean.withDefault(false)) - const connectSheetFlag = usePHFlag('connectSheet') - const isFlagResolved = connectSheetFlag !== undefined - const isConnectSheetEnabled = connectSheetFlag === true || connectSheetFlag === 'variation' + const { data: selectedOrganization } = useSelectedOrganizationQuery() const { isProjectScope, @@ -78,14 +76,14 @@ export function AppSidebarV2({ scope }: AppSidebarV2Props = {}) { - ) : ( + ) : selectedOrganization ? ( - )} + ) : null}
>( + ({ title, isLoading = false, isBlocking = true, product = '', children, selectedTable }, ref) => { + const router = useRouter() + const { data: selectedOrganization } = useSelectedOrganizationQuery() + const { data: selectedProject } = useSelectedProjectQuery() + + const setMainScrollContainer = useSetMainScrollContainer() + const combinedRef = mergeRefs(ref, setMainScrollContainer) + + const { appTitle } = useCustomContent(['app:title']) + const titleSuffix = appTitle || 'Supabase' + + const projectName = selectedProject?.name + const organizationName = selectedOrganization?.name + + const isPaused = selectedProject?.status === PROJECT_STATUS.INACTIVE + + const ignorePausedState = + router.pathname === '/project/[ref]' || + router.pathname.includes('/project/[ref]/settings') || + router.pathname.includes('/project/[ref]/functions') + const showPausedState = isPaused && !ignorePausedState + + return ( + <> + + + {title + ? `${title} | ${titleSuffix}` + : selectedTable + ? `${selectedTable} | ${projectName} | ${organizationName} | ${titleSuffix}` + : projectName + ? `${projectName} | ${organizationName} | ${titleSuffix}` + : organizationName + ? `${organizationName} | ${titleSuffix}` + : titleSuffix} + + + +
+ {showPausedState ? ( +
+
+ +
+
+ ) : ( + + + {children} + + )} +
+ + + + ) + } +) + +ProjectLayoutV2.displayName = 'ProjectLayoutV2' + +export const ProjectLayoutV2WithAuth = withAuth(ProjectLayoutV2) diff --git a/apps/studio/components/layouts/NavigationV2/ProjectLayoutV2.tsx b/apps/studio/components/layouts/NavigationV2/ProjectLayoutV2.tsx deleted file mode 100644 index 66d96137464..00000000000 --- a/apps/studio/components/layouts/NavigationV2/ProjectLayoutV2.tsx +++ /dev/null @@ -1,235 +0,0 @@ -import { mergeRefs, useParams } from 'common' -import { CreateBranchModal } from 'components/interfaces/BranchManagement/CreateBranchModal' -import { ProjectAPIDocs } from 'components/interfaces/ProjectAPIDocs/ProjectAPIDocs' -import { ResourceExhaustionWarningBanner } from 'components/ui/ResourceExhaustionWarningBanner/ResourceExhaustionWarningBanner' -import { useCustomContent } from 'hooks/custom-content/useCustomContent' -import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization' -import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' -import { withAuth } from 'hooks/misc/withAuth' -import { usePHFlag } from 'hooks/ui/useFlag' -import { PROJECT_STATUS } from 'lib/constants' -import Head from 'next/head' -import { useRouter } from 'next/router' -import { forwardRef, Fragment, PropsWithChildren, useEffect } from 'react' -import { useDatabaseSelectorStateSnapshot } from 'state/database-selector' -import { LogoLoader } from 'ui' - -import { useSetMainScrollContainer } from '../MainScrollContainerContext' -import BuildingState from '../ProjectLayout/BuildingState' -import ConnectingState from '../ProjectLayout/ConnectingState' -import { LoadingState } from '../ProjectLayout/LoadingState' -import { ProjectPausedState } from '../ProjectLayout/PausedState/ProjectPausedState' -import { PauseFailedState } from '../ProjectLayout/PauseFailedState' -import { PausingState } from '../ProjectLayout/PausingState' -import { ResizingState } from '../ProjectLayout/ResizingState' -import RestartingState from '../ProjectLayout/RestartingState' -import { RestoreFailedState } from '../ProjectLayout/RestoreFailedState' -import { RestoringState } from '../ProjectLayout/RestoringState' -import { UpgradingState } from '../ProjectLayout/UpgradingState' - -const routesToIgnoreProjectDetailsRequest = [ - '/project/[ref]/settings/general', - '/project/[ref]/database/settings', - '/project/[ref]/storage/settings', - '/project/[ref]/settings/infrastructure', - '/project/[ref]/settings/addons', -] - -const routesToIgnoreDBConnection = [ - '/project/[ref]/branches', - '/project/[ref]/database/backups/scheduled', - '/project/[ref]/database/backups/pitr', - '/project/[ref]/settings/addons', - '/project/[ref]/functions', -] - -const routesToIgnorePostgrestConnection = [ - '/project/[ref]/reports', - '/project/[ref]/settings/general', - '/project/[ref]/database/settings', - '/project/[ref]/settings/infrastructure', - '/project/[ref]/settings/addons', -] - -export interface ProjectLayoutV2Props { - title?: string - isLoading?: boolean - isBlocking?: boolean - product?: string - selectedTable?: string -} - -/** - * V2 Project layout - renders content directly without a secondary product menu sidebar. - * In V2, all navigation is in the primary sidebar (AppSidebarV2), so this layout - * only handles title, loading states, and content wrapping. - */ -export const ProjectLayoutV2 = forwardRef>( - ({ title, isLoading = false, isBlocking = true, product = '', children, selectedTable }, ref) => { - const router = useRouter() - const { data: selectedOrganization } = useSelectedOrganizationQuery() - const { data: selectedProject } = useSelectedProjectQuery() - - const setMainScrollContainer = useSetMainScrollContainer() - const combinedRef = mergeRefs(ref, setMainScrollContainer) - - const { appTitle } = useCustomContent(['app:title']) - const titleSuffix = appTitle || 'Supabase' - - const projectName = selectedProject?.name - const organizationName = selectedOrganization?.name - - const isPaused = selectedProject?.status === PROJECT_STATUS.INACTIVE - - const ignorePausedState = - router.pathname === '/project/[ref]' || - router.pathname.includes('/project/[ref]/settings') || - router.pathname.includes('/project/[ref]/functions') - const showPausedState = isPaused && !ignorePausedState - - return ( - <> - - - {title - ? `${title} | ${titleSuffix}` - : selectedTable - ? `${selectedTable} | ${projectName} | ${organizationName} | ${titleSuffix}` - : projectName - ? `${projectName} | ${organizationName} | ${titleSuffix}` - : organizationName - ? `${organizationName} | ${titleSuffix}` - : titleSuffix} - - - -
- {showPausedState ? ( -
-
- -
-
- ) : ( - - - {children} - - )} -
- - - - ) - } -) - -ProjectLayoutV2.displayName = 'ProjectLayoutV2' - -export const ProjectLayoutV2WithAuth = withAuth(ProjectLayoutV2) - -interface ContentWrapperProps { - isLoading: boolean - isBlocking?: boolean - children: React.ReactNode -} - -const ContentWrapper = ({ isLoading, isBlocking = true, children }: ContentWrapperProps) => { - const router = useRouter() - const { ref } = useParams() - const state = useDatabaseSelectorStateSnapshot() - const { data: selectedProject } = useSelectedProjectQuery() - const isHomeNew = usePHFlag('homeNew') === 'new-home' - - const isBranchesPage = router.pathname.includes('/project/[ref]/branches') - const isSettingsPages = router.pathname.includes('/project/[ref]/settings') - const isEdgeFunctionPages = router.pathname.includes('/project/[ref]/functions') - const isVaultPage = router.pathname === '/project/[ref]/settings/vault' - const isBackupsPage = router.pathname.includes('/project/[ref]/database/backups') - const isHomePage = router.pathname === '/project/[ref]' - - const requiresDbConnection: boolean = - (!isEdgeFunctionPages && - !isSettingsPages && - !routesToIgnoreDBConnection.includes(router.pathname)) || - isVaultPage - const requiresPostgrestConnection = !routesToIgnorePostgrestConnection.includes(router.pathname) - const requiresProjectDetails = !routesToIgnoreProjectDetailsRequest.includes(router.pathname) - - const isRestarting = selectedProject?.status === PROJECT_STATUS.RESTARTING - const isResizing = selectedProject?.status === PROJECT_STATUS.RESIZING - const isProjectUpgrading = selectedProject?.status === PROJECT_STATUS.UPGRADING - const isProjectRestoring = selectedProject?.status === PROJECT_STATUS.RESTORING - const isProjectRestoreFailed = selectedProject?.status === PROJECT_STATUS.RESTORE_FAILED - const isProjectBuilding = - selectedProject?.status === PROJECT_STATUS.COMING_UP || - selectedProject?.status === PROJECT_STATUS.UNKNOWN - const isProjectPausing = selectedProject?.status === PROJECT_STATUS.PAUSING - const isProjectPauseFailed = selectedProject?.status === PROJECT_STATUS.PAUSE_FAILED - const isProjectOffline = selectedProject?.postgrestStatus === 'OFFLINE' - - const shouldRedirectToHomeForBuilding = - isHomeNew && requiresDbConnection && isProjectBuilding && !isBranchesPage && !isHomePage - - const shouldShowBuildingState = - requiresDbConnection && isProjectBuilding && !isBranchesPage && !(isHomeNew && isHomePage) - - useEffect(() => { - if (shouldRedirectToHomeForBuilding && ref) { - router.replace(`/project/${ref}`) - } - }, [shouldRedirectToHomeForBuilding, ref, router]) - - useEffect(() => { - if (ref) state.setSelectedDatabaseId(ref) - }, [ref]) - - if (isBlocking && (isLoading || (requiresProjectDetails && selectedProject === undefined))) { - return router.pathname.endsWith('[ref]') ? : - } - - if (isRestarting && !isBackupsPage) { - return - } - - if (isResizing && !isBackupsPage) { - return - } - - if (isProjectUpgrading && !isBackupsPage) { - return - } - - if (isProjectPausing) { - return - } - - if (isProjectPauseFailed) { - return - } - - if (requiresPostgrestConnection && isProjectOffline) { - return - } - - if (requiresDbConnection && isProjectRestoring) { - return - } - - if (isProjectRestoreFailed && !isBackupsPage && !isEdgeFunctionPages) { - return - } - - if (shouldRedirectToHomeForBuilding) { - return - } - - if (shouldShowBuildingState) { - return - } - - return {children} -} diff --git a/apps/studio/components/layouts/NavigationV2/index.tsx b/apps/studio/components/layouts/NavigationV2/index.tsx index dee4d71c34f..f77538adb8c 100644 --- a/apps/studio/components/layouts/NavigationV2/index.tsx +++ b/apps/studio/components/layouts/NavigationV2/index.tsx @@ -1,6 +1,6 @@ -export { DefaultLayoutV2 } from './DefaultLayoutV2' -export { ProjectLayoutV2, ProjectLayoutV2WithAuth } from './ProjectLayoutV2' -export { AppSidebarV2 } from './AppSidebarV2' +export { DefaultLayoutV2 } from './DefaultLayout' +export { ProjectLayoutV2, ProjectLayoutV2WithAuth } from './ProjectLayout' +export { AppSidebarV2 } from './AppSidebar' export { NavGroup } from './NavGroup' export type { NavGroupItem, NavGroupProps } from './NavGroup' export { RightRailLayout } from './RightIconRail' diff --git a/apps/studio/components/layouts/NavigationV2/useAppSidebarNavItems.ts b/apps/studio/components/layouts/NavigationV2/useAppSidebarNavItems.ts index 6ce03fd95e3..c9bd73bb84c 100644 --- a/apps/studio/components/layouts/NavigationV2/useAppSidebarNavItems.ts +++ b/apps/studio/components/layouts/NavigationV2/useAppSidebarNavItems.ts @@ -21,7 +21,7 @@ import { generateDatabaseNavItems, generateObservabilityNavItems, generatePlatformNavItems, -} from './NavigationV2.utils' +} from './Navigation.utils' export type AppSidebarScope = 'project' | 'organization' diff --git a/apps/studio/components/layouts/ObservabilityLayout/ObservabilityLayout.tsx b/apps/studio/components/layouts/ObservabilityLayout/ObservabilityLayout.tsx index eb0848b07a2..c35dd158a30 100644 --- a/apps/studio/components/layouts/ObservabilityLayout/ObservabilityLayout.tsx +++ b/apps/studio/components/layouts/ObservabilityLayout/ObservabilityLayout.tsx @@ -3,7 +3,7 @@ import { useIsNavigationV2Enabled } from 'components/interfaces/App/FeaturePrevi import { usePathname } from 'next/navigation' import { useEffect, useRef, type PropsWithChildren } from 'react' -import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayoutV2' +import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayout' import { ProjectLayout } from '../ProjectLayout' import ObservabilityMenu from './ObservabilityMenu' import { useIndexAdvisorStatus } from '@/components/interfaces/QueryPerformance/hooks/useIsIndexAdvisorStatus' diff --git a/apps/studio/components/layouts/ProjectLayout/index.tsx b/apps/studio/components/layouts/ProjectLayout/index.tsx index 535bbcc1736..39cbcc52ad1 100644 --- a/apps/studio/components/layouts/ProjectLayout/index.tsx +++ b/apps/studio/components/layouts/ProjectLayout/index.tsx @@ -318,7 +318,7 @@ const MenuBarWrapper = ({ return !isLoading && productMenu && showMenuBar ? children : null } -interface ContentWrapperProps { +export interface ContentWrapperProps { isLoading: boolean isBlocking?: boolean children: ReactNode @@ -336,7 +336,7 @@ interface ContentWrapperProps { * * [TODO] Next iteration should scrape long polling and just listen to the project's status */ -const ContentWrapper = ({ isLoading, isBlocking = true, children }: ContentWrapperProps) => { +export const ContentWrapper = ({ isLoading, isBlocking = true, children }: ContentWrapperProps) => { const router = useRouter() const { ref } = useParams() const state = useDatabaseSelectorStateSnapshot() diff --git a/apps/studio/components/layouts/ProjectSettingsLayout/SettingsLayout.tsx b/apps/studio/components/layouts/ProjectSettingsLayout/SettingsLayout.tsx index 3d65a6d0d99..f0a7f906c1b 100644 --- a/apps/studio/components/layouts/ProjectSettingsLayout/SettingsLayout.tsx +++ b/apps/studio/components/layouts/ProjectSettingsLayout/SettingsLayout.tsx @@ -1,7 +1,7 @@ import { useRouter } from 'next/router' import type { PropsWithChildren } from 'react' -import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayoutV2' +import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayout' import { ProjectLayout } from '../ProjectLayout' import { useGenerateSettingsMenu } from './SettingsMenu.utils' import { useIsNavigationV2Enabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' diff --git a/apps/studio/components/layouts/RealtimeLayout/RealtimeLayout.tsx b/apps/studio/components/layouts/RealtimeLayout/RealtimeLayout.tsx index 233da06bb1d..78a323e9846 100644 --- a/apps/studio/components/layouts/RealtimeLayout/RealtimeLayout.tsx +++ b/apps/studio/components/layouts/RealtimeLayout/RealtimeLayout.tsx @@ -2,7 +2,7 @@ import { useIsNavigationV2Enabled } from 'components/interfaces/App/FeaturePrevi import { useRouter } from 'next/router' import type { PropsWithChildren } from 'react' -import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayoutV2' +import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayout' import { ProjectLayout } from '../ProjectLayout' import { generateRealtimeMenu } from './RealtimeMenu.utils' import { ProductMenu } from '@/components/ui/ProductMenu' diff --git a/apps/studio/components/layouts/StorageLayout/StorageLayout.tsx b/apps/studio/components/layouts/StorageLayout/StorageLayout.tsx index c3284090b96..a307eb5d4cf 100644 --- a/apps/studio/components/layouts/StorageLayout/StorageLayout.tsx +++ b/apps/studio/components/layouts/StorageLayout/StorageLayout.tsx @@ -1,6 +1,6 @@ import type { ReactNode } from 'react' -import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayoutV2' +import { ProjectLayoutV2 } from '../NavigationV2/ProjectLayout' import { ProjectLayout } from '../ProjectLayout' import { useIsNavigationV2Enabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { StorageMenuV2 } from '@/components/interfaces/Storage/StorageMenuV2' diff --git a/packages/ui/src/components/shadcn/ui/resizable.tsx b/packages/ui/src/components/shadcn/ui/resizable.tsx index edf21635279..d8ed45b9ac1 100644 --- a/packages/ui/src/components/shadcn/ui/resizable.tsx +++ b/packages/ui/src/components/shadcn/ui/resizable.tsx @@ -113,4 +113,4 @@ const ResizableHandle = ({ const useDefaultLayout = ResizablePrimitive.useDefaultLayout const usePanelRef = ResizablePrimitive.usePanelRef -export { ResizableHandle, ResizablePanel, ResizablePanelGroup, type, useDefaultLayout, usePanelRef } +export { ResizableHandle, ResizablePanel, ResizablePanelGroup, useDefaultLayout, usePanelRef }