interval dropdown

This commit is contained in:
Saxon Fletcher committed 2026-05-26 14:40:35 +10:00
1 parent 165dd41a25
commit 4af2b729fa
6 files changed
+49 -25

No files matched your search

@@ -39,6 +39,7 @@ export const EdgeFunctionOverview = () => {
const { isEnabled: isUnifiedLogsEnabled } = useUnifiedLogsPreview()
const [interval, setInterval] = useState<string>('15min')
const [showIntervalDropdown, setShowIntervalDropdown] = useState(false)
const selectedInterval =
EDGE_FUNCTION_CHART_INTERVALS.find((item) => item.key === interval) ||
EDGE_FUNCTION_CHART_INTERVALS[1]
@@ -153,6 +154,9 @@ export const EdgeFunctionOverview = () => {
useEdgeFunctionOverviewShortcuts({
onSetInterval: setInterval,
onToggleIntervalPicker: () => {
setShowIntervalDropdown((open) => !open)
},
onRefresh: () => {
combinedStatsResults.refetch()
},
@@ -186,7 +190,12 @@ export const EdgeFunctionOverview = () => {
return (
<>
<EdgeFunctionOverviewHeader interval={interval} onIntervalChange={setInterval} />
<EdgeFunctionOverviewHeader
interval={interval}
onIntervalChange={setInterval}
showIntervalDropdown={showIntervalDropdown}
onIntervalDropdownOpenChange={setShowIntervalDropdown}
/>
<PageContainer size="default">
<EdgeFunctionInvocationsSection
selectedInterval={selectedInterval}
@@ -52,28 +52,28 @@ export type InvocationUpdateAnnotation = {
export const EDGE_FUNCTION_CHART_INTERVALS: ChartIntervals[] = [
{
key: '15min',
label: '15 min',
label: 'Last 15 minutes',
startValue: 15,
startUnit: 'minute',
format: 'MMM D, h:mm:ssa',
},
{
key: '1hr',
label: '1 hour',
label: 'Last 60 minutes',
startValue: 1,
startUnit: 'hour',
format: 'MMM D, h:mma',
},
{
key: '3hr',
label: '3 hours',
label: 'Last 3 hours',
startValue: 3,
startUnit: 'hour',
format: 'MMM D, h:mma',
},
{
key: '1day',
label: '1 day',
label: 'Last 24 hours',
startValue: 1,
startUnit: 'day',
format: 'MMM D, h:mma',
@@ -3,7 +3,7 @@ import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import { Clock } from 'lucide-react'
import { useState } from 'react'
import { Button, HoverCard, HoverCardContent, HoverCardTrigger } from 'ui'
import { HoverCard, HoverCardContent, HoverCardTrigger } from 'ui'
import { TimestampInfo } from 'ui-patterns'
import {
PageHeader,
@@ -14,15 +14,13 @@ import {
PageHeaderTitle,
} from 'ui-patterns/PageHeader'
import {
EDGE_FUNCTION_CHART_INTERVALS,
formatShortFromNow,
getSegmentedButtonClassName,
} from './EdgeFunctionOverview.utils'
import { EDGE_FUNCTION_CHART_INTERVALS, formatShortFromNow } from './EdgeFunctionOverview.utils'
import CopyButton from '@/components/ui/CopyButton'
import { ChartIntervalDropdown } from '@/components/ui/Logs/ChartIntervalDropdown'
import { ShortcutTooltip } from '@/components/ui/ShortcutTooltip'
import { useProjectApiUrl } from '@/data/config/project-endpoint-query'
import { useEdgeFunctionQuery } from '@/data/edge-functions/edge-function-query'
import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
dayjs.extend(relativeTime)
@@ -30,14 +28,19 @@ dayjs.extend(relativeTime)
interface EdgeFunctionOverviewHeaderProps {
interval: string
onIntervalChange: (interval: string) => void
showIntervalDropdown?: boolean
onIntervalDropdownOpenChange?: (open: boolean) => void
}
export const EdgeFunctionOverviewHeader = ({
interval,
onIntervalChange,
showIntervalDropdown,
onIntervalDropdownOpenChange,
}: EdgeFunctionOverviewHeaderProps) => {
const { ref: projectRef, functionSlug } = useParams()
const [isTimestampHoverCardOpen, setIsTimestampHoverCardOpen] = useState(false)
const { data: organization } = useSelectedOrganizationQuery()
const { data: selectedFunction } = useEdgeFunctionQuery({
projectRef,
@@ -123,18 +126,16 @@ export const EdgeFunctionOverviewHeader = ({
</PageHeaderDescription>
</PageHeaderSummary>
<PageHeaderAside className="flex-wrap @xl:self-center">
<div className="flex items-center">
{EDGE_FUNCTION_CHART_INTERVALS.map((item, index) => (
<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>
<ChartIntervalDropdown
value={interval}
onChange={onIntervalChange}
intervals={EDGE_FUNCTION_CHART_INTERVALS}
organizationSlug={organization?.slug}
dropdownAlign="end"
tooltipSide="left"
open={showIntervalDropdown}
onOpenChange={onIntervalDropdownOpenChange}
/>
</PageHeaderAside>
</PageHeaderMeta>
</PageHeader>
@@ -3,6 +3,7 @@ import { useShortcut } from '@/state/shortcuts/useShortcut'
interface UseEdgeFunctionOverviewShortcutsParams {
onSetInterval: (key: string) => void
onToggleIntervalPicker: () => void
onRefresh: () => void
onOpenLogs: () => void
}
@@ -18,6 +19,7 @@ interface UseEdgeFunctionOverviewShortcutsParams {
*/
export function useEdgeFunctionOverviewShortcuts({
onSetInterval,
onToggleIntervalPicker,
onRefresh,
onOpenLogs,
}: UseEdgeFunctionOverviewShortcutsParams) {
@@ -25,6 +27,7 @@ export function useEdgeFunctionOverviewShortcuts({
useShortcut(SHORTCUT_IDS.FUNCTION_OVERVIEW_INTERVAL_1HR, () => onSetInterval('1hr'))
useShortcut(SHORTCUT_IDS.FUNCTION_OVERVIEW_INTERVAL_3HR, () => onSetInterval('3hr'))
useShortcut(SHORTCUT_IDS.FUNCTION_OVERVIEW_INTERVAL_1DAY, () => onSetInterval('1day'))
useShortcut(SHORTCUT_IDS.FUNCTION_OVERVIEW_TOGGLE_INTERVAL_PICKER, onToggleIntervalPicker)
useShortcut(SHORTCUT_IDS.FUNCTION_OVERVIEW_REFRESH, onRefresh)
useShortcut(SHORTCUT_IDS.FUNCTION_OVERVIEW_OPEN_LOGS, onOpenLogs)
}
@@ -14,6 +14,7 @@ import {
import { CHART_INTERVALS } from './logs.utils'
import { InlineLink } from '@/components/ui/InlineLink'
import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
import type { ChartIntervals } from '@/types'
function getDaysRequired(startValue: number, startUnit: string): number {
if (startUnit === 'day') return startValue
@@ -24,6 +25,7 @@ function getDaysRequired(startValue: number, startUnit: string): number {
interface ChartIntervalDropdownProps {
value: string
onChange: (value: string) => void
intervals?: ChartIntervals[]
organizationSlug?: string
dropdownAlign?: 'start' | 'center' | 'end'
tooltipSide?: 'left' | 'right' | 'top' | 'bottom'
@@ -34,13 +36,14 @@ interface ChartIntervalDropdownProps {
export const ChartIntervalDropdown = ({
value,
onChange,
intervals = CHART_INTERVALS,
organizationSlug,
dropdownAlign = 'start',
tooltipSide = 'right',
open,
onOpenChange,
}: ChartIntervalDropdownProps) => {
const selectedInterval = CHART_INTERVALS.find((i) => i.key === value) || CHART_INTERVALS[1]
const selectedInterval = intervals.find((i) => i.key === value) || intervals[1]
const { getEntitlementMax } = useCheckEntitlements('log.retention_days')
const retentionDays = getEntitlementMax()
@@ -54,7 +57,7 @@ export const ChartIntervalDropdown = ({
</DropdownMenuTrigger>
<DropdownMenuContent side="bottom" align={dropdownAlign} className="w-40">
<DropdownMenuRadioGroup value={value} onValueChange={onChange}>
{CHART_INTERVALS.map((i) => {
{intervals.map((i) => {
const daysRequired = getDaysRequired(i.startValue, i.startUnit)
const disabled = retentionDays !== undefined && daysRequired > retentionDays
@@ -11,6 +11,7 @@ export const FUNCTIONS_OVERVIEW_SHORTCUT_IDS = {
FUNCTION_OVERVIEW_INTERVAL_1HR: 'functions-overview.interval-1hr',
FUNCTION_OVERVIEW_INTERVAL_3HR: 'functions-overview.interval-3hr',
FUNCTION_OVERVIEW_INTERVAL_1DAY: 'functions-overview.interval-1day',
FUNCTION_OVERVIEW_TOGGLE_INTERVAL_PICKER: 'functions-overview.toggle-interval-picker',
FUNCTION_OVERVIEW_REFRESH: 'functions-overview.refresh',
FUNCTION_OVERVIEW_OPEN_LOGS: 'functions-overview.open-logs',
}
@@ -47,6 +48,13 @@ export const functionsOverviewRegistry: RegistryDefinations<FunctionsOverviewSho
showInSettings: false,
options: { ignoreInputs: true, registerInCommandMenu: true },
},
[FUNCTIONS_OVERVIEW_SHORTCUT_IDS.FUNCTION_OVERVIEW_TOGGLE_INTERVAL_PICKER]: {
id: FUNCTIONS_OVERVIEW_SHORTCUT_IDS.FUNCTION_OVERVIEW_TOGGLE_INTERVAL_PICKER,
label: 'Open time picker',
sequence: ['Shift+P'],
showInSettings: false,
options: { ignoreInputs: true, registerInCommandMenu: true, conflictBehavior: 'allow' },
},
[FUNCTIONS_OVERVIEW_SHORTCUT_IDS.FUNCTION_OVERVIEW_REFRESH]: {
id: FUNCTIONS_OVERVIEW_SHORTCUT_IDS.FUNCTION_OVERVIEW_REFRESH,
label: 'Refresh function stats',