Home / Function/ BillingMetric() — supabase Function Reference

BillingMetric() — supabase Function Reference

Architecture documentation for the BillingMetric() function in BillingMetric.tsx from the supabase codebase.

Entity Profile

Dependency Diagram

graph TD
  92c2398a_cf4a_5148_b198_86c7e7bb2151["BillingMetric()"]
  fced348a_ab7f_11cf_18fe_5313984546b4["billingMetricUnit()"]
  92c2398a_cf4a_5148_b198_86c7e7bb2151 -->|calls| fced348a_ab7f_11cf_18fe_5313984546b4
  33d44cde_fee6_d849_e1fe_792e48dd1fdb["formatUsage()"]
  92c2398a_cf4a_5148_b198_86c7e7bb2151 -->|calls| 33d44cde_fee6_d849_e1fe_792e48dd1fdb
  style 92c2398a_cf4a_5148_b198_86c7e7bb2151 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

apps/studio/components/interfaces/Organization/BillingSettings/BillingBreakdown/BillingMetric.tsx lines 24–251

export const BillingMetric = ({
  slug,
  metric,
  usage,
  subscription,
  relativeToSubscription,
  className,
}: BillingMetricProps) => {
  const usageMeta = usage.usages.find((x) => x.metric === metric.key)

  const usageLabel = useMemo(() => {
    if (!usageMeta) return ''

    if (relativeToSubscription && usageMeta.available_in_plan === false) {
      return 'Unavailable in plan'
    } else if (
      (usageMeta.cost && usageMeta.cost > 0) ||
      !relativeToSubscription ||
      usageMeta.unlimited ||
      usageMeta.pricing_free_units === 0
    ) {
      return metric.units === 'bytes' || metric.units === 'gigabytes'
        ? `${usageMeta.usage.toLocaleString() ?? 0} GB`
        : usageMeta.usage.toLocaleString() + (metric.unitName ? ` ${metric.unitName}` : '')
    } else {
      return metric.units === 'bytes' || metric.units === 'gigabytes'
        ? `${usageMeta.usage.toLocaleString() ?? 0} / ${usageMeta.pricing_free_units ?? 0} GB`
        : `${usageMeta.usage.toLocaleString()} / ${usageMeta.pricing_free_units?.toLocaleString()}` +
            (metric.unitName ? ` ${metric.unitName}` : '')
    }
  }, [usageMeta, relativeToSubscription, metric])

  const sortedProjectAllocations = useMemo(() => {
    if (!usageMeta || !usageMeta.project_allocations) return []

    return usageMeta.project_allocations.sort((a, b) => b.usage - a.usage)
  }, [usageMeta])

  if (!usageMeta) return null

  const usageRatio =
    usageMeta.usage === 0 ? 0 : usageMeta.usage / (usageMeta.pricing_free_units ?? 0)

  const isUsageBillingEnabled = subscription?.usage_billing_enabled === true

  const hasLimit = !!usageMeta.unlimited === false
  const isApproachingLimit = hasLimit && usageRatio >= USAGE_APPROACHING_THRESHOLD
  const isExceededLimit = relativeToSubscription && hasLimit && usageRatio >= 1

  const unit = billingMetricUnit(usageMeta.metric as PricingMetric)

  const percentageLabel =
    usageMeta.usage === 0 || usageMeta.pricing_free_units === 0
      ? ''
      : usageRatio < 0.01
        ? '(<1%)'
        : `(${(+(usageRatio * 100).toFixed(0)).toLocaleString()}%)`

  return (
    <HoverCard openDelay={50} closeDelay={200}>
      <HoverCardTrigger asChild>
        <div className={cn('flex items-center justify-between', className)}>
          {metric.anchor ? (
            <Link href={`/org/${slug}/usage#${metric.anchor}`} className="block w-full group">
              <div className="group flex items-center gap-1">
                <p className="text-sm text-foreground-light group-hover:text-foreground transition cursor-pointer">
                  {metric.name}
                </p>
                {usageMeta.available_in_plan && (
                  <span className="text-foreground-muted transition inline-block group-hover:transform group-hover:translate-x-0.5">
                    <ChevronRight strokeWidth={1.5} size={16} className="transition" />
                  </span>
                )}
              </div>
              <span className="text-sm">{usageLabel}</span>&nbsp;
              {relativeToSubscription && usageMeta.cost && usageMeta.cost > 0 ? (
                <span className="text-sm" translate="no">
                  ({formatCurrency(usageMeta.cost)})
                </span>
              ) : usageMeta.available_in_plan &&
                usageMeta.pricing_free_units !== 0 &&
                !usageMeta.unlimited &&
                relativeToSubscription ? (
                <span className="text-sm">{percentageLabel}</span>
              ) : null}
            </Link>
          ) : (
            <div className="block w-full">
              <p className="text-sm text-foreground-light flex space-x-1">{metric.name}</p>
              <span className="text-sm">{usageLabel}</span>&nbsp;
              {relativeToSubscription && usageMeta.cost && usageMeta.cost > 0 ? (
                <span className="text-sm" translate="no">
                  ({formatCurrency(usageMeta.cost)})
                </span>
              ) : usageMeta.available_in_plan &&
                usageMeta.pricing_free_units !== 0 &&
                !usageMeta.unlimited &&
                relativeToSubscription ? (
                <span className="text-sm">{percentageLabel}</span>
              ) : null}
            </div>
          )}

          {usageMeta.available_in_plan ? (
            <div>
              {relativeToSubscription &&
              !usageMeta.unlimited &&
              usageMeta.pricing_free_units !== 0 ? (
                <svg className="h-8 w-8 -rotate-90 transform">
                  <circle
                    cx={15}
                    cy={15}
                    r={12}
                    fill="transparent"
                    stroke="currentColor"
                    strokeWidth={4}
                    className="text-background-surface-300"
                  />
                  <circle
                    cx={15}
                    cy={15}
                    r={12}
                    fill="transparent"
                    stroke="currentColor"
                    strokeDasharray={75.398}
                    strokeDashoffset={`calc(75.39822 - ${
                      usageRatio < 1 ? usageRatio * 100 : 100
                    } / 100 * 75.39822)`}
                    strokeWidth={4}
                    className={
                      isUsageBillingEnabled
                        ? 'text-gray-dark-800'
                        : isExceededLimit
                          ? 'text-red-900'
                          : isApproachingLimit
                            ? 'text-yellow-1000'
                            : 'text-gray-dark-800'
                    }
                  />
                </svg>
              ) : null}
            </div>
          ) : (
            <div>
              <UpgradePlanButton
                source={`billingBreakdownUsage${metric.anchor}`}
                featureProposition={`to use ${metric.name}`}
              >
                Upgrade
              </UpgradePlanButton>
            </div>
          )}
        </div>
      </HoverCardTrigger>
      {usageMeta.available_in_plan && (
        <HoverCardContent side="bottom" align="end" className="w-[500px]" animate="slide-in">
          <div className="text-sm">
            <p className="font-medium" translate="no">
              {usageMeta.unit_price_desc}
            </p>

            {metric.tip && (
              <div className="my-2">
                <p className="text-sm">
                  {metric.tip}{' '}
                  {metric.docLink && (
                    <Link
                      href={metric.docLink.url}
                      target="_blank"
                      className="transition text-brand hover:text-brand-600 underline"
                    >
                      {metric.docLink.title}
                    </Link>
                  )}
                </p>
              </div>
            )}

            {subscription.usage_billing_enabled === false &&
              relativeToSubscription &&
              (isApproachingLimit || isExceededLimit) && (
                <div className="my-2">
                  <p className="text-sm">
                    Exceeding your plans included usage will lead to restrictions to your project.
                    Upgrade to a usage-based plan or disable the spend cap to avoid restrictions.
                  </p>
                </div>
              )}

            {sortedProjectAllocations && sortedProjectAllocations.length > 0 && (
              <table className="list-disc w-full">
                <thead>
                  <tr>
                    <th className="text-left">Project</th>
                    <th className="text-right">Usage</th>
                  </tr>
                </thead>
                <tbody>
                  {sortedProjectAllocations.map((allocation) => (
                    <tr key={`${usageMeta.metric}_${allocation.ref}`}>
                      <td>{allocation.name}</td>
                      <td className="text-right">
                        {formatUsage(usageMeta.metric as PricingMetric, allocation)}
                      </td>
                    </tr>
                  ))}
                  <tr></tr>
                </tbody>
                <tfoot>
                  <tr>
                    <td className="py-2 border-t text-left">
                      Total{unit && <span> ({unit})</span>}
                    </td>
                    <td className="py-2 border-t text-right">
                      {formatUsage(usageMeta.metric as PricingMetric, {
                        usage: usageMeta.usage_original,
                      })}{' '}
                    </td>
                  </tr>
                </tfoot>
              </table>
            )}
          </div>
        </HoverCardContent>
      )}
    </HoverCard>
  )
}

Subdomains

Frequently Asked Questions

What does BillingMetric() do?
BillingMetric() is a function in the supabase codebase.
What does BillingMetric() call?
BillingMetric() calls 2 function(s): billingMetricUnit, formatUsage.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free