Files
Kevin Grüneberg 4b948672a3 feat: support platform plan usage insights (#41185)
- Adds missing log and active compute hour insights in both usage summary and daily stats (only Platform Plan)
- Adds database size usage insights for platform orgs
- Hide the circular progress bar if the usage item has no included usage (otherwise always 100% filled with any usage)
- Hide percentage if usage item has no included usage
- Adjust upcoming invoice breakdown to properly handle compute and active compute hours
- Hide subscription change button for platform/enterprise orgs (we already have a callout saying they gotta reach out to us)
- Adjusted database size insights for platform to no longer display 0.5 GB per project being included
2025-12-15 16:14:46 +08:00

109 lines
3.2 KiB
TypeScript

import { ScaffoldContainer } from 'components/layouts/Scaffold'
import { DataPoint } from 'data/analytics/constants'
import { PricingMetric } from 'data/analytics/org-daily-stats-query'
import type { OrgSubscription } from 'data/subscriptions/types'
import { useOrgUsageQuery } from 'data/usage/org-usage-query'
import SectionHeader from '../SectionHeader'
import { CategoryMetaKey, USAGE_CATEGORIES } from '../Usage.constants'
import AttributeUsage from './AttributeUsage'
import DatabaseSizeUsage from './DatabaseSizeUsage'
import { DiskUsage } from './DiskUsage'
export interface ChartMeta {
[key: string]: { data: DataPoint[]; margin: number; isLoading: boolean }
}
export interface UsageSectionProps {
orgSlug: string
projectRef?: string | null
categoryKey: CategoryMetaKey
subscription?: OrgSubscription
chartMeta: ChartMeta
currentBillingCycleSelected: boolean
startDate?: string
endDate?: string
}
const UsageSection = ({
orgSlug,
projectRef,
categoryKey,
chartMeta,
subscription,
currentBillingCycleSelected,
startDate,
endDate,
}: UsageSectionProps) => {
const {
data: usage,
error: usageError,
isPending: isLoadingUsage,
isError: isErrorUsage,
isSuccess: isSuccessUsage,
} = useOrgUsageQuery({
orgSlug,
projectRef,
start: !currentBillingCycleSelected && startDate ? new Date(startDate) : undefined,
end: !currentBillingCycleSelected && endDate ? new Date(endDate) : undefined,
})
const categoryMeta = USAGE_CATEGORIES(subscription).find(
(category) => category.key === categoryKey
)
if (!categoryMeta) return null
return (
<>
<ScaffoldContainer>
<SectionHeader
title={categoryMeta.name}
description={categoryMeta.description}
className="pb-0"
/>
</ScaffoldContainer>
{categoryMeta.attributes.map((attribute) =>
attribute.key === 'diskSize' ? (
<DiskUsage
key={attribute.name}
slug={orgSlug}
projectRef={projectRef}
attribute={attribute}
subscription={subscription}
currentBillingCycleSelected={currentBillingCycleSelected}
usage={usage}
/>
) : attribute.key === PricingMetric.DATABASE_SIZE && subscription?.plan.id === 'free' ? (
<DatabaseSizeUsage
key={attribute.name}
slug={orgSlug}
projectRef={projectRef}
attribute={attribute}
subscription={subscription}
currentBillingCycleSelected={currentBillingCycleSelected}
usage={usage}
/>
) : (
<AttributeUsage
key={attribute.name}
slug={orgSlug}
projectRef={projectRef}
attribute={attribute}
usage={usage}
usageMeta={usage?.usages.find((x) => x.metric === attribute.key)}
chartMeta={chartMeta}
subscription={subscription}
error={usageError}
isLoading={isLoadingUsage}
isError={isErrorUsage}
isSuccess={isSuccessUsage}
currentBillingCycleSelected={currentBillingCycleSelected}
/>
)
)}
</>
)
}
export default UsageSection