import MotionNumber from '@number-flow/react' import { useParams } from 'common' import { AnimatePresence, motion } from 'framer-motion' import { Info } from 'lucide-react' import { useTheme } from 'next-themes' import { useMemo } from 'react' import { UseFormReturn } from 'react-hook-form' import { Badge, cn, Tooltip, TooltipContent, TooltipTrigger } from 'ui' import { DiskStorageSchemaType } from '../DiskManagement.schema' import { AUTOSCALING_THRESHOLD } from './DiskManagement.constants' import { useDiskBreakdownQuery } from '@/data/config/disk-breakdown-query' import { useDiskUtilizationQuery } from '@/data/config/disk-utilization-query' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import { GB } from '@/lib/constants' import { formatBytes } from '@/lib/helpers' interface DiskSpaceBarProps { form: UseFormReturn } export const DiskSpaceBar = ({ form }: DiskSpaceBarProps) => { const { ref } = useParams() const { resolvedTheme } = useTheme() const { formState, watch } = form const isDarkMode = resolvedTheme?.includes('dark') const { data: project } = useSelectedProjectQuery() const { data: diskUtil, // to do, error handling } = useDiskUtilizationQuery({ projectRef: ref, }) const { data: diskBreakdown } = useDiskBreakdownQuery({ projectRef: ref, connectionString: project?.connectionString, }) const diskBreakdownBytes = useMemo(() => { return { availableBytes: diskUtil?.metrics.fs_avail_bytes ?? 0, totalUsedBytes: diskUtil?.metrics.fs_used_bytes ?? 0, totalDiskSizeBytes: diskUtil?.metrics.fs_size_bytes, dbSizeBytes: Math.max(0, diskBreakdown?.db_size_bytes ?? 0), walSizeBytes: Math.max(0, diskBreakdown?.wal_size_bytes ?? 0), systemBytes: Math.max( 0, (diskUtil?.metrics.fs_used_bytes ?? 0) - (diskBreakdown?.db_size_bytes ?? 0) - (diskBreakdown?.wal_size_bytes ?? 0) ), } }, [diskUtil, diskBreakdown]) const showNewSize = formState.dirtyFields.totalSize !== undefined && diskBreakdown const newTotalSize = watch('totalSize') const totalSize = formState.defaultValues?.totalSize || 0 const usedSizeTotal = Math.round(((diskBreakdownBytes?.totalUsedBytes ?? 0) / GB) * 100) / 100 const usedTotalPercentage = Math.min((usedSizeTotal / totalSize) * 100, 100) const usedSizeDatabase = Math.round(((diskBreakdownBytes?.dbSizeBytes ?? 0) / GB) * 100) / 100 const usedPercentageDatabase = totalSize === 0 ? 0 : Math.min((usedSizeDatabase / totalSize) * 100, 100) const newUsedPercentageDatabase = Math.min((usedSizeDatabase / newTotalSize) * 100, 100) const usedSizeWAL = Math.round(((diskBreakdownBytes?.walSizeBytes ?? 0) / GB) * 100) / 100 const usedPercentageWAL = totalSize === 0 ? 0 : Math.min((usedSizeWAL / totalSize) * 100, 100) const newUsedPercentageWAL = Math.min((usedSizeWAL / newTotalSize) * 100, 100) const usedSizeSystem = Math.round(((diskBreakdownBytes?.systemBytes ?? 0) / GB) * 100) / 100 const usedPercentageSystem = totalSize === 0 ? 0 : Math.min((usedSizeSystem / totalSize) * 100, 100) const newUsedPercentageSystem = Math.min((usedSizeSystem / newTotalSize) * 100, 100) const resizePercentage = AUTOSCALING_THRESHOLD * 100 const newResizePercentage = AUTOSCALING_THRESHOLD * 100 return (
{usedSizeTotal.toFixed(2)} GB used of {' '} GB
{!showNewSize && (
)}
{showNewSize && ( New disk size )}
{!showNewSize && (
Autoscaling

Briven expands your disk storage automatically when the database reached 90% of the disk size. However, any disk modifications, including auto-scaling, can only take place once every 4 hours.

If within those 4 hours you reach 95% of the disk space, your project{' '} will enter read-only mode.

)}
{!showNewSize && (
)}

Note: Disk Size refers to the total space your project occupies on disk, including the database itself (currently{' '} {formatBytes(diskBreakdownBytes?.dbSizeBytes, 2, 'GB')}), additional files like the write-ahead log (currently{' '} {formatBytes(diskBreakdownBytes?.walSizeBytes, 2, 'GB')}), and other system resources (currently {formatBytes(diskBreakdownBytes?.systemBytes, 2, 'GB')}). Data can take 5 minutes to refresh.

) } const LegendItem = ({ name, description, color, size, }: { name: string description: string color: string size: number }) => (
{name}
{name} - {formatBytes(size, 2, 'GB')}

{description}

)