Files
supabase/apps/studio/components/layouts/ProjectSettingsLayout/SettingsLayout.tsx
Danny White 498d051d88 feat(studio): add project settings shortcuts (#46352)
## What kind of change does this PR introduce?

Feature. Resolves FE-3417.

## What is the current behavior?

Project Settings has a top-level `G then ,` shortcut, but its
subnavigation and repeated key/log drain actions do not have scoped
keyboard shortcuts or visible shortcut tooltips.

| Area | Current behaviour |
| --- | --- |
| Project Settings sidebar | Routes are click-only once users are inside
Settings. |
| API/JWT keys | Creation buttons do not expose keyboard shortcuts. |
| Log Drains | Add/save destination actions do not expose keyboard
shortcuts. |

## What is the new behavior?

Adds scoped Project Settings navigation chords, shortcut tooltips on the
sidebar rows, and page/action shortcuts for API keys, JWT standby keys,
and Log Drains.

| Area | New shortcut coverage |
| --- | --- |
| Project Settings sidebar | `S then G/C/I/N/W/K/J/L/A/D` for eligible
in-section routes. |
| API Keys | `Shift+P` and `Shift+S` open the publishable/secret key
dialogs; `Mod+Enter` submits the open dialog. |
| JWT Keys | `Shift+N` opens Create standby key; `Mod+Enter` submits the
open dialog. |
| Log Drains | `Shift+N` adds a destination when the primary action is
available; `Mod+Enter` saves the open destination sheet. |


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added keyboard shortcuts for Project Settings navigation and for
actions in API Keys, JWT Keys, and Log Drains (open, create/submit).

* **Improvements**
* Dialogs and forms now support keyboard-triggered open and submit
actions with improved enable/disable gating and updated settings menu
composition; shortcuts appear in the shortcuts reference.

* **Tests**
* Added tests covering shortcut wiring and shortcut-driven open/submit
behaviors across dialogs and action panels.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46352?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: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Ali Waseem <waseema393@gmail.com>
2026-05-26 15:48:50 +00:00

50 lines
1.4 KiB
TypeScript

import { useRouter } from 'next/router'
import type { PropsWithChildren } from 'react'
import { ProjectLayout } from '../ProjectLayout'
import { useGenerateSettingsMenu } from './SettingsMenu.utils'
import { ProductMenu } from '@/components/ui/ProductMenu'
import { ProductMenuShortcuts } from '@/components/ui/ProductMenu/ProductMenuShortcuts'
import { withAuth } from '@/hooks/misc/withAuth'
/**
* Menu-only component for the settings section. Used by the desktop sidebar and by the
* mobile sheet submenu. Must not wrap ProjectLayout so that opening the settings submenu
* in the mobile sheet does not overwrite registerOpenMenu and break the menu button.
*/
export const SettingsProductMenu = () => {
const router = useRouter()
const page = router.pathname.includes('billing')
? router.pathname.split('/')[5]
: router.pathname.split('/')[4]
const menu = useGenerateSettingsMenu()
return (
<>
<ProductMenuShortcuts menu={menu} />
<ProductMenu page={page} menu={menu} />
</>
)
}
interface SettingsLayoutProps {
title: string
}
export const SettingsLayout = ({ title, children }: PropsWithChildren<SettingsLayoutProps>) => {
return (
<ProjectLayout
isBlocking={false}
product="Settings"
browserTitle={{ section: title }}
productMenu={<SettingsProductMenu />}
>
{children}
</ProjectLayout>
)
}
export default withAuth(SettingsLayout)