ActiveCompute.tsx104 lines · main
| 1 | import { BarChart2 } from 'lucide-react' |
| 2 | import { useMemo } from 'react' |
| 3 | import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' |
| 4 | |
| 5 | import { SectionContent } from './SectionContent' |
| 6 | import { dailyUsageToDataPoints } from './Usage.utils' |
| 7 | import UsageBarChart from './UsageBarChart' |
| 8 | import Panel from '@/components/ui/Panel' |
| 9 | import { DataPoint } from '@/data/analytics/constants' |
| 10 | import { PricingMetric, type OrgDailyUsageResponse } from '@/data/analytics/org-daily-stats-query' |
| 11 | import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' |
| 12 | import { DOCS_URL } from '@/lib/constants' |
| 13 | |
| 14 | export interface ComputeProps { |
| 15 | orgDailyStats: OrgDailyUsageResponse | undefined |
| 16 | isLoadingOrgDailyStats: boolean |
| 17 | } |
| 18 | |
| 19 | const ActiveCompute = ({ orgDailyStats, isLoadingOrgDailyStats }: ComputeProps) => { |
| 20 | const { billingAll } = useIsFeatureEnabled(['billing:all']) |
| 21 | |
| 22 | const chartData: DataPoint[] = dailyUsageToDataPoints( |
| 23 | orgDailyStats, |
| 24 | (metric) => metric === PricingMetric.ACTIVE_COMPUTE_HOURS |
| 25 | ) |
| 26 | |
| 27 | const notAllValuesZero = useMemo(() => { |
| 28 | return chartData.some( |
| 29 | (dataPoint) => |
| 30 | dataPoint['active_compute_hours'] && Number(dataPoint['active_compute_hours']) > 0 |
| 31 | ) |
| 32 | }, [chartData]) |
| 33 | |
| 34 | return ( |
| 35 | <div id="active-compute" className="scroll-my-12"> |
| 36 | <SectionContent |
| 37 | section={{ |
| 38 | name: 'Active Compute Hours', |
| 39 | description: |
| 40 | 'Amount of active compute hours your projects on scale-to-zero instances consumed. Projects on scale-to-zero instances automatically scale down after a 15m inactivity period.', |
| 41 | links: billingAll |
| 42 | ? [ |
| 43 | { |
| 44 | name: 'Learn more', |
| 45 | url: `${DOCS_URL}/guides/integrations/briven-for-platforms#pico-compute-instance`, |
| 46 | }, |
| 47 | ] |
| 48 | : [], |
| 49 | }} |
| 50 | > |
| 51 | {isLoadingOrgDailyStats && <GenericSkeletonLoader />} |
| 52 | |
| 53 | {!isLoadingOrgDailyStats && ( |
| 54 | <> |
| 55 | <div className="space-y-1"> |
| 56 | {chartData.length > 0 && ( |
| 57 | <div className="flex items-center justify-between"> |
| 58 | <div className="flex items-center space-x-4"> |
| 59 | <p className="text-sm">Active Compute Hours usage</p> |
| 60 | </div> |
| 61 | </div> |
| 62 | )} |
| 63 | |
| 64 | <div className="flex items-center justify-between border-b last:border-b-0 py-1 last:py-0"> |
| 65 | <p className="text-sm text-foreground-light"> |
| 66 | Active Compute Hours usage in period |
| 67 | </p> |
| 68 | <p className="text-sm"> |
| 69 | {chartData.reduce( |
| 70 | (prev, cur) => prev + ((cur['active_compute_hours'] as number) ?? 0), |
| 71 | 0 |
| 72 | )}{' '} |
| 73 | hours |
| 74 | </p> |
| 75 | </div> |
| 76 | </div> |
| 77 | |
| 78 | {chartData.length > 0 && notAllValuesZero ? ( |
| 79 | <UsageBarChart |
| 80 | name={`Active Compute Hours usage`} |
| 81 | unit={'hours'} |
| 82 | attributes={[{ key: 'active_compute_hours', color: 'blue' }]} |
| 83 | data={chartData} |
| 84 | yMin={24} |
| 85 | /> |
| 86 | ) : ( |
| 87 | <Panel> |
| 88 | <Panel.Content> |
| 89 | <div className="flex flex-col items-center justify-center"> |
| 90 | <BarChart2 className="text-foreground-light mb-2" /> |
| 91 | <p className="text-sm">No data in period</p> |
| 92 | <p className="text-sm text-foreground-light">May take up to one hour to show</p> |
| 93 | </div> |
| 94 | </Panel.Content> |
| 95 | </Panel> |
| 96 | )} |
| 97 | </> |
| 98 | )} |
| 99 | </SectionContent> |
| 100 | </div> |
| 101 | ) |
| 102 | } |
| 103 | |
| 104 | export default ActiveCompute |