From 95ad6110006baf3bc26d7c09f82341e6e5ae796e Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Fri, 26 May 2023 16:12:44 +0100 Subject: [PATCH 1/5] feat: update disk size to GB size of your choice --- .../Database/DiskSizeConfiguration.tsx | 206 ++++++++++++++++++ .../pages/project/[ref]/settings/database.tsx | 2 + 2 files changed, 208 insertions(+) create mode 100644 studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx diff --git a/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx b/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx new file mode 100644 index 00000000000..1f551ab0de3 --- /dev/null +++ b/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx @@ -0,0 +1,206 @@ +import * as Tooltip from '@radix-ui/react-tooltip' +import { PermissionAction } from '@supabase/shared-types/out/constants' +import { useParams } from 'common/hooks' +import { FormHeader } from 'components/ui/Forms' +import Panel from 'components/ui/Panel' +import { useProjectSubscriptionQuery } from 'data/subscriptions/project-subscription-query' +import { useProjectUsageQuery } from 'data/usage/project-usage-query' +import { checkPermissions, useStore } from 'hooks' +import { post } from 'lib/common/fetch' +import { API_URL } from 'lib/constants' +import Link from 'next/link' +import { FC, useEffect, useState } from 'react' +import { Alert, Button, Form, InputNumber, Modal } from 'ui' +import { number, object } from 'yup' + +const DiskSizeConfiguration: FC = ({ disabled = false }) => { + const { ui, app, meta } = useStore() + const { ref } = useParams() + + const canUpdateDiskSizeConfig = checkPermissions(PermissionAction.UPDATE, 'projects') + + const [showResetDbPass, setShowResetDbPass] = useState(false) + const [isUpdatingDiskSize, setIsUpdatingDiskSize] = useState(false) + + const { + data: projectUsage, + error: projectUsageError, + isLoading: projectUsageLoading, + } = useProjectUsageQuery({ projectRef: ref }) + + const { data: projectSubscriptionData } = useProjectSubscriptionQuery({ projectRef: ref }) + + console.log('projectSubscriptionData', projectSubscriptionData) + + useEffect(() => { + if (showResetDbPass) { + setIsUpdatingDiskSize(false) + } + }, [showResetDbPass]) + + const confirmResetDbPass = async (values: { [prop: string]: any }) => { + if (!ref) return + + try { + setIsUpdatingDiskSize(true) + const res = await post(`${API_URL}/projects/${ref}/resize`, { + volume_size_gb: values['new-disk-size'], + }) + + if (res.error) { + throw res.error + } else { + await app.projects.fetchDetail(ref, (project) => meta.setProjectDetails(project)) + ui.setNotification({ + category: 'success', + message: `Succesfully updated disk size to values['new-disk-size'] GB`, + }) + setShowResetDbPass(false) + } + + setIsUpdatingDiskSize(false) + } catch (error: any) { + ui.setNotification({ category: 'error', message: error.message }) + setIsUpdatingDiskSize(false) + } + } + + const currentDiskSize = projectUsage?.disk_volume_size_gb ?? 0 + + const INITIAL_VALUES = { + 'new-disk-size': currentDiskSize, + } + + const diskSizeValidationSchema = object({ + 'new-disk-size': number() + .required('Please enter a GB amount you want to resize the disk up to.') + .moreThan(Number(currentDiskSize ?? 0), `Must be more than ${currentDiskSize} GB`) + // to do, update with max_disk_volume_size_gb + .lessThan(200, 'Must be no more than 200 GB'), + }) + + return ( +
+ + {projectSubscriptionData?.tier.supabase_prod_id != 'tier_free' ? ( +
+ + +
+
+ {projectUsage?.disk_volume_size_gb && ( + + Current disk Size: + + {currentDiskSize} + GB + + + )} +

+ Supabase uses network-attached storage to balance performance with scalability. +

+
+
+ + + + + {!canUpdateDiskSizeConfig && ( + + + +
+ + You need additional permissions to increase the disk size + +
+
+
+ )} +
+
+
+
+
+ + If you intend to import a lot of data into your database which requires multiple disk + expansions then reach out to our team. For example, uploading more than 1.5x the current + size of your database storage will put your database into read-only mode. + +
+ ) : ( + + + + } + > +
+ If you are intending to use more than 8GB of disk space, then you will need to upgrade + to at least the Pro tier. +
+
+ )} + + Increase disk size} + size="small" + visible={showResetDbPass} + loading={isUpdatingDiskSize} + onCancel={() => setShowResetDbPass(false)} + hideFooter + > +
+ {({ isSubmitting }: { isSubmitting: boolean }) => ( + <> + +
+ +
+
+ + +
+ + +
+
+ + )} + +
+
+ ) +} + +export default DiskSizeConfiguration diff --git a/studio/pages/project/[ref]/settings/database.tsx b/studio/pages/project/[ref]/settings/database.tsx index d9b90a1cecb..f4ce38c156c 100644 --- a/studio/pages/project/[ref]/settings/database.tsx +++ b/studio/pages/project/[ref]/settings/database.tsx @@ -10,6 +10,7 @@ import { } from 'components/interfaces/Settings/Database' import SSLConfiguration from 'components/interfaces/Settings/Database/SSLConfiguration' +import DiskSizeConfiguration from 'components/interfaces/Settings/Database/DiskSizeConfiguration' const ProjectSettings: NextPageWithLayout = () => { const { ref: projectRef } = useParams() @@ -21,6 +22,7 @@ const ProjectSettings: NextPageWithLayout = () => { + {networkRestrictions && } From 4ed1d4d9c9b43fdaa0a7ee798641864ceedcc265 Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Fri, 26 May 2023 16:49:53 +0100 Subject: [PATCH 2/5] update docs --- .../pages/guides/platform/database-size.mdx | 16 ++-- .../Database/DiskSizeConfiguration.tsx | 75 +++++++++++-------- 2 files changed, 54 insertions(+), 37 deletions(-) diff --git a/apps/docs/pages/guides/platform/database-size.mdx b/apps/docs/pages/guides/platform/database-size.mdx index ec25d73509e..5d92884eb5f 100644 --- a/apps/docs/pages/guides/platform/database-size.mdx +++ b/apps/docs/pages/guides/platform/database-size.mdx @@ -9,7 +9,7 @@ export const meta = { Database size refers to the _monthly average storage usage_, as reported by Postgres. This metric is reported in your project's [billing usage](https://app.supabase.com/project/_/settings/billing/usage) and is updated daily. As you read this document we will refer to "database size" and "disk size": - "Database size" is the total size of used storage from your database. -- "Disk size" describes the size of the underlying available storage. +- "Disk Storage size" describes the size of the underlying available storage. ## Database space management @@ -23,7 +23,7 @@ select from pg_database; ``` -This value is reported in the [database settings page](https://app.supabase.com/project/_/settings/database). +This value is reported in the [database report page](https://app.supabase.com/project/_/reports/database). Database Space is consumed primarily by your data, indexes, and materialized views. You can reduce your disk size by removing any of these and running a Vacuum operation. @@ -61,16 +61,18 @@ Supabase uses network-attached storage to balance performance with scalability. Pro and Enterprise projects have auto-scaling Disk Storage. -Disk storage expands automatically when the database reaches 90% of the disk size. The disk is expanded to be 50% larger (e.g., 8GB -> 12GB). Auto-scaling can only take place once every 6 hours. If within those 6 hours you reach 95% of the disk space, your project will enter read-only mode. +Disk Storage expands automatically when the database reaches 90% of the disk size. The disk is expanded to be 50% larger (e.g., 8GB -> 12GB). Auto-scaling can only take place once every 6 hours. If within those 6 hours you reach 95% of the disk space, your project will enter read-only mode. - +The maximum Disk Storage Size for Pro Tier is 64TB. If you need more than this, [contact us](https://app.supabase.com/support/new) to learn more about the Enterprise plan. -If you intend to import a lot of data into your database which requires multiple disk expansions then [reach out to our team](https://app.supabase.com/support/new). For example, uploading more than 1.5x the current size of your database storage will put your database into [read-only mode](#read-only-mode). +The Disk Storage Size can also be manually expanded in [Database settings page](https://app.supabase.com/project/_/settings/database). The maximum default you can expand the Disk Storage to is 200GB. If you wish to manually expand it any more than 200B, please [contact us](https://app.supabase.com/support/new) to discuss expanding the 200GB limit. + + + +You may want to import a lot of data into your database which requires multiple disk expansions; for example, uploading more than 1.5x the current size of your database storage will put your database into [read-only mode](#read-only-mode). If so, it is highly recommended you increase the Disk Storage Size manually on the [Database settings page](https://app.supabase.com/project/_/settings/database). -The maximum Disk Size for Pro Tier is 64TB. If you need more than this, [contact us](https://app.supabase.com/support/new) to learn more about the Enterprise plan. - ### Free Tier Behavior Free Tier projects enter [read-only](#read-only-mode) mode when you exceed the 500mb limit. Once in read-only mode, you have several options: diff --git a/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx b/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx index 1f551ab0de3..4fc47706a5e 100644 --- a/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx +++ b/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx @@ -53,7 +53,7 @@ const DiskSizeConfiguration: FC = ({ disabled = false }) => { await app.projects.fetchDetail(ref, (project) => meta.setProjectDetails(project)) ui.setNotification({ category: 'success', - message: `Succesfully updated disk size to values['new-disk-size'] GB`, + message: `Succesfully updated disk size to ${values['new-disk-size']} GB`, }) setShowResetDbPass(false) } @@ -66,6 +66,8 @@ const DiskSizeConfiguration: FC = ({ disabled = false }) => { } const currentDiskSize = projectUsage?.disk_volume_size_gb ?? 0 + // to do, update with max_disk_volume_size_gb + const maxDiskSize = 200 const INITIAL_VALUES = { 'new-disk-size': currentDiskSize, @@ -76,7 +78,7 @@ const DiskSizeConfiguration: FC = ({ disabled = false }) => { .required('Please enter a GB amount you want to resize the disk up to.') .moreThan(Number(currentDiskSize ?? 0), `Must be more than ${currentDiskSize} GB`) // to do, update with max_disk_volume_size_gb - .lessThan(200, 'Must be no more than 200 GB'), + .lessThan(Number(maxDiskSize), 'Must be no more than 200 GB'), }) return ( @@ -90,7 +92,7 @@ const DiskSizeConfiguration: FC = ({ disabled = false }) => {
{projectUsage?.disk_volume_size_gb && ( - Current disk Size: + Current Disk Storage Size: {currentDiskSize} GB @@ -152,14 +154,14 @@ const DiskSizeConfiguration: FC = ({ disabled = false }) => { } >
- If you are intending to use more than 8GB of disk space, then you will need to upgrade + If you are intending to use more than 500MB of disk space, then you will need to upgrade to at least the Pro tier.
)} Increase disk size} + header={
Increase Disk Storage Size
} size="small" visible={showResetDbPass} loading={isUpdatingDiskSize} @@ -172,31 +174,44 @@ const DiskSizeConfiguration: FC = ({ disabled = false }) => { validationSchema={diskSizeValidationSchema} onSubmit={confirmResetDbPass} > - {({ isSubmitting }: { isSubmitting: boolean }) => ( - <> - -
- -
-
- - -
- - -
-
- - )} + {({ isSubmitting }: { isSubmitting: boolean }) => + currentDiskSize >= maxDiskSize ? ( + <> + + You cannot manually expand the disk size any more than {maxDiskSize} GB. If you + need more than this, contact us to learn more about the Enterprise plan. + + + ) : ( + <> + +
+ +
+
+ + +
+ + +
+
+ + ) + }
From 1325e9215d1fba55481c101f690c77a6449884c4 Mon Sep 17 00:00:00 2001 From: Greg Richardson Date: Fri, 26 May 2023 13:26:47 -0600 Subject: [PATCH 3/5] chore: fix spelling errors --- .../interfaces/Settings/Database/DiskSizeConfiguration.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx b/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx index 4fc47706a5e..5f5d5586dd4 100644 --- a/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx +++ b/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx @@ -53,7 +53,7 @@ const DiskSizeConfiguration: FC = ({ disabled = false }) => { await app.projects.fetchDetail(ref, (project) => meta.setProjectDetails(project)) ui.setNotification({ category: 'success', - message: `Succesfully updated disk size to ${values['new-disk-size']} GB`, + message: `Successfully updated disk size to ${values['new-disk-size']} GB`, }) setShowResetDbPass(false) } From 3e245b4c5a61df134fa7b00e5ed965d7fada99c9 Mon Sep 17 00:00:00 2001 From: Terry Sutton Date: Fri, 26 May 2023 17:34:49 -0230 Subject: [PATCH 4/5] Update language, add project usage mutation --- .../Subscription/Tier/SubscriptionTier.tsx | 4 +- .../Database/DiskSizeConfiguration.tsx | 70 +++++++++---------- studio/data/usage/project-usage-mutation.ts | 51 ++++++++++++++ 3 files changed, 88 insertions(+), 37 deletions(-) create mode 100644 studio/data/usage/project-usage-mutation.ts diff --git a/studio/components/interfaces/BillingV2/Subscription/Tier/SubscriptionTier.tsx b/studio/components/interfaces/BillingV2/Subscription/Tier/SubscriptionTier.tsx index 4fcdf9405d2..e61b6193a97 100644 --- a/studio/components/interfaces/BillingV2/Subscription/Tier/SubscriptionTier.tsx +++ b/studio/components/interfaces/BillingV2/Subscription/Tier/SubscriptionTier.tsx @@ -89,7 +89,7 @@ const SubscriptionTier = ({}: SubscriptionTierProps) => {

When this project exceeds its included usage quotas, it may become unresponsive. {currentPlan?.id === 'free' - ? 'If you wish to exceed the included usage, it is advised you upgrade to a paid plan.' + ? 'If you wish to exceed the included usage, you should upgrade to a paid plan.' : 'You can change the Cost Control settings if you plan on exceeding the included usage quotas.'}

@@ -98,7 +98,7 @@ const SubscriptionTier = ({}: SubscriptionTierProps) => { type="horizontal" value={daysWithinCycle - daysToCycleEnd} max={daysWithinCycle} - barClass="bg-scale-1100" + barClass="bg-scale-1200" labelBottom={`Current billing cycle (${billingCycleStart.format( 'MMM DD' )} - ${billingCycleEnd.format('MMM DD')})`} diff --git a/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx b/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx index 4fc47706a5e..f3ffbed29c8 100644 --- a/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx +++ b/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx @@ -4,33 +4,26 @@ import { useParams } from 'common/hooks' import { FormHeader } from 'components/ui/Forms' import Panel from 'components/ui/Panel' import { useProjectSubscriptionQuery } from 'data/subscriptions/project-subscription-query' +import { useProjectUsageUpdateMutation } from 'data/usage/project-usage-mutation' import { useProjectUsageQuery } from 'data/usage/project-usage-query' import { checkPermissions, useStore } from 'hooks' -import { post } from 'lib/common/fetch' -import { API_URL } from 'lib/constants' import Link from 'next/link' import { FC, useEffect, useState } from 'react' import { Alert, Button, Form, InputNumber, Modal } from 'ui' import { number, object } from 'yup' const DiskSizeConfiguration: FC = ({ disabled = false }) => { - const { ui, app, meta } = useStore() - const { ref } = useParams() + const { ui } = useStore() + const { ref: projectRef } = useParams() const canUpdateDiskSizeConfig = checkPermissions(PermissionAction.UPDATE, 'projects') const [showResetDbPass, setShowResetDbPass] = useState(false) const [isUpdatingDiskSize, setIsUpdatingDiskSize] = useState(false) - const { - data: projectUsage, - error: projectUsageError, - isLoading: projectUsageLoading, - } = useProjectUsageQuery({ projectRef: ref }) - - const { data: projectSubscriptionData } = useProjectSubscriptionQuery({ projectRef: ref }) - - console.log('projectSubscriptionData', projectSubscriptionData) + const { data: projectUsage } = useProjectUsageQuery({ projectRef }) + const { data: projectSubscriptionData } = useProjectSubscriptionQuery({ projectRef }) + const { mutateAsync: updateProjectUsage } = useProjectUsageUpdateMutation() useEffect(() => { if (showResetDbPass) { @@ -39,26 +32,18 @@ const DiskSizeConfiguration: FC = ({ disabled = false }) => { }, [showResetDbPass]) const confirmResetDbPass = async (values: { [prop: string]: any }) => { - if (!ref) return + const volumeSize = values['new-disk-size'] + if (!projectRef) return try { setIsUpdatingDiskSize(true) - const res = await post(`${API_URL}/projects/${ref}/resize`, { - volume_size_gb: values['new-disk-size'], + await updateProjectUsage({ projectRef, volumeSize }) + ui.setNotification({ + category: 'success', + message: `Successfully updated disk size to ${values['new-disk-size']} GB`, }) - - if (res.error) { - throw res.error - } else { - await app.projects.fetchDetail(ref, (project) => meta.setProjectDetails(project)) - ui.setNotification({ - category: 'success', - message: `Succesfully updated disk size to ${values['new-disk-size']} GB`, - }) - setShowResetDbPass(false) - } - setIsUpdatingDiskSize(false) + setShowResetDbPass(false) } catch (error: any) { ui.setNotification({ category: 'error', message: error.message }) setIsUpdatingDiskSize(false) @@ -100,7 +85,8 @@ const DiskSizeConfiguration: FC = ({ disabled = false }) => { )}

- Supabase uses network-attached storage to balance performance with scalability. + Supabase employs auto-scaling storage and allows for manual disk size
{' '} + adjustments when necessary

@@ -136,19 +122,33 @@ const DiskSizeConfiguration: FC = ({ disabled = false }) => {
- - If you intend to import a lot of data into your database which requires multiple disk - expansions then reach out to our team. For example, uploading more than 1.5x the current - size of your database storage will put your database into read-only mode. + +

+ We auto-scale your disk as you need more storage, but can only do this every 6 hours. + If you upload more than 1.5x the current size of your storage, your database will go + into read-only mode. If you know how big your database is going to be, you can + manually increase the size here. +

+ +

+ Read more about{' '} + + disk management + + . +

) : ( + } diff --git a/studio/data/usage/project-usage-mutation.ts b/studio/data/usage/project-usage-mutation.ts new file mode 100644 index 00000000000..b944063d674 --- /dev/null +++ b/studio/data/usage/project-usage-mutation.ts @@ -0,0 +1,51 @@ +import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query' +import { post } from 'lib/common/fetch' +import { API_URL } from 'lib/constants' +import { usageKeys } from './keys' + +export type ProjectUsageVariables = { + projectRef: string + volumeSize: number +} + +export type ProjectUsageResponse = { + error?: any +} + +export async function updateProjectUsage({ projectRef, volumeSize }: ProjectUsageVariables) { + if (!projectRef) throw new Error('projectRef is required') + + const payload = { volume_size_gb: volumeSize } + + const response = (await post( + `${API_URL}/projects/${projectRef}/resize`, + payload + )) as ProjectUsageResponse + if (response.error) throw response.error + + return response +} + +type ProjectUsageUpdateData = Awaited> + +export const useProjectUsageUpdateMutation = ({ + onSuccess, + ...options +}: Omit< + UseMutationOptions, + 'mutationFn' +> = {}) => { + const queryClient = useQueryClient() + + return useMutation( + (vars) => updateProjectUsage(vars), + { + async onSuccess(data, variables, context) { + const { projectRef } = variables + await queryClient.invalidateQueries(usageKeys.usage(projectRef)) + await onSuccess?.(data, variables, context) + }, + ...options, + } + ) +} From 00454c7efd4512ae40b092d019ddef119e51de7e Mon Sep 17 00:00:00 2001 From: Alaister Young Date: Tue, 30 May 2023 16:12:04 +1000 Subject: [PATCH 5/5] manually update the cache after resizing disk --- .../Database/DiskSizeConfiguration.tsx | 12 ++-- .../config/project-disk-resize-mutation.ts | 60 +++++++++++++++++++ studio/data/usage/project-usage-mutation.ts | 51 ---------------- 3 files changed, 68 insertions(+), 55 deletions(-) create mode 100644 studio/data/config/project-disk-resize-mutation.ts delete mode 100644 studio/data/usage/project-usage-mutation.ts diff --git a/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx b/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx index f3ffbed29c8..34d0dea0b29 100644 --- a/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx +++ b/studio/components/interfaces/Settings/Database/DiskSizeConfiguration.tsx @@ -4,15 +4,19 @@ import { useParams } from 'common/hooks' import { FormHeader } from 'components/ui/Forms' import Panel from 'components/ui/Panel' import { useProjectSubscriptionQuery } from 'data/subscriptions/project-subscription-query' -import { useProjectUsageUpdateMutation } from 'data/usage/project-usage-mutation' +import { useProjectDiskResizeMutation } from 'data/config/project-disk-resize-mutation' import { useProjectUsageQuery } from 'data/usage/project-usage-query' import { checkPermissions, useStore } from 'hooks' import Link from 'next/link' -import { FC, useEffect, useState } from 'react' +import { useEffect, useState } from 'react' import { Alert, Button, Form, InputNumber, Modal } from 'ui' import { number, object } from 'yup' -const DiskSizeConfiguration: FC = ({ disabled = false }) => { +export interface DiskSizeConfigurationProps { + disabled?: boolean +} + +const DiskSizeConfiguration = ({ disabled = false }: DiskSizeConfigurationProps) => { const { ui } = useStore() const { ref: projectRef } = useParams() @@ -23,7 +27,7 @@ const DiskSizeConfiguration: FC = ({ disabled = false }) => { const { data: projectUsage } = useProjectUsageQuery({ projectRef }) const { data: projectSubscriptionData } = useProjectSubscriptionQuery({ projectRef }) - const { mutateAsync: updateProjectUsage } = useProjectUsageUpdateMutation() + const { mutateAsync: updateProjectUsage } = useProjectDiskResizeMutation() useEffect(() => { if (showResetDbPass) { diff --git a/studio/data/config/project-disk-resize-mutation.ts b/studio/data/config/project-disk-resize-mutation.ts new file mode 100644 index 00000000000..97a8b4e9a46 --- /dev/null +++ b/studio/data/config/project-disk-resize-mutation.ts @@ -0,0 +1,60 @@ +import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query' +import { post } from 'lib/common/fetch' +import { API_URL } from 'lib/constants' +import { usageKeys } from '../usage/keys' + +export type ProjectDiskResizeVariables = { + projectRef: string + volumeSize: number +} + +export type ProjectDiskResizeResponse = { + error?: any +} + +export async function resizeProjectDisk({ projectRef, volumeSize }: ProjectDiskResizeVariables) { + if (!projectRef) throw new Error('projectRef is required') + + const payload = { volume_size_gb: volumeSize } + + const response = (await post( + `${API_URL}/projects/${projectRef}/resize`, + payload + )) as ProjectDiskResizeResponse + if (response.error) throw response.error + + return response +} + +type ProjectDiskResizeData = Awaited> + +export const useProjectDiskResizeMutation = ({ + onSuccess, + ...options +}: Omit< + UseMutationOptions, + 'mutationFn' +> = {}) => { + const queryClient = useQueryClient() + + return useMutation( + (vars) => resizeProjectDisk(vars), + { + async onSuccess(data, variables, context) { + const { projectRef } = variables + + queryClient.setQueriesData(usageKeys.usage(projectRef), (prev) => { + if (!prev) return prev + + return { + ...prev, + disk_volume_size_gb: variables.volumeSize, + } + }) + + await onSuccess?.(data, variables, context) + }, + ...options, + } + ) +} diff --git a/studio/data/usage/project-usage-mutation.ts b/studio/data/usage/project-usage-mutation.ts deleted file mode 100644 index b944063d674..00000000000 --- a/studio/data/usage/project-usage-mutation.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query' -import { post } from 'lib/common/fetch' -import { API_URL } from 'lib/constants' -import { usageKeys } from './keys' - -export type ProjectUsageVariables = { - projectRef: string - volumeSize: number -} - -export type ProjectUsageResponse = { - error?: any -} - -export async function updateProjectUsage({ projectRef, volumeSize }: ProjectUsageVariables) { - if (!projectRef) throw new Error('projectRef is required') - - const payload = { volume_size_gb: volumeSize } - - const response = (await post( - `${API_URL}/projects/${projectRef}/resize`, - payload - )) as ProjectUsageResponse - if (response.error) throw response.error - - return response -} - -type ProjectUsageUpdateData = Awaited> - -export const useProjectUsageUpdateMutation = ({ - onSuccess, - ...options -}: Omit< - UseMutationOptions, - 'mutationFn' -> = {}) => { - const queryClient = useQueryClient() - - return useMutation( - (vars) => updateProjectUsage(vars), - { - async onSuccess(data, variables, context) { - const { projectRef } = variables - await queryClient.invalidateQueries(usageKeys.usage(projectRef)) - await onSuccess?.(data, variables, context) - }, - ...options, - } - ) -}