Files
supabase/apps/studio/components/interfaces/Storage/BucketsUpgradePlan.tsx
Ali WaseemandJoshen Lim a1c7e57df3 studio: clarify storage bucket upgrade message for Pro users on Nano compute (#46008)
## Summary

Vector and analytics bucket access is gated by both the org's plan tier
and the project's compute size, but the storage config API only returns
a single `enabled: false` flag. The empty state always told users to
"Upgrade to Pro" — including users who were already on Pro with Nano
compute, leaving them no obvious path forward.

`BucketsUpgradePlan` now reads the org plan and the project's
`infra_compute_size`. When the user is on a paid plan but still on Nano
compute, the message becomes "Upgrade your project's compute size to
Micro or larger…" and the button is wired through `UpgradePlanButton`'s
existing `addon='computeSize'` route to `/settings/compute-and-disk`.
Free plan users keep the existing copy and upgrade flow.

Closes FE-3383.

## Test plan

- [ ] Free org, Nano compute, navigate to `/storage/vectors`: still
shows "Upgrade to Pro" with the billing link
- [ ] Pro org, Nano compute, navigate to `/storage/vectors`: shows the
compute-size message and the button navigates to compute-and-disk
settings
- [ ] Pro org, Micro+ compute: page renders the actual Vector buckets UI
(unchanged)
- [ ] Same flows on `/storage/analytics`

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a regional limitation notice for Vector Buckets with an
informational "Coming soon" empty state and tooltip listing available
regions.

* **Bug Fixes**
* Storage bucket upgrade prompts now show context-aware messaging based
on organization plan and project settings, guiding users to the correct
upgrade path.

* **Refactor**
* Region-gating UI logic consolidated into a shared component for
clearer messaging and maintenance.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46008?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-05-20 04:32:21 +00:00

76 lines
3.0 KiB
TypeScript

import { useParams } from 'common'
import { AnalyticsBucket as AnalyticsBucketIcon, VectorBucket as VectorBucketIcon } from 'icons'
import { EmptyStatePresentational } from 'ui-patterns'
import { PageContainer } from 'ui-patterns/PageContainer'
import { PageSection, PageSectionContent } from 'ui-patterns/PageSection'
import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
import { BUCKET_TYPES } from './Storage.constants'
import { AlphaNotice } from '@/components/ui/AlphaNotice'
import { UpgradePlanButton } from '@/components/ui/UpgradePlanButton'
import { useProjectStorageConfigQuery } from '@/data/config/project-storage-config-query'
import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
export const BucketsUpgradePlan = ({ type }: { type: 'analytics' | 'vector' }) => {
const { ref: projectRef } = useParams()
const { isLoading: isLoadingStorageConfig } = useProjectStorageConfigQuery({ projectRef })
const { data: organization, isLoading: isLoadingOrganization } = useSelectedOrganizationQuery()
const { data: project, isLoading: isLoadingProject } = useSelectedProjectQuery()
const isLoading =
isLoadingStorageConfig || isLoadingOrganization || isLoadingProject || !organization || !project
if (isLoading) {
return (
<PageContainer>
<PageSection>
<PageSectionContent className="flex flex-col gap-y-8">
<GenericSkeletonLoader />
</PageSectionContent>
</PageSection>
</PageContainer>
)
}
const isFreePlan = organization.plan?.id === 'free'
const isNanoCompute = project.infra_compute_size === 'nano'
const requiresComputeUpgrade = !isFreePlan && isNanoCompute
return (
<PageContainer>
<PageSection>
<PageSectionContent className="flex flex-col gap-y-8">
<AlphaNotice
entity={type === 'analytics' ? 'Analytics buckets' : 'Vector buckets'}
feedbackUrl={
type === 'analytics'
? 'https://github.com/orgs/supabase/discussions/40116'
: 'https://github.com/orgs/supabase/discussions/40815'
}
/>
<EmptyStatePresentational
icon={type === 'analytics' ? AnalyticsBucketIcon : VectorBucketIcon}
title={
type === 'analytics'
? BUCKET_TYPES.analytics.valueProp
: BUCKET_TYPES.vectors.valueProp
}
description={
requiresComputeUpgrade
? `Upgrade your project's compute size to Micro or larger to use ${type} buckets`
: `Upgrade to Pro to use ${type} buckets for your project`
}
>
<UpgradePlanButton
source={`${type}Buckets`}
featureProposition={`use ${type} buckets`}
addon={requiresComputeUpgrade ? 'computeSize' : undefined}
/>
</EmptyStatePresentational>
</PageSectionContent>
</PageSection>
</PageContainer>
)
}