mirror of
https://github.com/supabase/supabase.git
synced 2026-05-06 08:56:46 -04:00
157 lines
5.4 KiB
TypeScript
157 lines
5.4 KiB
TypeScript
import type { ComponentProps } from 'react'
|
|
import { useMemo } from 'react'
|
|
import { Button } from 'ui'
|
|
import { Chart, ChartActions, ChartLoadingState, ChartMetric } from 'ui-patterns/Chart'
|
|
import { PageContainer } from 'ui-patterns/PageContainer'
|
|
import {
|
|
PageSection,
|
|
PageSectionAside,
|
|
PageSectionContent,
|
|
PageSectionMeta,
|
|
PageSectionSummary,
|
|
} from 'ui-patterns/PageSection'
|
|
import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
|
|
|
|
import { EdgeFunctionChartEmptyState } from './EdgeFunctionChartEmptyState'
|
|
import { EdgeFunctionInvocationsChart } from './EdgeFunctionInvocationsChart'
|
|
import {
|
|
EDGE_FUNCTION_CHART_INTERVALS,
|
|
formatRate,
|
|
getChartEmptyStateCopy,
|
|
getSegmentedButtonClassName,
|
|
} from './EdgeFunctionOverview.utils'
|
|
import type { InvocationChartDatum, InvocationUpdateAnnotation } from './EdgeFunctionOverview.utils'
|
|
import { toAlertError } from './EdgeFunctionRecentErrors.utils'
|
|
import AlertError from '@/components/ui/AlertError'
|
|
import type { ChartIntervals } from '@/types'
|
|
|
|
interface EdgeFunctionInvocationsSectionProps {
|
|
interval: string
|
|
onIntervalChange: (interval: string) => void
|
|
selectedInterval: ChartIntervals
|
|
actions?: ComponentProps<typeof ChartActions>['actions']
|
|
totalInvocationCount: number
|
|
totalErrorCount: number
|
|
totalWarningCount: number
|
|
isLoadingFunction: boolean
|
|
isErrorFunction: boolean
|
|
functionError?: unknown
|
|
isLoadingChart: boolean
|
|
isErrorChart: boolean
|
|
chartErrorMessage?: string
|
|
chartData: InvocationChartDatum[]
|
|
onChartClick: () => void
|
|
updateAnnotation?: InvocationUpdateAnnotation
|
|
}
|
|
|
|
export const EdgeFunctionInvocationsSection = ({
|
|
interval,
|
|
onIntervalChange,
|
|
selectedInterval,
|
|
actions,
|
|
totalInvocationCount,
|
|
totalErrorCount,
|
|
totalWarningCount,
|
|
isLoadingFunction,
|
|
isErrorFunction,
|
|
functionError,
|
|
isLoadingChart,
|
|
isErrorChart,
|
|
chartErrorMessage,
|
|
chartData,
|
|
onChartClick,
|
|
updateAnnotation,
|
|
}: EdgeFunctionInvocationsSectionProps) => {
|
|
const dateTimeFormat = selectedInterval.format ?? 'MMM D, h:mma'
|
|
const emptyStateCopy = useMemo(
|
|
() => getChartEmptyStateCopy('invocations', isErrorChart, chartErrorMessage),
|
|
[chartErrorMessage, isErrorChart]
|
|
)
|
|
|
|
return (
|
|
<PageSection className="bg-surface-100/50 border-b pb-10 pt-8">
|
|
<PageSectionContent>
|
|
<PageContainer size="full">
|
|
<div className="flex flex-col gap-5">
|
|
<PageSectionMeta className="!items-center">
|
|
<PageSectionSummary>
|
|
<div className="flex flex-wrap items-start gap-x-8 gap-y-4">
|
|
<ChartMetric
|
|
label="Total Invocations"
|
|
value={totalInvocationCount}
|
|
status="default"
|
|
tooltip="Total number of invocations"
|
|
/>
|
|
<ChartMetric
|
|
label="5xx Rate"
|
|
value={formatRate(totalErrorCount, totalInvocationCount)}
|
|
status="negative"
|
|
tooltip="Share of invocations that returned a 5xx status code"
|
|
/>
|
|
<ChartMetric
|
|
label="4xx Rate"
|
|
value={formatRate(totalWarningCount, totalInvocationCount)}
|
|
status="warning"
|
|
tooltip="Share of invocations that returned a 4xx status code"
|
|
/>
|
|
</div>
|
|
</PageSectionSummary>
|
|
<PageSectionAside className="flex-wrap @xl:self-center">
|
|
<div className="flex items-center">
|
|
{EDGE_FUNCTION_CHART_INTERVALS.map((item, index) => {
|
|
return (
|
|
<Button
|
|
key={`function-filter-${item.key}`}
|
|
type={interval === item.key ? 'secondary' : 'default'}
|
|
onClick={() => onIntervalChange(item.key)}
|
|
className={getSegmentedButtonClassName(
|
|
index,
|
|
EDGE_FUNCTION_CHART_INTERVALS.length
|
|
)}
|
|
>
|
|
{item.label}
|
|
</Button>
|
|
)
|
|
})}
|
|
</div>
|
|
<ChartActions actions={actions} />
|
|
</PageSectionAside>
|
|
</PageSectionMeta>
|
|
|
|
<div>
|
|
{isLoadingFunction && <GenericSkeletonLoader />}
|
|
{isErrorFunction && (
|
|
<AlertError
|
|
error={toAlertError(functionError)}
|
|
subject="Failed to retrieve edge function details"
|
|
layout="vertical"
|
|
/>
|
|
)}
|
|
</div>
|
|
|
|
<div>
|
|
<Chart isLoading={isLoadingChart}>
|
|
{isLoadingChart ? (
|
|
<ChartLoadingState />
|
|
) : isErrorChart || chartData.length === 0 ? (
|
|
<EdgeFunctionChartEmptyState
|
|
title={emptyStateCopy.title}
|
|
description={emptyStateCopy.description}
|
|
/>
|
|
) : (
|
|
<EdgeFunctionInvocationsChart
|
|
chartData={chartData}
|
|
dateTimeFormat={dateTimeFormat}
|
|
onChartClick={onChartClick}
|
|
updateAnnotation={updateAnnotation}
|
|
/>
|
|
)}
|
|
</Chart>
|
|
</div>
|
|
</div>
|
|
</PageContainer>
|
|
</PageSectionContent>
|
|
</PageSection>
|
|
)
|
|
}
|