import { SupportCategories } from '@supabase/shared-types/out/constants' import { useFlag, useParams } from 'common' import { Lock } from 'lucide-react' import { useTheme } from 'next-themes' import Image from 'next/image' import { Alert, AlertDescription, AlertTitle, Badge, Button, Tooltip, TooltipContent, TooltipTrigger, } from 'ui' import { Admonition } from 'ui-patterns' import { PageContainer } from 'ui-patterns/PageContainer' import { PageSection } from 'ui-patterns/PageSection' import { getCustomDomainDisabledReason, getIPv4DisabledReason, getPitrAlertState, getPitrDisabledReason, } from './Addons.utils' import CustomDomainSidePanel from './CustomDomainSidePanel' import IPv4SidePanel from './IPv4SidePanel' import PITRSidePanel from './PITRSidePanel' import { getAddons, subscriptionHasHipaaAddon, } from '@/components/interfaces/Billing/Subscription/Subscription.utils' import { ProjectUpdateDisabledTooltip } from '@/components/interfaces/Organization/BillingSettings/ProjectUpdateDisabledTooltip' import { SupportLink } from '@/components/interfaces/Support/SupportLink' import AlertError from '@/components/ui/AlertError' import { InlineLink } from '@/components/ui/InlineLink' import { ResourceItem } from '@/components/ui/Resource/ResourceItem' import { ResourceList } from '@/components/ui/Resource/ResourceList' import { HorizontalShimmerWithIcon } from '@/components/ui/Shimmers' import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query' import { useOrgSubscriptionQuery } from '@/data/subscriptions/org-subscription-query' import { useProjectAddonsQuery } from '@/data/subscriptions/project-addons-query' import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' import { useIsAwsCloudProvider, useIsOrioleDbInAws, useIsProjectActive, useSelectedProjectQuery, } from '@/hooks/misc/useSelectedProject' import { BASE_PATH, DOCS_URL } from '@/lib/constants' import { getDatabaseMajorVersion, getSemanticVersion } from '@/lib/helpers' import { useAddonsPagePanel } from '@/state/addons-page' export const Addons = () => { const { resolvedTheme } = useTheme() const { ref: projectRef } = useParams() const { setPanel } = useAddonsPagePanel() const isAws = useIsAwsCloudProvider() const isProjectActive = useIsProjectActive() const isOrioleDbInAws = useIsOrioleDbInAws() === true const { projectSettingsCustomDomains, projectAddonsDedicatedIpv4Address } = useIsFeatureEnabled([ 'project_settings:custom_domains', 'project_addons:dedicated_ipv4_address', ]) const { data: selectedOrg } = useSelectedOrganizationQuery() const { data: selectedProject } = useSelectedProjectQuery() const isBranch = selectedProject?.parent_project_ref const { data: settings } = useProjectSettingsV2Query({ projectRef }) const { data: subscription } = useOrgSubscriptionQuery({ orgSlug: selectedOrg?.slug }) const projectUpdateDisabled = useFlag('disableProjectCreationAndUpdate') const hasHipaaAddon = subscriptionHasHipaaAddon(subscription) && settings?.is_sensitive === true // Only projects of version greater than briven-postgrest-14.1.0.44 can use PITR const sufficientPgVersion = // introduced as generatedSemantic version could be < 141044 even if actual version is indeed past it // eg. 15.1.1.2 leads to 15112 getDatabaseMajorVersion(selectedProject?.dbVersion ?? '') > 14 || getSemanticVersion(selectedProject?.dbVersion ?? '') >= 141044 const { data: addons, error, isPending: isLoading, isError, isSuccess, } = useProjectAddonsQuery({ projectRef }) const selectedAddons = addons?.selected_addons ?? [] const { pitr, customDomain, ipv4 } = getAddons(selectedAddons) const canUpdateIPv4 = settings?.db_ip_addr_config === 'ipv6' const ipv4Enabled = ipv4 !== undefined const pitrEnabled = pitr !== undefined const customDomainEnabled = customDomain !== undefined const canOpenIPv4 = isAws && isProjectActive && !projectUpdateDisabled && (canUpdateIPv4 || ipv4Enabled) const canOpenPITR = isProjectActive && !projectUpdateDisabled && sufficientPgVersion && !hasHipaaAddon && !isOrioleDbInAws const canOpenCustomDomain = isProjectActive && !projectUpdateDisabled const ipv4DisabledReason = getIPv4DisabledReason({ isAws, isProjectActive, projectUpdateDisabled, canUpdateIPv4, ipv4Enabled, }) const pitrDisabledReason = getPitrDisabledReason({ isProjectActive, projectUpdateDisabled, hasHipaaAddon, sufficientPgVersion, isOrioleDbInAws, }) const customDomainDisabledReason = getCustomDomainDisabledReason({ isProjectActive, projectUpdateDisabled, }) const pitrAlertState = getPitrAlertState({ hasHipaaAddon, sufficientPgVersion, isOrioleDbInAws, }) const listTopSpacing = isBranch ? 'mt-6' : undefined const resourceItemClassName = 'min-h-[128px] border-b! last:border-b-0! [&>div:first-child]:hidden @lg:[&>div:first-child]:flex' let pitrAlert = null if (pitrAlertState === 'hipaa') { pitrAlert = ( PITR cannot be changed with HIPAA All projects should have PITR enabled by default and cannot be changed with HIPAA enabled. Contact support for further assistance.
) } else if (pitrAlertState === 'legacy-project') { pitrAlert = ( Your project is too old to enable PITR

Reach out to us via support if you're interested

) } else if (pitrAlertState === 'orioledb') { pitrAlert = ( PITR not supported Point in time recovery is not supported with OrioleDB ) } return ( {isBranch && ( Updating add-ons here will only apply to this preview branch. To manage add-ons for your main branch, please visit the{' '} main branch . )} {isLoading && ( {Array.from({ length: 3 }).map((_, index) => (
))} )} {isError && } {isSuccess && ( {projectAddonsDedicatedIpv4Address && ( setPanel('ipv4') : undefined} media={ IPv4 } meta={
{ipv4Enabled ? ( Enabled ) : ( Disabled )}
} >
Dedicated IPv4 address

Reserve a dedicated IPv4 address for your project.

e.stopPropagation()} > About IPv4 deprecation
)} setPanel('pitr') : undefined} media={ PITR } meta={
{pitrEnabled ? ( Enabled ) : ( Disabled )} {!canOpenPITR && pitrDisabledReason && ( {pitrDisabledReason} )}
} >
Point in time recovery

Restore your database to a specific moment in the past.

e.stopPropagation()} > About PITR backups
{pitrAlert} {projectSettingsCustomDomains && ( setPanel('customDomain') : undefined} media={ Custom Domain } meta={
{customDomainEnabled ? ( Enabled ) : ( Disabled )} {!canOpenCustomDomain && customDomainDisabledReason && ( {customDomainDisabledReason} )}
} >
Custom domain

Serve your project on your own domain name.

e.stopPropagation()} > About custom domains
)}
)} ) }