mirror of
https://github.com/supabase/supabase.git
synced 2026-10-10 20:05:06 +03:00
## What kind of change does this PR introduce? Feature — adds keyboard shortcuts for the Realtime section in Studio. ## What is the current behavior? No keyboard shortcuts exist for Realtime navigation or inspector actions. ## What is the new behavior? ### Navigation chords (layout-scoped, active on any Realtime page) | Shortcut | Action | |---|---| | `R I` | Go to Inspector | | `R P` | Go to Policies | | `R S` | Go to Settings | ### Inspector actions (active on the Inspector page) | Shortcut | Action | Gating | |---|---|---| | `Shift+J` | Join a channel | Only when no channel is joined | | `Shift+L` | Start/Stop listening | Only when a channel is joined | | `Shift+F` | Open filter popover | Only when a channel is joined | | `Shift+B` | Broadcast a message | Only when listening | | `Mod+Shift+C` | Copy selected message | Only when a message is selected | <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Realtime Inspector: new keyboard shortcuts (join channel, toggle listening, toggle filters, broadcast) and a copy-message shortcut with toast feedback. * Channel & Filter popovers support controlled/uncontrolled open state; header now wires popover state through props. * Shortcut tooltips added to copy and broadcast actions; realtime page navigation shortcuts and menu shortcuts added. * **Tests** * Shortcut reference sheet tests updated to include realtime navigation and inspector groups. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46001?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 --> --------- Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com>
48 lines
1.6 KiB
TypeScript
48 lines
1.6 KiB
TypeScript
import { useRouter } from 'next/router'
|
|
import type { PropsWithChildren } from 'react'
|
|
|
|
import { ProjectLayout } from '../ProjectLayout'
|
|
import { generateRealtimeMenu } from './RealtimeMenu.utils'
|
|
import { ProductMenu } from '@/components/ui/ProductMenu'
|
|
import { ProductMenuShortcuts } from '@/components/ui/ProductMenu/ProductMenuShortcuts'
|
|
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
|
import { withAuth } from '@/hooks/misc/withAuth'
|
|
|
|
/**
|
|
* Menu-only component for the Realtime section. Used by the desktop sidebar and by the
|
|
* mobile sheet submenu. Must not wrap ProjectLayout so that opening the realtime submenu
|
|
* in the mobile sheet does not overwrite registerOpenMenu and break the menu button.
|
|
*/
|
|
export const RealtimeProductMenu = () => {
|
|
const router = useRouter()
|
|
const { data: project } = useSelectedProjectQuery()
|
|
const page = router.pathname.split('/')[4]
|
|
|
|
return <ProductMenu page={page} menu={generateRealtimeMenu(project ?? undefined)} />
|
|
}
|
|
|
|
export interface RealtimeLayoutProps {
|
|
title: string
|
|
}
|
|
|
|
export const RealtimeLayout = ({ title, children }: PropsWithChildren<RealtimeLayoutProps>) => {
|
|
const { data: project } = useSelectedProjectQuery()
|
|
const router = useRouter()
|
|
const page = router.pathname.split('/')[4]
|
|
const menu = generateRealtimeMenu(project)
|
|
|
|
return (
|
|
<ProjectLayout
|
|
product="Realtime"
|
|
browserTitle={{ section: title }}
|
|
productMenu={<ProductMenu page={page} menu={menu} />}
|
|
isBlocking={false}
|
|
>
|
|
<ProductMenuShortcuts menu={menu} />
|
|
{children}
|
|
</ProjectLayout>
|
|
)
|
|
}
|
|
|
|
export default withAuth(RealtimeLayout)
|