mirror of
https://github.com/supabase/supabase.git
synced 2026-06-14 23:25:16 +08:00
Closes [FE-3245](https://linear.app/supabase/issue/FE-3245/add-keyboard-shortcuts-to-edge-functions-pages). Adds keyboard shortcuts across the Edge Functions surface, mirroring the patterns already in place for Database / Auth / Storage. ## Summary Three layers of new shortcuts, plus one quality-of-life fix on the existing search input: ### 1. Edge Functions list page (`/project/:ref/functions`) | Key | Action | |---|---| | `Shift+F` | Focus the search input | | `Shift+N` | Route to `/functions/new` (deploy a new function) | | `F` then `C` | Clear search filter | | `Shift+R` | Refresh the functions list (new toolbar button) | | `S` then `C` | Reset sort to `name:asc` | | `Esc` (in search) | Clears value, then blurs on a second press (`onSearchInputEscape`) | ### 2. Edge Functions section nav (active anywhere under `/functions/*`) | Key | Action | |---|---| | `F` then `O` | Functions overview | | `F` then `K` | Secrets | Wired through `EdgeFunctionsProductMenu` items via `shortcutId`, registered by `<ProductMenuShortcuts />` mounted in `EdgeFunctionsLayout`. ### 3. Per-function detail (active anywhere under `/functions/:slug/*`) | Key | Action | |---|---| | `1` | Overview | | `2` | Invocations | | `3` | Logs | | `4` | Code | | `5` | Settings | | `Shift+T` | Open the Test sheet | | `Shift+D` | Toggle the Download popover | | `Shift+C` | Copy the function URL (with toast) | ### 4. Test sheet (active when `EdgeFunctionTesterSheet` is open) | Key | Action | |---|---| | `Mod+Enter` | Send Request — first binding for this; mirrors `SQL_EDITOR_RUN` semantics | ### 5. New per-function Overview (`edgeFunctionsOverview` flag) | Key | Action | |---|---| | `I` then `M` | 15 min | | `I` then `H` | 1 hour | | `I` then `T` | 3 hours | | `I` then `D` | 1 day | | `Shift+R` | Refresh combined stats query | | `O` then `L` | Open Logs (or Invocations if unified-logs preview is off) | `ShortcutTooltip` added to the most prominent buttons (search, refresh, copy URL, download, test, send request). Interval/refresh/open-logs on the overview are registered without inline tooltips but remain discoverable via `Cmd+K` and the shortcut reference sheet (`Mod+/`). ## Implementation notes - New reference group `NAVIGATION_FUNCTION_DETAIL` ("Function Page Navigation") added to keep the reference sheet grouped sensibly. - Three new registry files: `functions-list.ts`, `functions-nav.ts`, `functions-detail.ts`, `functions-detail-nav.ts`, `functions-overview.ts`. - Three new hooks: `useFunctionsListShortcuts`, `useFunctionsDetailShortcuts`, `useEdgeFunctionOverviewShortcuts`. - `EdgeFunctionsLayout` refactored to share a single `useGenerateEdgeFunctionsMenu` hook between `<ProductMenu>` and `<ProductMenuShortcuts>` (matches the AuthLayout / DatabaseLayout pattern). - Download popover hoisted to controlled state so `Shift+D` can toggle it. ## Test plan ### Functions list page - [x] On `/project/:ref/functions`, press `Shift+F` — search input gains focus and value is selected - [x] Type in the search → press `Esc` → value clears (focus retained). Press `Esc` again → blurs - [x] Press `Shift+N` → routes to `/functions/new` - [x] With a non-default sort, press `S` then `C` → sort resets to `name:asc`. Confirm shortcut is disabled when already at default - [x] Press `Shift+R` → list refetches; loading indicator appears on the new Refresh button - [x] Press `F` then `C` → search clears ### Section nav (anywhere under `/functions/*`) - [x] From any page under `/functions/*`, press `F` then `O` → navigates to Functions list - [x] Press `F` then `K` → navigates to Secrets - [x] Verify the chord doesn't fire while typing in an input ### Per-function detail (any sub-page) - [x] On any function detail tab, press `1`/`2`/`3`/`4`/`5` → navigates to Overview / Invocations / Logs / Code / Settings respectively (digits 2 and 3 only on platform builds) - [x] Press `Shift+T` → Test sheet opens. Press escape to close - [x] Press `Shift+D` → Download popover opens; press escape to close - [x] Press `Shift+C` → URL copied + toast appears - [x] Hover the URL copy button, Download button, Test button — `ShortcutTooltip` shows the chord ### Test sheet - [x] Open the Test sheet (button or `Shift+T`) - [x] Without focusing anything, press `Mod+Enter` → request fires - [x] With focus inside the body editor / a header input, press `Mod+Enter` → request still fires (`Mod+`-keys bypass input guard) - [x] While `isPending`, `Mod+Enter` is a no-op (shortcut disabled) - [x] Hover Send Request → tooltip shows `Mod+Enter` ### New overview (with `edgeFunctionsOverview` flag enabled) - [x] Press `I` then `M` / `H` / `T` / `D` → interval segmented buttons highlight accordingly and chart re-fetches - [x] Press `Shift+R` → stats refetch - [x] Press `O` then `L` → routes to logs (or invocations when unified-logs preview is off) ### Regression checks - [x] `Cmd+/` opens the reference sheet and the new "Edge Functions Navigation" and "Function Page Navigation" groups render - [x] `Cmd+K` command palette includes the new shortcut entries under "Shortcuts" - [x] On the list page, the existing X button on the search still clears value - [x] Esc handler does not interfere with closing modals/popovers elsewhere on the page <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added comprehensive keyboard shortcuts for Edge Functions (navigation, tab switching, chart intervals, create/refresh, test/send request, download, copy URL) with visible shortcut hints on relevant buttons and inputs. * **Refactor** * Layouts and product menu updated to surface and wire these shortcuts across the UI. * **Tests** * Shortcut reference tests updated to include Edge Functions groups and entries. * **Documentation** * Shortcut reference sheet labels updated to include Edge Functions sections. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45947) <!-- 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>
76 lines
2.1 KiB
TypeScript
76 lines
2.1 KiB
TypeScript
import { useParams } from 'common'
|
|
import { useRouter } from 'next/router'
|
|
import { useMemo, type ComponentProps, type PropsWithChildren } from 'react'
|
|
|
|
import { ProjectLayout } from '../ProjectLayout'
|
|
import { ProductMenu } from '@/components/ui/ProductMenu'
|
|
import type { ProductMenuGroup } from '@/components/ui/ProductMenu/ProductMenu.types'
|
|
import { ProductMenuShortcuts } from '@/components/ui/ProductMenu/ProductMenuShortcuts'
|
|
import { withAuth } from '@/hooks/misc/withAuth'
|
|
import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
|
|
|
|
const useGenerateEdgeFunctionsMenu = (): ProductMenuGroup[] => {
|
|
const { ref: projectRef = 'default' } = useParams()
|
|
|
|
return useMemo(
|
|
() => [
|
|
{
|
|
title: 'Manage',
|
|
items: [
|
|
{
|
|
name: 'Functions',
|
|
key: 'main',
|
|
pages: ['', '[functionSlug]', 'new'],
|
|
url: `/project/${projectRef}/functions`,
|
|
items: [],
|
|
shortcutId: SHORTCUT_IDS.NAV_FUNCTIONS_OVERVIEW,
|
|
},
|
|
{
|
|
name: 'Secrets',
|
|
key: 'secrets',
|
|
url: `/project/${projectRef}/functions/secrets`,
|
|
items: [],
|
|
shortcutId: SHORTCUT_IDS.NAV_FUNCTIONS_SECRETS,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
[projectRef]
|
|
)
|
|
}
|
|
|
|
export const EdgeFunctionsProductMenu = () => {
|
|
const router = useRouter()
|
|
const page = router.pathname.split('/')[4]
|
|
const menu = useGenerateEdgeFunctionsMenu()
|
|
|
|
return <ProductMenu page={page} menu={menu} />
|
|
}
|
|
|
|
interface EdgeFunctionsLayoutProps {
|
|
title: string
|
|
browserTitle?: ComponentProps<typeof ProjectLayout>['browserTitle']
|
|
}
|
|
|
|
const EdgeFunctionsLayout = ({
|
|
children,
|
|
title,
|
|
browserTitle,
|
|
}: PropsWithChildren<EdgeFunctionsLayoutProps>) => {
|
|
const menu = useGenerateEdgeFunctionsMenu()
|
|
|
|
return (
|
|
<ProjectLayout
|
|
product="Edge Functions"
|
|
browserTitle={{ ...browserTitle, section: title }}
|
|
productMenu={<EdgeFunctionsProductMenu />}
|
|
isBlocking={false}
|
|
>
|
|
<ProductMenuShortcuts menu={menu} />
|
|
{children}
|
|
</ProjectLayout>
|
|
)
|
|
}
|
|
|
|
export default withAuth(EdgeFunctionsLayout)
|