import { useParams } from 'common' import dayjs from 'dayjs' import { Auth, Database, Realtime, Storage } from 'icons' import sumBy from 'lodash/sumBy' import Link from 'next/link' import { useRouter } from 'next/router' import { useEffect, useState } from 'react' import { Loading } from 'ui' import BarChart from '@/components/ui/Charts/BarChart' import { ChartIntervalDropdown } from '@/components/ui/Logs/ChartIntervalDropdown' import { CHART_INTERVALS } from '@/components/ui/Logs/logs.utils' import Panel from '@/components/ui/Panel' import { ProjectLogStatsVariables, UsageApiCounts, useProjectLogStatsQuery, } from '@/data/analytics/project-log-stats-query' import { useFillTimeseriesSorted } from '@/hooks/analytics/useFillTimeseriesSorted' import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements' import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' type ChartIntervalKey = ProjectLogStatsVariables['interval'] const ProjectUsage = () => { const router = useRouter() const { ref: projectRef } = useParams() const { data: organization } = useSelectedOrganizationQuery() const { projectAuthAll: authEnabled, projectStorageAll: storageEnabled } = useIsFeatureEnabled([ 'project_auth:all', 'project_storage:all', ]) const { getEntitlementMax } = useCheckEntitlements('log.retention_days') const retentionDays = getEntitlementMax() const DEFAULT_INTERVAL: ChartIntervalKey = retentionDays !== undefined && retentionDays < 7 ? '1hr' : '1day' const [interval, setInterval] = useState(DEFAULT_INTERVAL) useEffect(() => { setInterval(retentionDays !== undefined && retentionDays < 7 ? '1hr' : '1day') }, [retentionDays]) const { data, isPending: isLoading } = useProjectLogStatsQuery({ projectRef, interval }) const selectedInterval = CHART_INTERVALS.find((i) => i.key === interval) || CHART_INTERVALS[1] const startDateLocal = dayjs().subtract( selectedInterval.startValue, selectedInterval.startUnit as dayjs.ManipulateType ) const endDateLocal = dayjs() const { data: charts } = useFillTimeseriesSorted({ data: data?.result ?? [], timestampKey: 'timestamp', valueKey: [ 'total_auth_requests', 'total_rest_requests', 'total_storage_requests', 'total_realtime_requests', ], defaultValue: 0, startDate: startDateLocal.toISOString(), endDate: endDateLocal.toISOString(), minPointsToFill: 5, }) const datetimeFormat = selectedInterval.format || 'MMM D, ha' const handleBarClick = ( value: UsageApiCounts, _type: 'rest' | 'realtime' | 'storage' | 'auth' ) => { const unit = selectedInterval.startUnit const selectedStart = dayjs(value?.timestamp) const selectedEnd = selectedStart.add(1, unit) if (_type === 'rest') { router.push( `/project/${projectRef}/logs/edge-logs?its=${selectedStart.toISOString()}&ite=${selectedEnd.toISOString()}` ) return } router.push( `/project/${projectRef}/logs/edge-logs?its=${selectedStart.toISOString()}&ite=${selectedEnd.toISOString()}&f=${JSON.stringify( { product: { [_type]: true, }, } )}` ) } return (
setInterval(interval as ProjectLogStatsVariables['interval'])} organizationSlug={organization?.slug} dropdownAlign="start" tooltipSide="right" /> Statistics for {selectedInterval.label.toLowerCase()}
} title="Database" href={`/project/${projectRef}/editor`} /> handleBarClick(v as UsageApiCounts, 'rest')} customDateFormat={datetimeFormat} highlightedValue={sumBy(charts, 'total_rest_requests')} /> {authEnabled && (
} title="Auth" href={`/project/${projectRef}/auth/users`} /> handleBarClick(v as UsageApiCounts, 'auth')} customDateFormat={datetimeFormat} highlightedValue={sumBy(charts || [], 'total_auth_requests')} /> )} {storageEnabled && ( } title="Storage" href={`/project/${projectRef}/storage/buckets`} /> handleBarClick(v as UsageApiCounts, 'storage')} customDateFormat={datetimeFormat} highlightedValue={sumBy(charts, 'total_storage_requests')} /> )} } title="Realtime" /> handleBarClick(v as UsageApiCounts, 'realtime')} customDateFormat={datetimeFormat} highlightedValue={sumBy(charts, 'total_realtime_requests')} /> ) } export default ProjectUsage const PanelHeader = (props: any) => { const Tag = props?.href ? Link : 'div' return (
{props.icon}

{props.title}

) }