mirror of
https://github.com/supabase/supabase.git
synced 2026-06-10 21:41:25 +08:00
Adds the final set of keyboard shortcuts to the Unified Logs page and converts the last hardcoded `keydown` listener (detail-panel prev/next) to the shared shortcut registry. Each action also surfaces its keybind in a registry-driven tooltip. Closes FE-3415. ## Shortcuts | Action | Shortcut | Notes | | --- | --- | --- | | Refresh logs | `Shift+R` | new | | Download logs | `Shift+E` | new — opens export dropdown | | Focus filter bar | `Shift+F` | new | | Clear filters | `F` then `C` | new | | Copy selected as JSON | `Mod+Shift+J` | new — reuses `results.copy-json` | | Copy selected as Markdown | `Mod+Shift+M` | new — reuses `results.copy-markdown` | | Previous / next log (detail panel) | `↑` / `↓` | converted from hardcoded listener | | Close details panel | `Escape` | new | Existing shared `data-table.*` shortcuts kept as-is: toggle sidebar (`Mod+B`), live mode (`Mod+J`), reset filters (`Mod+Esc`), reset columns (`Mod+U`), reset focus (`Mod+.`). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added keyboard shortcuts for Unified Logs: copy selected rows as JSON/Markdown, navigate rows, refresh, clear/reset filters, download, and focus filter — shortcuts show in the command menu and display badges/hints in menus and buttons. * **Refactor** * Shortcut handling unified across log controls; shortcuts enable/disable based on context and a new "Logs" group appears in the shortcut reference. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
80 lines
2.2 KiB
TypeScript
80 lines
2.2 KiB
TypeScript
import type { FetchPreviousPageOptions } from '@tanstack/react-query'
|
|
import { CirclePause, CirclePlay } from 'lucide-react'
|
|
import { useQueryStates } from 'nuqs'
|
|
import { useEffect } from 'react'
|
|
import { Button, cn } from 'ui'
|
|
|
|
import { useDataTable } from './providers/DataTableProvider'
|
|
import { ShortcutTooltip } from '@/components/ui/ShortcutTooltip'
|
|
import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
|
|
import { useShortcut } from '@/state/shortcuts/useShortcut'
|
|
|
|
const REFRESH_INTERVAL = 10_000
|
|
|
|
interface LiveButtonProps {
|
|
searchParamsParser: any
|
|
fetchPreviousPage?: (options?: FetchPreviousPageOptions | undefined) => Promise<unknown>
|
|
}
|
|
|
|
export function LiveButton({ fetchPreviousPage, searchParamsParser }: LiveButtonProps) {
|
|
const [{ live, date, sort }, setSearch] = useQueryStates(searchParamsParser)
|
|
const { table } = useDataTable()
|
|
useShortcut(SHORTCUT_IDS.DATA_TABLE_TOGGLE_LIVE, handleClick, { registerInCommandMenu: true })
|
|
|
|
useEffect(() => {
|
|
let timeoutId: NodeJS.Timeout
|
|
|
|
async function fetchData() {
|
|
if (live) {
|
|
await fetchPreviousPage?.()
|
|
timeoutId = setTimeout(fetchData, REFRESH_INTERVAL)
|
|
} else {
|
|
clearTimeout(timeoutId)
|
|
}
|
|
}
|
|
|
|
fetchData()
|
|
|
|
return () => {
|
|
clearTimeout(timeoutId)
|
|
}
|
|
}, [live, fetchPreviousPage])
|
|
|
|
// REMINDER: make sure to reset live when date is set
|
|
// TODO: test properly
|
|
useEffect(() => {
|
|
if ((date || sort) && live) {
|
|
setSearch((prev) => ({ ...prev, live: null }))
|
|
}
|
|
}, [date, sort])
|
|
|
|
function handleClick() {
|
|
setSearch((prev) => ({
|
|
...prev,
|
|
live: !prev.live,
|
|
date: null,
|
|
sort: null,
|
|
}))
|
|
table.getColumn('date')?.setFilterValue(undefined)
|
|
table.resetSorting()
|
|
}
|
|
|
|
return (
|
|
<ShortcutTooltip
|
|
shortcutId={SHORTCUT_IDS.DATA_TABLE_TOGGLE_LIVE}
|
|
label={live ? 'Pause live mode' : 'Start live mode'}
|
|
side="bottom"
|
|
>
|
|
<Button
|
|
className={cn(live && 'border-info text-info hover:text-info')}
|
|
onClick={handleClick}
|
|
type={live ? 'primary' : 'default'}
|
|
size="tiny"
|
|
icon={live ? <CirclePause className="h-4 w-4" /> : <CirclePlay className="h-4 w-4" />}
|
|
>
|
|
Live
|
|
</Button>
|
|
</ShortcutTooltip>
|
|
)
|
|
}
|