Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { PermissionAction } from '@supabase/shared-types/out/constants'
import { useParams } from 'common'
import { AnimatePresence, motion } from 'framer-motion'
import { ChevronRight } from 'lucide-react'
import { useEffect, useState } from 'react'
import { useEffect, useRef, useState } from 'react'
import { useForm } from 'react-hook-form'
import { CloudProvider } from 'shared-data'
import { toast } from 'sonner'
Expand All @@ -13,6 +13,7 @@ import {
Collapsible_Shadcn_,
CollapsibleContent_Shadcn_,
CollapsibleTrigger_Shadcn_,
DialogSectionSeparator,
Form,
Separator,
} from 'ui'
Expand Down Expand Up @@ -77,6 +78,8 @@ export function DiskManagementForm() {
const { data: org } = useSelectedOrganizationQuery()
const { setProjectStatus } = useSetProjectStatus()

const advancedSettingsRef = useRef<HTMLDivElement>(null)

const isSpendCapEnabled =
org?.plan.id !== 'free' && !org?.usage_billing_enabled && project?.cloud_provider !== 'FLY'

Expand Down Expand Up @@ -163,43 +166,8 @@ export function DiskManagementForm() {
reValidateMode: 'onChange',
})

useEffect(() => {
if (!isDiskAttributesSuccess) return
// @ts-ignore
const { type, iops, throughput_mbps, size_gb } = data?.attributes ?? { size_gb: 0 }
const formValues = {
storageType: type,
provisionedIOPS: iops,
throughput: throughput_mbps,
totalSize: size_gb,
computeSize: form.getValues('computeSize'),
}

if (!('requested_modification' in data)) {
if (refetchInterval !== false) {
form.reset(formValues)
setRefetchInterval(false)
toast.success('Disk configuration changes have been successfully applied!')
}
} else {
setRefetchInterval(2000)
}
}, [data, isDiskAttributesSuccess, form, refetchInterval])

const { computeSize: modifiedComputeSize } = form.watch()

// We only support disk configurations for >=Large instances
// If a customer downgrades back to <Large, we should reset the storage settings to avoid incurring unnecessary costs
useEffect(() => {
if (modifiedComputeSize && project?.infra_compute_size && isDialogOpen) {
if (RESTRICTED_COMPUTE_FOR_THROUGHPUT_ON_GP3.includes(modifiedComputeSize)) {
form.setValue('storageType', DiskType.GP3)
form.setValue('throughput', DISK_LIMITS['gp3'].minThroughput)
form.setValue('provisionedIOPS', DISK_LIMITS['gp3'].minIops)
}
}
}, [modifiedComputeSize, isDialogOpen, project])

const isSuccess =
isAddonsSuccess &&
isDiskAttributesSuccess &&
Expand All @@ -213,6 +181,7 @@ export function DiskManagementForm() {
const isPlanUpgradeRequired = !hasAccess

const { formState } = form
const errors = formState.errors
const usedSize = Math.round(((diskUtil?.metrics.fs_used_bytes ?? 0) / GB) * 100) / 100
const totalSize = formState.defaultValues?.totalSize || 0
const usedPercentage = (usedSize / totalSize) * 100
Expand Down Expand Up @@ -328,6 +297,41 @@ export function DiskManagementForm() {
}
}

useEffect(() => {
if (!isDiskAttributesSuccess) return
// @ts-ignore
const { type, iops, throughput_mbps, size_gb } = data?.attributes ?? { size_gb: 0 }
const formValues = {
storageType: type,
provisionedIOPS: iops,
throughput: throughput_mbps,
totalSize: size_gb,
computeSize: form.getValues('computeSize'),
}

if (!('requested_modification' in data)) {
if (refetchInterval !== false) {
form.reset(formValues)
setRefetchInterval(false)
toast.success('Disk configuration changes have been successfully applied!')
}
} else {
setRefetchInterval(2000)
}
}, [data, isDiskAttributesSuccess, form, refetchInterval])

// We only support disk configurations for >=Large instances
// If a customer downgrades back to <Large, we should reset the storage settings to avoid incurring unnecessary costs
useEffect(() => {
if (modifiedComputeSize && project?.infra_compute_size && isDialogOpen) {
if (RESTRICTED_COMPUTE_FOR_THROUGHPUT_ON_GP3.includes(modifiedComputeSize)) {
form.setValue('storageType', DiskType.GP3)
form.setValue('throughput', DISK_LIMITS['gp3'].minThroughput)
form.setValue('provisionedIOPS', DISK_LIMITS['gp3'].minIops)
}
}
}, [modifiedComputeSize, isDialogOpen, project])

useEffect(() => {
// Initialize field values properly when data has been loaded, preserving any user changes
if (isDiskAttributesSuccess || isSuccess) {
Expand All @@ -336,6 +340,26 @@ export function DiskManagementForm() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isSuccess, isDiskAttributesSuccess])

useEffect(() => {
const fieldErrors = Object.keys(errors)
if (fieldErrors.length > 0) {
if (
fieldErrors.includes('throughput') ||
fieldErrors.includes('provisionedIOPS') ||
fieldErrors.includes('maxSizeGb')
) {
setAdvancedSettingsOpenState(true)

// [Joshen] The timeout is to let the collapsible open prior to scrolling
const timeoutId = setTimeout(() => {
advancedSettingsRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' })
}, 100)

return () => clearTimeout(timeoutId)
}
}
}, [errors])

return (
<>
<ScaffoldContainer className="relative flex flex-col gap-10" bottomPadding>
Expand Down Expand Up @@ -447,8 +471,6 @@ export function DiskManagementForm() {
<Separator />

<Collapsible_Shadcn_
// TO DO: wrap component into pattern
className="-space-y-px"
open={advancedSettingsOpen}
onOpenChange={() => setAdvancedSettingsOpenState((prev) => !prev)}
>
Expand All @@ -467,16 +489,17 @@ export function DiskManagementForm() {
/>
</CollapsibleTrigger_Shadcn_>
<CollapsibleContent_Shadcn_
ref={advancedSettingsRef}
className={cn(
'transition-all rounded-b',
'data-open:border data-closed:animate-collapsible-up data-open:animate-collapsible-down'
'border border-t-0 data-closed:animate-collapsible-up data-open:animate-collapsible-down'
)}
>
<div className="flex flex-col gap-y-8 py-8">
<div className="px-card flex flex-col gap-y-8">
<AutoScaleFields form={form} />
</div>
<Separator />
<DialogSectionSeparator />
<div className="px-card flex flex-col gap-y-8">
<NoticeBar
type="default"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useQuery } from '@tanstack/react-query'
import { FeatureFlagContext, IS_PLATFORM, useFlag } from 'common'
import { fullImageUrl } from 'common/marketplace-client'
import { Boxes } from 'lucide-react'
import dynamic from 'next/dynamic'
import Image from 'next/image'
Expand All @@ -11,11 +12,6 @@ import { marketplaceIntegrationsQueryOptions } from '@/data/marketplace/integrat
import { useCLIReleaseVersionQuery } from '@/data/misc/cli-release-version-query'
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'

const fullImageUrl = (imagePath: string) => {
const API_URL = process.env.NEXT_PUBLIC_MARKETPLACE_API_URL || ''
return `${API_URL}${imagePath}`
}

/**
* [Joshen] Returns a combination of
* - Marketplace integrations retrieved remotely (Only if feature flag enabled)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { ExternalLink } from 'lucide-react'
import { useTheme } from 'next-themes'
import Image from 'next/image'
import Link from 'next/link'
import { Alert, Alert_Shadcn_, AlertTitle_Shadcn_, Button } from 'ui'
import { Alert_Shadcn_, AlertTitle_Shadcn_, Button } from 'ui'
import { Admonition } from 'ui-patterns/admonition'
import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'

import { ProjectUpdateDisabledTooltip } from '../ProjectUpdateDisabledTooltip'
Expand Down Expand Up @@ -118,23 +119,28 @@ const CostControl = ({}: CostControlProps) => {
{isSuccess && !costControlDisabled && (
<div className="space-y-6">
{['team', 'enterprise', 'platform'].includes(currentPlan?.id || '') ? (
<Alert
withIcon
variant="info"
title={`You will be charged for any additional usage on the ${
currentPlan?.name || ''
} plan`}
>
{currentPlan?.name || ''} plan requires you to have spend cap off at all
times. Your projects will never become unresponsive. Only when your{' '}
<Link
href={`/org/${slug}/usage`}
className="text-green-900 transition hover:text-green-1000"
>
included usage
</Link>{' '}
is exceeded will you be charged for any additional usage.
</Alert>
<>
<Admonition
type="default"
layout="horizontal"
title={`You will be charged for any additional usage on the ${
currentPlan?.name || ''
} plan`}
description={
<>
{currentPlan?.name || ''} plan requires you to have spend cap off at all
times. Your projects will never become unresponsive. Only when your{' '}
<Link
href={`/org/${slug}/usage`}
className="text-green-900 transition hover:text-green-1000"
>
included usage
</Link>{' '}
is exceeded will you be charged for any additional usage.
</>
}
/>
</>
) : (
<p className="text-sm text-foreground-light">
If you need to go beyond the included quota, simply switch off your spend cap
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ export const ExitSurveyModal = ({ visible, projects, onClose }: ExitSurveyModalP
</div>
{hasProjectsWithComputeDowngrade && (
<Admonition
layout="horizontal"
type="warning"
layout="horizontal"
title={`${projectsWithComputeDowngrade.length} of your projects will be restarted upon clicking confirm,`}
description={
<>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { PermissionAction, SupportCategories } from '@supabase/shared-types/out/constants'
import { useFlag, useParams } from 'common'
import Link from 'next/link'
import { Alert, Button } from 'ui'
import { Admonition } from 'ui-patterns'
import { Button } from 'ui'
import { Admonition } from 'ui-patterns/admonition'
import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'

import { ProjectUpdateDisabledTooltip } from '../ProjectUpdateDisabledTooltip'
Expand Down Expand Up @@ -95,22 +95,20 @@ const Subscription = () => {
</Button>
</ProjectUpdateDisabledTooltip>
) : projectUpdateDisabled ? (
<Alert
className="mt-2"
withIcon
variant="info"
<Admonition
type="default"
layout="horizontal"
title={`Unable to update plan from ${planName}`}
>
We have temporarily disabled project and subscription changes - our
engineers are working on a fix.
</Alert>
description="We have temporarily disabled project and subscription changes - our
engineers are working on a fix."
/>
) : (
<Alert
withIcon
className="mt-2"
variant="info"
<Admonition
type="default"
layout="horizontal"
title={`Unable to update plan from ${planName}`}
actions={[
description="Please contact us if you'd like to change your plan."
actions={
<Button asChild key="contact-support" type="default">
<SupportLink
queryParams={{
Expand All @@ -120,11 +118,9 @@ const Subscription = () => {
>
Contact support
</SupportLink>
</Button>,
]}
>
Please contact us if you'd like to change your plan.
</Alert>
</Button>
}
/>
)}
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { Download, Loader2 } from 'lucide-react'
import { useEffect, useMemo, useState } from 'react'
import { toast } from 'sonner'
import {
Alert,
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
Expand All @@ -23,14 +22,15 @@ import {
TooltipContent,
TooltipTrigger,
} from 'ui'
import { Admonition } from 'ui-patterns/admonition'
import { FormLayout } from 'ui-patterns/form/Layout/FormLayout'
import {
PageSection,
PageSectionContent,
PageSectionMeta,
PageSectionSummary,
PageSectionTitle,
} from 'ui-patterns'
import { FormLayout } from 'ui-patterns/form/Layout/FormLayout'
} from 'ui-patterns/PageSection'

import { SupportLink } from '@/components/interfaces/Support/SupportLink'
import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
Expand Down Expand Up @@ -186,15 +186,18 @@ export const SSLConfiguration = () => {
</AlertDialog>
</FormLayout>
{isSuccess && !sslEnforcementConfiguration?.appliedSuccessfully && (
<Alert
withIcon
variant="warning"
<Admonition
type="warning"
layout="horizontal"
title="SSL enforcement was not updated successfully"
>
Please try updating again, or contact{' '}
<SupportLink className={InlineLinkClassName}>support</SupportLink> if this error
persists
</Alert>
description={
<>
Please try updating again, or contact{' '}
<SupportLink className={InlineLinkClassName}>support</SupportLink> if this error
persists
</>
}
/>
)}
</CardContent>
<CardContent>
Expand Down
Loading
Loading