From 71a184738ce03eeb7122901ff537ddfa977b64d2 Mon Sep 17 00:00:00 2001
From: Joshen Lim
Date: Tue, 17 Sep 2024 15:22:18 +0800
Subject: [PATCH] Chore/more disk mgt UI updates (#29333)
* Only show new disk billing UI for AWS provider projects
* Fix DiskSpaceBar autoscaling should be fixed at 90%
* Change all MiB to MB and GiB to GB
* Prettier
---
.../DiskManagement.constants.tsx | 7 ++++--
.../DiskManagement/DiskManagement.test.ts | 4 ++--
.../DiskManagement/DiskManagement.utils.ts | 10 ++++-----
.../DiskManagementPanelForm.tsx | 22 +++++++++----------
.../DiskManagementPanelSchema.ts | 10 ++++-----
.../DiskManagementReviewAndSubmitDialog.tsx | 4 ++--
.../DiskManagement/DiskSpaceBar.tsx | 14 +++++-------
.../pages/project/[ref]/settings/database.tsx | 6 ++++-
8 files changed, 40 insertions(+), 37 deletions(-)
diff --git a/apps/studio/components/interfaces/DiskManagement/DiskManagement.constants.tsx b/apps/studio/components/interfaces/DiskManagement/DiskManagement.constants.tsx
index 95e59e9eb71..98a64acc64e 100644
--- a/apps/studio/components/interfaces/DiskManagement/DiskManagement.constants.tsx
+++ b/apps/studio/components/interfaces/DiskManagement/DiskManagement.constants.tsx
@@ -1,5 +1,8 @@
import { PlanType } from 'data/subscriptions/org-subscription-query'
+// Disk Storage expands automatically when the database reaches 90% of the disk size
+export const AUTOSCALING_THRESHOLD = 0.9
+
export enum DiskType {
GP3 = 'gp3',
IO2 = 'io2',
@@ -16,12 +19,12 @@ export const THROUGHPUT_RANGE = {
export const DISK_PRICING = {
[DiskType.GP3]: {
- storage: 0.125, // per GiB per month
+ storage: 0.125, // per GB per month
iops: 0.024, // per IOPS per month, charged after 3000 IOPS
throughput: 0.095, // per MB/s per month, charged after 125 MB/s
},
[DiskType.IO2]: {
- storage: 0.195, // per GiB per month
+ storage: 0.195, // per GB per month
iops: 0.119, // per IOPS per month
},
}
diff --git a/apps/studio/components/interfaces/DiskManagement/DiskManagement.test.ts b/apps/studio/components/interfaces/DiskManagement/DiskManagement.test.ts
index 89909b4ce6b..76210dcdb97 100644
--- a/apps/studio/components/interfaces/DiskManagement/DiskManagement.test.ts
+++ b/apps/studio/components/interfaces/DiskManagement/DiskManagement.test.ts
@@ -64,7 +64,7 @@ describe('DiskManagement.utils.ts:calculateIOPSPrice', () => {
})
describe('DiskManagement.utils.ts:calculateThroughputPrice', () => {
- test('GP3 with 125 MiBps 150 MiBps', () => {
+ test('GP3 with 125 MB/s 150 MB/s', () => {
const result = calculateThroughputPrice({
storageType: DiskType.GP3,
oldThroughput: 125,
@@ -73,7 +73,7 @@ describe('DiskManagement.utils.ts:calculateThroughputPrice', () => {
expect(result.oldPrice).toBe('0.00')
expect(result.newPrice).toBe('2.38')
})
- test('IO1 with 125 MiBps 150 MiBps', () => {
+ test('IO1 with 125 MB/s 150 MB/s', () => {
const result = calculateThroughputPrice({
storageType: DiskType.IO2,
oldThroughput: 125,
diff --git a/apps/studio/components/interfaces/DiskManagement/DiskManagement.utils.ts b/apps/studio/components/interfaces/DiskManagement/DiskManagement.utils.ts
index 0d0235e41bf..67b4111fd8a 100644
--- a/apps/studio/components/interfaces/DiskManagement/DiskManagement.utils.ts
+++ b/apps/studio/components/interfaces/DiskManagement/DiskManagement.utils.ts
@@ -13,14 +13,14 @@ export const calculateDiskSizePrice = ({
newSize: number
newStorageType: DiskType
}) => {
- const oldPricePerGiB = DISK_PRICING[oldStorageType]?.storage ?? 0
- const newPricePerGiB = DISK_PRICING[newStorageType]?.storage ?? 0
+ const oldPricePerGB = DISK_PRICING[oldStorageType]?.storage ?? 0
+ const newPricePerGB = DISK_PRICING[newStorageType]?.storage ?? 0
const { includedDiskGB } = PLAN_DETAILS?.[planId as keyof typeof PLAN_DETAILS] ?? {}
- const oldPrice = (Math.max(oldSize - includedDiskGB[oldStorageType], 0) * oldPricePerGiB).toFixed(
+ const oldPrice = (Math.max(oldSize - includedDiskGB[oldStorageType], 0) * oldPricePerGB).toFixed(
2
)
- const newPrice = (Math.max(newSize - includedDiskGB[newStorageType], 0) * newPricePerGiB).toFixed(
+ const newPrice = (Math.max(newSize - includedDiskGB[newStorageType], 0) * newPricePerGB).toFixed(
2
)
@@ -62,7 +62,7 @@ export const calculateIOPSPrice = ({
}
// This is only applicable for GP3 storage type, no need to consider IO2 at all
-// Also assumes that disk size is > 400 GiB (separate requirement to update throughput)
+// Also assumes that disk size is > 400 GB (separate requirement to update throughput)
export const calculateThroughputPrice = ({
storageType,
newThroughput,
diff --git a/apps/studio/components/interfaces/DiskManagement/DiskManagementPanelForm.tsx b/apps/studio/components/interfaces/DiskManagement/DiskManagementPanelForm.tsx
index 04c65a935d6..30dba5b764b 100644
--- a/apps/studio/components/interfaces/DiskManagement/DiskManagementPanelForm.tsx
+++ b/apps/studio/components/interfaces/DiskManagement/DiskManagementPanelForm.tsx
@@ -210,7 +210,7 @@ export function DiskManagementPanelForm() {
if (watchedStorageType === 'io2') {
setValue('throughput', undefined) // Throughput is not configurable for 'io2'
} else if (watchedStorageType === 'gp3') {
- // Ensure throughput is within the allowed range if it's greater than or equal to 400 GiB
+ // Ensure throughput is within the allowed range if it's greater than or equal to 400 GB
const currentThroughput = form.getValues('throughput')
const { min, max } = THROUGHPUT_RANGE[DiskType.GP3]
if (!currentThroughput || currentThroughput < min || currentThroughput > max) {
@@ -382,7 +382,7 @@ export function DiskManagementPanelForm() {
For io2 storage type, min IOPS is at {minIOPS}, while max IOPS is
- at 1000 * disk size in GiB or{' '}
+ at 1000 * disk size in GB or{' '}
{IOPS_RANGE[DiskType.IO2].max.toLocaleString()}, whichever is
lower
@@ -405,7 +405,7 @@ export function DiskManagementPanelForm() {
For gp3 storage type, min IOPS is at {minIOPS} while max IOPS is
- at 500 * disk size in GiB or{' '}
+ at 500 * disk size in GB or{' '}
{IOPS_RANGE[DiskType.GP3].max.toLocaleString()}, whichever is
lower
@@ -474,14 +474,14 @@ export function DiskManagementPanelForm() {
control={control}
render={({ field }) => (
Throughput must be between {minThroughput} and {maxThroughput}{' '}
- MiBps based on your IOPS.
+ MB/s based on your IOPS.
@@ -491,8 +491,8 @@ export function DiskManagementPanelForm() {
/>
- Min throughput is at 125MiBps, while max throughput is at
- 0.25MiBps * IOPS or 1000, whichever is lower
+ Min throughput is at 125MB/s, while max throughput is at
+ 0.25MB/s * IOPS or 1000, whichever is lower
@@ -503,7 +503,7 @@ export function DiskManagementPanelForm() {
{maxThroughputBasedOnCompute.toFixed(0)}
{' '}
- MiBps based on your current compute size of{' '}
+ MB/s based on your current compute size of{' '}
{currentCompute?.name}
)}
@@ -528,7 +528,7 @@ export function DiskManagementPanelForm() {
- MiBps
+ MB/s
@@ -560,7 +560,7 @@ export function DiskManagementPanelForm() {
layout="horizontal"
description={
includedDiskGB > 0 &&
- `Your plan includes ${includedDiskGB} GiB of disk size for ${watchedStorageType}.`
+ `Your plan includes ${includedDiskGB} GB of disk size for ${watchedStorageType}.`
}
>
@@ -585,7 +585,7 @@ export function DiskManagementPanelForm() {
/>
- GiB
+ GB
diff --git a/apps/studio/components/interfaces/DiskManagement/DiskManagementPanelSchema.ts b/apps/studio/components/interfaces/DiskManagement/DiskManagementPanelSchema.ts
index 88916a0bef8..548bfd51db0 100644
--- a/apps/studio/components/interfaces/DiskManagement/DiskManagementPanelSchema.ts
+++ b/apps/studio/components/interfaces/DiskManagement/DiskManagementPanelSchema.ts
@@ -4,11 +4,11 @@ const baseSchema = z.object({
storageType: z.enum(['io2', 'gp3']).describe('Type of storage: io2 or gp3'),
totalSize: z
.number()
- .min(8, { message: 'Allocated disk size must be at least 8 GiB.' })
- .max(16384, { message: 'Allocated disk size must not exceed 16,384 GiB.' })
- .describe('Allocated disk size in GiB'),
+ .min(8, { message: 'Allocated disk size must be at least 8 GB.' })
+ .max(16384, { message: 'Allocated disk size must not exceed 16,384 GB.' })
+ .describe('Allocated disk size in GB'),
provisionedIOPS: z.number().describe('Provisioned IOPS for storage type'),
- throughput: z.number().optional().describe('Throughput in MiBps for gp3'),
+ throughput: z.number().optional().describe('Throughput in MB/s for gp3'),
})
export const DiskStorageSchema = baseSchema.superRefine((data, ctx) => {
@@ -75,7 +75,7 @@ export const DiskStorageSchema = baseSchema.superRefine((data, ctx) => {
if (throughput !== undefined && (throughput < 125 || throughput > maxThroughput)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
- message: `Throughput must be set between 125 and ${maxThroughput} MiBps.`,
+ message: `Throughput must be set between 125 and ${maxThroughput} MB/s.`,
path: ['throughput'],
})
}
diff --git a/apps/studio/components/interfaces/DiskManagement/DiskManagementReviewAndSubmitDialog.tsx b/apps/studio/components/interfaces/DiskManagement/DiskManagementReviewAndSubmitDialog.tsx
index f9050dbce45..4a4fbce6f9f 100644
--- a/apps/studio/components/interfaces/DiskManagement/DiskManagementReviewAndSubmitDialog.tsx
+++ b/apps/studio/components/interfaces/DiskManagement/DiskManagementReviewAndSubmitDialog.tsx
@@ -164,7 +164,7 @@ export const DiskManagementReviewAndSubmitDialog = ({
attribute="Disk size"
defaultValue={form.formState.defaultValues?.totalSize ?? 0}
newValue={form.getValues('totalSize')}
- unit="GiB"
+ unit="GB"
beforePrice={Number(diskSizePrice.oldPrice)}
afterPrice={Number(diskSizePrice.newPrice)}
/>
@@ -181,7 +181,7 @@ export const DiskManagementReviewAndSubmitDialog = ({
attribute="Throughput"
defaultValue={form.formState.defaultValues?.throughput ?? 0}
newValue={form.getValues('throughput') ?? 0}
- unit="MiBps"
+ unit="MB/s"
beforePrice={Number(throughputPrice.oldPrice)}
afterPrice={Number(throughputPrice.newPrice)}
/>
diff --git a/apps/studio/components/interfaces/DiskManagement/DiskSpaceBar.tsx b/apps/studio/components/interfaces/DiskManagement/DiskSpaceBar.tsx
index d4bd6a0c2c1..1f3ff172e64 100644
--- a/apps/studio/components/interfaces/DiskManagement/DiskSpaceBar.tsx
+++ b/apps/studio/components/interfaces/DiskManagement/DiskSpaceBar.tsx
@@ -1,6 +1,5 @@
import { AnimatePresence, motion } from 'framer-motion'
import MotionNumber from 'motion-number'
-import { useState } from 'react'
import {
badgeVariants,
@@ -9,6 +8,7 @@ import {
TooltipContent_Shadcn_,
TooltipTrigger_Shadcn_,
} from 'ui'
+import { AUTOSCALING_THRESHOLD } from './DiskManagement.constants'
interface DiskSpaceBarProps {
showNewBar: boolean
@@ -23,21 +23,17 @@ export default function DiskSpaceBar({
usedSize,
newTotalSize,
}: DiskSpaceBarProps) {
- const [resizeThreshold, setResizeThreshold] = useState(0.5) // 500 MB threshold for resize
-
const usedPercentage = (usedSize / totalSize) * 100
- const resizePoint = totalSize - resizeThreshold
- const resizePercentage = (resizePoint / totalSize) * 100
+ const resizePercentage = AUTOSCALING_THRESHOLD * 100
const newUsedPercentage = (usedSize / newTotalSize) * 100
- const newResizePoint = newTotalSize - resizeThreshold
- const newResizePercentage = (newResizePoint / newTotalSize) * 100
+ const newResizePercentage = AUTOSCALING_THRESHOLD * 100
return (
- {usedSize.toFixed(2)} GiB used of{' '}
+ {usedSize.toFixed(2)} GB used of{' '}
{' '}
- GiB
+ GB
diff --git a/apps/studio/pages/project/[ref]/settings/database.tsx b/apps/studio/pages/project/[ref]/settings/database.tsx
index 11230ca81c3..2a7b0c0239c 100644
--- a/apps/studio/pages/project/[ref]/settings/database.tsx
+++ b/apps/studio/pages/project/[ref]/settings/database.tsx
@@ -17,14 +17,18 @@ import DiskSizeConfiguration from 'components/interfaces/Settings/Database/DiskS
import { useFlag } from 'hooks/ui/useFlag'
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
import { useOrgSubscriptionQuery } from 'data/subscriptions/org-subscription-query'
+import { useSelectedProject } from 'hooks/misc/useSelectedProject'
const ProjectSettings: NextPageWithLayout = () => {
const diskManagementV2 = useFlag('diskManagementV2')
+ const project = useSelectedProject()
const selectedOrg = useSelectedOrganization()
const { data: subscription } = useOrgSubscriptionQuery({ orgSlug: selectedOrg?.slug })
const showNewDiskManagementUI =
- subscription?.usage_based_billing_project_addons && diskManagementV2
+ diskManagementV2 &&
+ project?.cloud_provider === 'AWS' &&
+ subscription?.usage_based_billing_project_addons
return (
<>