mirror of
https://github.com/supabase/supabase.git
synced 2026-06-13 01:39:53 +08:00
## Summary Wires Linear-style keyboard shortcuts across all observability pages — refresh, time picker, filters, and sub-page navigation — with hover tooltips surfacing each binding. | Page | Shortcut | Action | | --- | --- | --- | | Overview | `Shift+R` | Refresh report | | Overview | `Shift+P` | Open time picker | | Query Performance | `Shift+R` | Refresh report | | Query Performance | `R` then `C` | Reset report (`pg_stat_statements_reset`) | | Query Performance | `Shift+F` | Search queries | | Query Performance | `F` then `C` | Reset filters | | API Gateway | `Shift+R` | Refresh report | | API Gateway | `Shift+P` | Open time picker | | API Gateway | `Shift+F` | Add filter | | API Gateway | `F` then `C` | Reset filters | | API Gateway | `Shift+S` | Filter requests by service | | Database | `Shift+R` | Refresh report | | Database | `Shift+P` | Open time picker | | Auth | `Shift+R` | Refresh report | | Auth | `Shift+P` | Open time picker | | Data API | `Shift+R` | Refresh report | | Data API | `Shift+P` | Open time picker | | Storage | `Shift+R` | Refresh report | | Storage | `Shift+P` | Open time picker | | Realtime | `Shift+R` | Refresh report | | Realtime | `Shift+P` | Open time picker | | Edge Functions | `Shift+R` | Refresh report | | Edge Functions | `Shift+P` | Open time picker | | All observability pages | `U` then `O/Q/G/D/P/A/F/S/L` | Jump to sub-page | ## Test plan - [ ] Each shortcut fires on its page; tooltip on hover shows the binding - [ ] Picker shortcut toggles the popover open/closed without leaving the tooltip visible - [ ] Reset-report on Query Performance opens the confirm modal - [ ] `Escape` on the query search clears the value, then blurs - [ ] No "Shift+R already registered" / Tooltip controlled-uncontrolled warnings in the console <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Keyboard shortcuts to navigate Observability pages and perform common actions (refresh, toggle date picker/interval, focus search, reset filters, create reports). * Shortcut hints shown on relevant buttons and controls; date pickers and interval dropdowns can be controlled via shortcuts. * Global shortcut groups/registries added for Observability navigation and page actions. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46277?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
106 lines
3.7 KiB
TypeScript
106 lines
3.7 KiB
TypeScript
import { ChevronDown } from 'lucide-react'
|
|
import {
|
|
Button,
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuRadioGroup,
|
|
DropdownMenuRadioItem,
|
|
DropdownMenuTrigger,
|
|
Tooltip,
|
|
TooltipContent,
|
|
TooltipTrigger,
|
|
} from 'ui'
|
|
|
|
import { CHART_INTERVALS } from './logs.utils'
|
|
import { InlineLink } from '@/components/ui/InlineLink'
|
|
import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
|
|
|
|
function getDaysRequired(startValue: number, startUnit: string): number {
|
|
if (startUnit === 'day') return startValue
|
|
if (startUnit === 'hour') return startValue / 24
|
|
return 0
|
|
}
|
|
|
|
interface ChartIntervalDropdownProps {
|
|
value: string
|
|
onChange: (value: string) => void
|
|
organizationSlug?: string
|
|
dropdownAlign?: 'start' | 'center' | 'end'
|
|
tooltipSide?: 'left' | 'right' | 'top' | 'bottom'
|
|
open?: boolean
|
|
onOpenChange?: (open: boolean) => void
|
|
}
|
|
|
|
export const ChartIntervalDropdown = ({
|
|
value,
|
|
onChange,
|
|
organizationSlug,
|
|
dropdownAlign = 'start',
|
|
tooltipSide = 'right',
|
|
open,
|
|
onOpenChange,
|
|
}: ChartIntervalDropdownProps) => {
|
|
const selectedInterval = CHART_INTERVALS.find((i) => i.key === value) || CHART_INTERVALS[1]
|
|
|
|
const { getEntitlementMax } = useCheckEntitlements('log.retention_days')
|
|
const retentionDays = getEntitlementMax()
|
|
|
|
return (
|
|
<DropdownMenu open={open} onOpenChange={onOpenChange}>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button type="default" iconRight={<ChevronDown size={14} />}>
|
|
<span>{selectedInterval.label}</span>
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent side="bottom" align={dropdownAlign} className="w-40">
|
|
<DropdownMenuRadioGroup value={value} onValueChange={onChange}>
|
|
{CHART_INTERVALS.map((i) => {
|
|
const daysRequired = getDaysRequired(i.startValue, i.startUnit)
|
|
const disabled = retentionDays !== undefined && daysRequired > retentionDays
|
|
|
|
if (disabled) {
|
|
return (
|
|
<Tooltip key={i.key}>
|
|
<TooltipTrigger asChild>
|
|
<DropdownMenuRadioItem disabled value={i.key} className="pointer-events-auto!">
|
|
{i.label}
|
|
</DropdownMenuRadioItem>
|
|
</TooltipTrigger>
|
|
<TooltipContent side={tooltipSide}>
|
|
<p>
|
|
Your plan only includes up to {retentionDays} day
|
|
{retentionDays !== undefined && retentionDays > 1 ? 's' : ''} of log retention
|
|
</p>
|
|
<p className="text-foreground-light">
|
|
{organizationSlug ? (
|
|
<>
|
|
<InlineLink
|
|
className="text-foreground-light hover:text-foreground"
|
|
href={`/org/${organizationSlug}/billing?panel=subscriptionPlan`}
|
|
>
|
|
Upgrade your plan
|
|
</InlineLink>{' '}
|
|
to increase log retention and view statistics for the{' '}
|
|
{i.label.toLowerCase()}
|
|
</>
|
|
) : (
|
|
`Upgrade your plan to increase log retention and view statistics for the ${i.label.toLowerCase()}`
|
|
)}
|
|
</p>
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
)
|
|
} else {
|
|
return (
|
|
<DropdownMenuRadioItem key={i.key} value={i.key}>
|
|
{i.label}
|
|
</DropdownMenuRadioItem>
|
|
)
|
|
}
|
|
})}
|
|
</DropdownMenuRadioGroup>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
)
|
|
}
|