DatabaseSizeUsage.tsx 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import Link from 'next/link'
  2. import { useMemo } from 'react'
  3. import { Alert, AlertDescription, AlertTitle, Button, CriticalIcon } from 'ui'
  4. import { InfoTooltip } from 'ui-patterns/info-tooltip'
  5. import { SectionContent } from '../SectionContent'
  6. import { CategoryAttribute } from '../Usage.constants'
  7. import Panel from '@/components/ui/Panel'
  8. import { PricingMetric } from '@/data/analytics/org-daily-stats-query'
  9. import type { OrgSubscription } from '@/data/subscriptions/types'
  10. import { OrgUsageResponse } from '@/data/usage/org-usage-query'
  11. import { formatBytes } from '@/lib/helpers'
  12. export interface DatabaseSizeUsageProps {
  13. slug: string
  14. projectRef?: string | null
  15. attribute: CategoryAttribute
  16. subscription?: OrgSubscription
  17. usage?: OrgUsageResponse
  18. currentBillingCycleSelected: boolean
  19. }
  20. const DatabaseSizeUsage = ({
  21. attribute,
  22. subscription,
  23. usage,
  24. currentBillingCycleSelected,
  25. }: DatabaseSizeUsageProps) => {
  26. const databaseSizeUsage = useMemo(
  27. () => usage?.usages.find((it) => it.metric === PricingMetric.DATABASE_SIZE),
  28. [usage]
  29. )
  30. const hasProjectsExceedingDatabaseSize = useMemo(() => {
  31. return databaseSizeUsage?.project_allocations.some((it) => it.usage > 0.5 * 1e9)
  32. }, [databaseSizeUsage])
  33. return (
  34. <div id={attribute.anchor} className="scroll-my-12">
  35. <SectionContent section={attribute}>
  36. <div className="space-y-4">
  37. {currentBillingCycleSelected && hasProjectsExceedingDatabaseSize && (
  38. <Alert variant="warning">
  39. <CriticalIcon />
  40. <AlertTitle>Projects exceeding quota</AlertTitle>
  41. <AlertDescription>
  42. You have projects that are exceeding 0.5 GB of database size. Reduce the database
  43. size or upgrade to a paid plan.
  44. </AlertDescription>
  45. </Alert>
  46. )}
  47. <div>
  48. <div className="flex items-center justify-between">
  49. <div className="flex items-center space-x-4">
  50. <p className="text-sm">{attribute.name} usage</p>
  51. </div>
  52. </div>
  53. {subscription?.plan.id !== 'platform' && (
  54. <>
  55. <div className="flex items-center justify-between border-b py-1">
  56. <p className="text-xs text-foreground-light">
  57. Included in {subscription?.plan?.name} Plan
  58. </p>
  59. <p className="text-xs">0.5 GB per project</p>
  60. </div>
  61. <div className="flex items-center justify-between">
  62. <p className="text-xs text-foreground-light">Max database size</p>
  63. <p className="text-xs">
  64. {databaseSizeUsage?.usage
  65. ? formatBytes(databaseSizeUsage?.usage_original)
  66. : '-'}
  67. </p>
  68. </div>
  69. </>
  70. )}
  71. </div>
  72. {currentBillingCycleSelected && subscription?.plan.id !== 'platform' ? (
  73. <div className="space-y-4">
  74. <div className="space-y-1">
  75. <p className="text-sm">Current database size per project</p>
  76. </div>
  77. {databaseSizeUsage?.project_allocations.length === 0 && (
  78. <Panel>
  79. <Panel.Content>
  80. <div className="flex flex-col items-center justify-center">
  81. <p className="text-sm">No active projects</p>
  82. <p className="text-sm text-foreground-light">
  83. You don't have any active projects in this organization.
  84. </p>
  85. </div>
  86. </Panel.Content>
  87. </Panel>
  88. )}
  89. {databaseSizeUsage?.project_allocations.map((project, idx) => {
  90. return (
  91. <div
  92. key={`usage-project-${project.ref}`}
  93. className={
  94. idx !== databaseSizeUsage.project_allocations.length - 1
  95. ? 'border-b pb-2'
  96. : ''
  97. }
  98. >
  99. <div className="flex justify-between">
  100. <span className="text-foreground-light flex items-center gap-2">
  101. {project.name}
  102. </span>
  103. <Button asChild type="default" size={'tiny'}>
  104. <Link
  105. href={`/project/${project.ref}/observability/database#database-size-report`}
  106. >
  107. Manage Database Size
  108. </Link>
  109. </Button>
  110. </div>
  111. <div className="flex flex-col gap-2">
  112. <div className="flex items-center h-6 gap-3">
  113. <span className="text-foreground-light text-sm font-mono flex items-center gap-2">
  114. <span className="text-foreground font-semibold font-mono mt-[-2px]">
  115. {formatBytes(project.usage)}
  116. </span>{' '}
  117. Database Size
  118. </span>
  119. <InfoTooltip side="top">
  120. <p>
  121. {formatBytes(project.usage)} GB database size as reported by Postgres.
  122. </p>
  123. </InfoTooltip>
  124. </div>
  125. </div>
  126. </div>
  127. )
  128. })}
  129. </div>
  130. ) : (
  131. <Panel>
  132. <Panel.Content>
  133. <div className="flex flex-col items-center justify-center">
  134. <p className="text-sm">Data not available</p>
  135. <p className="text-sm text-foreground-light">
  136. Switch to current billing cycle to see current database size per project.
  137. </p>
  138. </div>
  139. </Panel.Content>
  140. </Panel>
  141. )}
  142. </div>
  143. </SectionContent>
  144. </div>
  145. )
  146. }
  147. export default DatabaseSizeUsage