mirror of
https://github.com/supabase/supabase.git
synced 2026-10-10 20:05:06 +03:00
feat: separate concerns
This commit is contained in:
1 parent
e728620a40
commit
e5d2e2b275
4 files changed
+57
-25
No files matched your search
@@ -47,6 +47,12 @@ vi.mock('common', () => ({
|
||||
mergeRefs:
|
||||
(..._refs: any[]) =>
|
||||
(_value: unknown) => {},
|
||||
IS_PLATFORM: false,
|
||||
LOCAL_STORAGE_KEYS: {
|
||||
FREE_MICRO_UPGRADE_BANNER_DISMISSED: (ref: string) =>
|
||||
`free-micro-upgrade-banner-dismissed-${ref}`,
|
||||
},
|
||||
isFeatureEnabled: () => false,
|
||||
}))
|
||||
|
||||
vi.mock('framer-motion', () => ({
|
||||
@@ -121,6 +127,27 @@ vi.mock('@/hooks/custom-content/useCustomContent', () => ({
|
||||
useCustomContent: () => ({ appTitle: 'Supabase' }),
|
||||
}))
|
||||
|
||||
vi.mock('@/hooks/misc/useCheckEntitlements', () => ({
|
||||
useCheckEntitlements: () => ({ hasAccess: false, isLoading: false }),
|
||||
}))
|
||||
|
||||
vi.mock('@/hooks/misc/useLocalStorage', () => ({
|
||||
useLocalStorageQuery: () => [false, vi.fn()],
|
||||
}))
|
||||
|
||||
vi.mock('@/components/ui/BannerStack/BannerStackProvider', () => ({
|
||||
BANNER_ID: { FREE_MICRO_UPGRADE: 'free-micro-upgrade-banner' },
|
||||
useBannerStack: () => ({ addBanner: vi.fn(), dismissBanner: vi.fn(), banners: [] }),
|
||||
}))
|
||||
|
||||
vi.mock('@/components/ui/BannerStack/Banners/BannerFreeMicroUpgrade', () => ({
|
||||
BannerFreeMicroUpgrade: () => null,
|
||||
}))
|
||||
|
||||
vi.mock('data/usage/resource-warnings-query', () => ({
|
||||
useResourceWarningsQuery: () => ({ data: undefined }),
|
||||
}))
|
||||
|
||||
vi.mock('@/hooks/misc/useSelectedOrganization', () => ({
|
||||
useSelectedOrganizationQuery: () => ({
|
||||
data: { name: 'Organization 1', slug: 'org-1' },
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { mergeRefs, useParams } from 'common'
|
||||
import { LOCAL_STORAGE_KEYS, mergeRefs, useParams } from 'common'
|
||||
import { useResourceWarningsQuery } from 'data/usage/resource-warnings-query'
|
||||
import { AnimatePresence, motion } from 'framer-motion'
|
||||
import Head from 'next/head'
|
||||
import { useRouter } from 'next/router'
|
||||
@@ -45,10 +46,8 @@ import { useCustomContent } from '@/hooks/custom-content/useCustomContent'
|
||||
import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
|
||||
import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
|
||||
import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
|
||||
import { useResourceWarningsQuery } from 'data/usage/resource-warnings-query'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { withAuth } from '@/hooks/misc/withAuth'
|
||||
import { LOCAL_STORAGE_KEYS } from 'common'
|
||||
import { PROJECT_STATUS } from '@/lib/constants'
|
||||
import { buildStudioPageTitle } from '@/lib/page-title'
|
||||
import { getPathnameWithoutQuery } from '@/lib/pathname.utils'
|
||||
@@ -126,11 +125,11 @@ export const ProjectLayout = forwardRef<HTMLDivElement, PropsWithChildren<Projec
|
||||
)
|
||||
const isComputeNearExhaustion =
|
||||
!!projectResourceWarnings?.cpu_exhaustion ||
|
||||
!!projectResourceWarnings?.memory_and_swap_exhaustion
|
||||
!!projectResourceWarnings?.memory_and_swap_exhaustion ||
|
||||
!!projectResourceWarnings?.disk_space_exhaustion
|
||||
const isEligibleForFreeUpgrade =
|
||||
entitledUpdateCompute &&
|
||||
selectedProject?.infra_compute_size === 'nano' &&
|
||||
isComputeNearExhaustion
|
||||
entitledUpdateCompute && selectedProject?.infra_compute_size === 'nano'
|
||||
const showUpgradeBanner = isEligibleForFreeUpgrade && isComputeNearExhaustion
|
||||
const [isFreeMicroUpgradeBannerDismissed] = useLocalStorageQuery(
|
||||
LOCAL_STORAGE_KEYS.FREE_MICRO_UPGRADE_BANNER_DISMISSED(selectedProject?.ref ?? ''),
|
||||
false
|
||||
@@ -180,7 +179,7 @@ export const ProjectLayout = forwardRef<HTMLDivElement, PropsWithChildren<Projec
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedProject?.ref) return
|
||||
if (isEligibleForFreeUpgrade && !isFreeMicroUpgradeBannerDismissed) {
|
||||
if (showUpgradeBanner && !isFreeMicroUpgradeBannerDismissed) {
|
||||
addBanner({
|
||||
id: BANNER_ID.FREE_MICRO_UPGRADE,
|
||||
isDismissed: false,
|
||||
@@ -192,7 +191,7 @@ export const ProjectLayout = forwardRef<HTMLDivElement, PropsWithChildren<Projec
|
||||
}
|
||||
}, [
|
||||
selectedProject?.ref,
|
||||
isEligibleForFreeUpgrade,
|
||||
showUpgradeBanner,
|
||||
isFreeMicroUpgradeBannerDismissed,
|
||||
addBanner,
|
||||
dismissBanner,
|
||||
|
||||
@@ -41,10 +41,10 @@ export const BannerFreeMicroUpgrade = () => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-y-1 mb-2">
|
||||
<p className="text-sm font-medium">Free upgrade to Micro available</p>
|
||||
<p className="text-sm font-medium">Your project is running low on resources</p>
|
||||
<p className="text-xs text-foreground-lighter text-balance">
|
||||
Your Pro plan includes a free upgrade from Nano to Micro — double the memory at no extra
|
||||
cost.
|
||||
Your Nano compute is approaching its limits. Upgrade to Micro for free — it's included
|
||||
in your Pro plan.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
|
||||
@@ -106,30 +106,32 @@ export const ComputeBadgeWrapper = ({
|
||||
const isEligibleForFreeUpgrade = !!data && data.plan.id !== 'free' && computeSize === 'nano'
|
||||
const isLoading = isLoadingAddons || isLoadingSubscriptions
|
||||
const isComputeNearExhaustion =
|
||||
!!resourceWarnings?.cpu_exhaustion || !!resourceWarnings?.memory_and_swap_exhaustion
|
||||
const hasUpgradeAvailable = (isFreeOnNano || isEligibleForFreeUpgrade) && isComputeNearExhaustion
|
||||
!!resourceWarnings?.cpu_exhaustion ||
|
||||
!!resourceWarnings?.memory_and_swap_exhaustion ||
|
||||
!!resourceWarnings?.disk_space_exhaustion
|
||||
const showUpgradeGlow = isEligibleForFreeUpgrade && isComputeNearExhaustion
|
||||
|
||||
if (!computeSize) return null
|
||||
|
||||
return (
|
||||
<HoverCard onOpenChange={() => setOpenState(!open)} openDelay={280}>
|
||||
<HoverCardTrigger asChild className="group" onClick={(e) => e.stopPropagation()}>
|
||||
<div className={cn('flex items-center', hasUpgradeAvailable && 'animate-badge-pulse')}>
|
||||
<div className={cn('flex items-center', showUpgradeGlow && 'animate-badge-pulse')}>
|
||||
<div
|
||||
className={cn(
|
||||
'flex',
|
||||
hasUpgradeAvailable && 'relative inline-flex overflow-hidden rounded'
|
||||
showUpgradeGlow && 'relative inline-flex overflow-hidden rounded'
|
||||
)}
|
||||
>
|
||||
<ComputeBadge
|
||||
infraComputeSize={computeSize}
|
||||
icon={hasUpgradeAvailable && <ChevronsUpAnimated />}
|
||||
icon={showUpgradeGlow && <ChevronsUpAnimated />}
|
||||
className={cn(
|
||||
hasUpgradeAvailable && 'text-brand-600 border-brand-500 bg-brand/10 gap-1',
|
||||
showUpgradeGlow && 'text-brand-600 border-brand-500 bg-brand/10 gap-1',
|
||||
badgeClassName
|
||||
)}
|
||||
/>
|
||||
{hasUpgradeAvailable && (
|
||||
{showUpgradeGlow && (
|
||||
<span className="animate-badge-shimmer pointer-events-none absolute inset-0 bg-gradient-to-br from-transparent via-brand/20 to-transparent blur-md" />
|
||||
)}
|
||||
</div>
|
||||
@@ -186,16 +188,20 @@ export const ComputeBadgeWrapper = ({
|
||||
<p className="text-foreground">
|
||||
{isFreeOnNano
|
||||
? 'Double your memory for free'
|
||||
: isEligibleForFreeUpgrade
|
||||
? 'Free upgrade to Micro available'
|
||||
: 'Unlock more compute'}
|
||||
: isEligibleForFreeUpgrade && isComputeNearExhaustion
|
||||
? 'Your project is running low on resources'
|
||||
: isEligibleForFreeUpgrade
|
||||
? 'Free upgrade to Micro available'
|
||||
: 'Unlock more compute'}
|
||||
</p>
|
||||
<p className="text-foreground-light">
|
||||
{isFreeOnNano
|
||||
? 'Upgrade to Pro and get a free Micro compute upgrade — double the memory at no extra cost.'
|
||||
: isEligibleForFreeUpgrade
|
||||
? 'Your Pro plan includes a free upgrade from Nano to Micro compute.'
|
||||
: 'Scale your project up to 64 cores and 256 GB RAM.'}
|
||||
: isEligibleForFreeUpgrade && isComputeNearExhaustion
|
||||
? 'Your Nano compute is approaching its limits. Your Pro plan includes a free upgrade to Micro — double the memory at no extra cost.'
|
||||
: isEligibleForFreeUpgrade
|
||||
? 'Your Pro plan includes a free upgrade from Nano to Micro compute.'
|
||||
: 'Scale your project up to 64 cores and 256 GB RAM.'}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
Reference in new issue
Block a user