mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
Allow project subscription pages to load irregardless of project details
This commit is contained in:
1 parent
2cf4e5f3f7
commit
327b082a77
9 files changed
+55
-49
No files matched your search
@@ -6,7 +6,6 @@ import SubscriptionTier from './Tier/SubscriptionTier'
|
||||
import { SUBSCRIPTION_PANEL_KEYS, useSubscriptionPageStateSnapshot } from 'state/subscription-page'
|
||||
import { useSelectedOrganization } from 'hooks'
|
||||
import { useEffect } from 'react'
|
||||
import ProjectBackupsStore from 'stores/project/ProjectBackupsStore'
|
||||
|
||||
export interface SubscriptionProps {}
|
||||
|
||||
@@ -51,13 +50,15 @@ const Subscription = ({}: SubscriptionProps) => {
|
||||
}
|
||||
}, [router, organization?.slug, isOrgBilling])
|
||||
|
||||
useEffect(() => {
|
||||
if (panel && typeof panel === 'string' && allowedValues.includes(panel)) {
|
||||
snap.setPanelKey(panel as SUBSCRIPTION_PANEL_KEYS)
|
||||
}
|
||||
}, [panel])
|
||||
|
||||
// No need to bother rendering, we'll redirect anyway
|
||||
if (isOrgBilling) return null
|
||||
|
||||
if (panel && typeof panel === 'string' && allowedValues.includes(panel)) {
|
||||
snap.setPanelKey(panel as SUBSCRIPTION_PANEL_KEYS)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="border-b">
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useQueryClient } from '@tanstack/react-query'
|
||||
import clsx from 'clsx'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
|
||||
import { useParams, useTheme } from 'common'
|
||||
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
|
||||
@@ -356,8 +356,8 @@ const ComputeInstanceSidePanel = () => {
|
||||
|
||||
{selectedCategory === 'micro' && (
|
||||
<p className="text-sm text-scale-1100">
|
||||
Your database will use the standard Micro size instance of 2-core {cpuArchitecture} CPU (Shared)
|
||||
with 1GB of memory.
|
||||
Your database will use the standard Micro size instance of 2-core {cpuArchitecture}{' '}
|
||||
CPU (Shared) with 1GB of memory.
|
||||
</p>
|
||||
)}
|
||||
|
||||
|
||||
@@ -17,6 +17,26 @@ import ProjectPausedState from './ProjectPausedState'
|
||||
import RestoringState from './RestoringState'
|
||||
import UpgradingState from './UpgradingState'
|
||||
|
||||
// [Joshen] This is temporary while we unblock users from managing their project
|
||||
// if their project is not responding well for any reason. Eventually needs a bit of an overhaul
|
||||
const routesToIgnoreProjectDetailsRequest = [
|
||||
'/project/[ref]/settings/general',
|
||||
'/project/[ref]/settings/database',
|
||||
'/project/[ref]/settings/storage',
|
||||
'/project/[ref]/settings/billing/subscription',
|
||||
'/project/[ref]/settings/billing/usage',
|
||||
'/project/[ref]/settings/billing/invoices',
|
||||
]
|
||||
|
||||
const routesToIgnorePostgrestConnection = [
|
||||
'/project/[ref]/reports',
|
||||
'/project/[ref]/settings/general',
|
||||
'/project/[ref]/settings/database',
|
||||
'/project/[ref]/settings/billing/subscription',
|
||||
'/project/[ref]/settings/billing/usage',
|
||||
'/project/[ref]/settings/billing/invoices',
|
||||
]
|
||||
|
||||
export interface ProjectLayoutProps {
|
||||
title?: string
|
||||
isLoading?: boolean
|
||||
@@ -108,8 +128,14 @@ interface MenuBarWrapperProps {
|
||||
}
|
||||
|
||||
const MenuBarWrapper = ({ isLoading, productMenu, children }: MenuBarWrapperProps) => {
|
||||
const router = useRouter()
|
||||
const selectedProject = useSelectedProject()
|
||||
return <>{!isLoading && productMenu && selectedProject !== undefined ? children : null}</>
|
||||
const requiresProjectDetails = !routesToIgnoreProjectDetailsRequest.includes(router.pathname)
|
||||
|
||||
const showMenuBar =
|
||||
!requiresProjectDetails || (requiresProjectDetails && selectedProject !== undefined)
|
||||
|
||||
return <>{!isLoading && productMenu && showMenuBar ? children : null}</>
|
||||
}
|
||||
|
||||
interface ContentWrapperProps {
|
||||
@@ -133,17 +159,9 @@ const ContentWrapper = ({ isLoading, children }: ContentWrapperProps) => {
|
||||
const selectedProject = useSelectedProject()
|
||||
const router = useRouter()
|
||||
|
||||
const routesToIgnorePostgrestConnection = [
|
||||
'/project/[ref]/reports',
|
||||
'/project/[ref]/settings/general',
|
||||
'/project/[ref]/settings/database',
|
||||
'/project/[ref]/settings/billing/subscription',
|
||||
'/project/[ref]/settings/billing/usage',
|
||||
'/project/[ref]/settings/billing/invoices',
|
||||
]
|
||||
|
||||
const requiresDbConnection: boolean = router.pathname !== '/project/[ref]/settings/general'
|
||||
const requiresPostgrestConnection = !routesToIgnorePostgrestConnection.includes(router.pathname)
|
||||
const requiresProjectDetails = !routesToIgnoreProjectDetailsRequest.includes(router.pathname)
|
||||
|
||||
const isProjectUpgrading = selectedProject?.status === PROJECT_STATUS.UPGRADING
|
||||
const isProjectRestoring = selectedProject?.status === PROJECT_STATUS.RESTORING
|
||||
@@ -155,7 +173,7 @@ const ContentWrapper = ({ isLoading, children }: ContentWrapperProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{isLoading || selectedProject === undefined ? (
|
||||
{isLoading || (requiresProjectDetails && selectedProject === undefined) ? (
|
||||
<Connecting />
|
||||
) : isProjectUpgrading ? (
|
||||
<UpgradingState />
|
||||
@@ -168,7 +186,7 @@ const ContentWrapper = ({ isLoading, children }: ContentWrapperProps) => {
|
||||
) : requiresDbConnection && isProjectBuilding ? (
|
||||
<BuildingState project={selectedProject} />
|
||||
) : (
|
||||
<Fragment key={selectedProject.ref}>{children}</Fragment>
|
||||
<Fragment key={selectedProject?.ref}>{children}</Fragment>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
import { FC, ReactNode, useEffect } from 'react'
|
||||
import { useFlag, useSelectedOrganization, useSelectedProject, useStore, withAuth } from 'hooks'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useFlag, useSelectedOrganization, useSelectedProject, useStore, withAuth } from 'hooks'
|
||||
import { PropsWithChildren, useEffect } from 'react'
|
||||
import { generateSettingsMenu } from './SettingsMenu.utils'
|
||||
|
||||
import ProjectLayout from '../'
|
||||
import { useParams } from 'common'
|
||||
import ProductMenu from 'components/ui/ProductMenu'
|
||||
import ProjectLayout from '../'
|
||||
|
||||
interface Props {
|
||||
interface SettingsLayoutProps {
|
||||
title?: string
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
const SettingsLayout: FC<Props> = ({ title, children }) => {
|
||||
const SettingsLayout = ({ title, children }: PropsWithChildren<SettingsLayoutProps>) => {
|
||||
const { ref } = useParams()
|
||||
const { ui, meta } = useStore()
|
||||
const project = useSelectedProject()
|
||||
const organization = useSelectedOrganization()
|
||||
@@ -26,12 +27,7 @@ const SettingsLayout: FC<Props> = ({ title, children }) => {
|
||||
: router.pathname.split('/')[4]
|
||||
|
||||
const isVaultEnabled = useFlag('vaultExtension')
|
||||
const menuRoutes = generateSettingsMenu(
|
||||
project?.ref as string,
|
||||
project,
|
||||
isVaultEnabled,
|
||||
isOrgBilling
|
||||
)
|
||||
const menuRoutes = generateSettingsMenu(ref, project, isVaultEnabled, isOrgBilling)
|
||||
|
||||
useEffect(() => {
|
||||
if (ui.selectedProjectRef) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { IS_PLATFORM, PROJECT_STATUS } from 'lib/constants'
|
||||
import { ProductMenuGroup } from 'components/ui/ProductMenu/ProductMenu.types'
|
||||
|
||||
export const generateSettingsMenu = (
|
||||
ref: string,
|
||||
ref?: string,
|
||||
project?: ProjectBase,
|
||||
isVaultEnabled: boolean = false,
|
||||
isOrgBilling: boolean = false
|
||||
|
||||
@@ -9,6 +9,7 @@ import { useCheckPermissions, useStore } from 'hooks'
|
||||
import { IS_PLATFORM } from 'lib/constants'
|
||||
import { STORAGE_FILE_SIZE_LIMIT_MAX_BYTES, StorageSizeUnits } from './StorageSettings.constants'
|
||||
import { convertFromBytes, convertToBytes } from './StorageSettings.utils'
|
||||
import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
|
||||
|
||||
export type StorageSettingsProps = {
|
||||
projectRef: string | undefined
|
||||
@@ -27,8 +28,8 @@ const StorageSettings = ({ projectRef }: StorageSettingsProps) => {
|
||||
|
||||
if (!data) {
|
||||
return (
|
||||
<div className="p-6 mx-auto text-center sm:w-full md:w-3/4">
|
||||
<p className="text-sm">Loading...</p>
|
||||
<div className="w-full">
|
||||
<GenericSkeletonLoader />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ const ProjectUpgradeFailedBanner = () => {
|
||||
const { target_version, status, initiated_at, error } = data?.databaseUpgradeStatus ?? {}
|
||||
|
||||
const key = `supabase-upgrade-${ref}-${initiated_at}`
|
||||
const isAcknowledged = localStorage?.getItem(key) === 'true' ?? false
|
||||
const isAcknowledged =
|
||||
typeof window !== 'undefined' ? localStorage?.getItem(key) === 'true' ?? false : false
|
||||
const [showMessage, setShowMessage] = useState(!isAcknowledged)
|
||||
|
||||
const isFailed = status === DatabaseUpgradeStatus.Failed
|
||||
|
||||
@@ -8,16 +8,10 @@ import { projectKeys } from './keys'
|
||||
export type ProjectDetailVariables = { ref?: string }
|
||||
|
||||
export async function getProjectDetail({ ref }: ProjectDetailVariables, signal?: AbortSignal) {
|
||||
if (!ref) {
|
||||
throw new Error('Project ref is required')
|
||||
}
|
||||
if (!ref) throw new Error('Project ref is required')
|
||||
|
||||
const data = await get<Project>(`${API_URL}/projects/${ref}`, { signal })
|
||||
|
||||
if (!isResponseOk(data)) {
|
||||
throw data.error
|
||||
}
|
||||
|
||||
if (!isResponseOk(data)) throw data.error
|
||||
return data
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@ import { post } from 'lib/common/fetch'
|
||||
import { API_URL, PROJECT_STATUS } from 'lib/constants'
|
||||
import { NextPageWithLayout } from 'types'
|
||||
|
||||
/**
|
||||
* PageLayout is used to setup layout - as usual it will requires inject global store
|
||||
*/
|
||||
const PageLayout: NextPageWithLayout = () => {
|
||||
const { ref: projectRef } = useParams()
|
||||
const { project } = useProjectContext()
|
||||
@@ -21,8 +18,6 @@ const PageLayout: NextPageWithLayout = () => {
|
||||
}
|
||||
}, [project])
|
||||
|
||||
if (!project) return <div></div>
|
||||
|
||||
return (
|
||||
<div className="flex flex-grow p-4 storage-container">
|
||||
<StorageSettings projectRef={projectRef} />
|
||||
|
||||
Reference in new issue
Block a user