fix(studio): add a keyboard shortcut for the Compute sidebar item (#50361)

The Compute entry in the project sidebar was the only product route
without a `shortcutId`, so it had neither a `G`-chord nor the hover
keybind tooltip every sibling gets. Bound it to `G` then `C` (previously
unused) and added a test asserting every product route carries a
shortcut.

Fixes FE-4389

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

## Summary by CodeRabbit

- **New Features**
- Added a keyboard shortcut for quick navigation to Compute: press
**G**, then **C**.
- Compute navigation now includes a discoverable shortcut for consistent
access from the navigation interface.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Ali Waseem authored and GitHub committed 2026-09-14 19:44:40 +00:00
1 parent bd95407a9c
commit 2cd9b42e80
3 files changed
+15

No files matched your search

@@ -90,6 +90,11 @@ describe('generateProductRoutes', () => {
expect(keys(generateProductRoutes(REF, activeProject, { compute: true }))).toContain('compute') expect(keys(generateProductRoutes(REF, activeProject, { compute: true }))).toContain('compute')
}) })
it('gives every product route a navigation shortcut', () => {
const routes = generateProductRoutes(REF, activeProject, { compute: true })
expect(routes.filter((r) => !r.shortcutId)).toEqual([])
})
it('excludes auth when auth feature is disabled', () => { it('excludes auth when auth feature is disabled', () => {
const routes = generateProductRoutes(REF, activeProject, { auth: false }) const routes = generateProductRoutes(REF, activeProject, { auth: false })
expect(keys(routes)).not.toContain('auth') expect(keys(routes)).not.toContain('auth')
@@ -178,6 +178,7 @@ export const generateProductRoutes = (
icon: <Compute size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />, icon: <Compute size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/compute`), link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/compute`),
isNew: true, isNew: true,
shortcutId: SHORTCUT_IDS.NAV_COMPUTE,
}, },
] ]
: []), : []),
+9
View File
@@ -59,6 +59,7 @@ import { STORAGE_NAV_SHORTCUT_IDS, storageNavRegistry } from './registry/storage
import { TABLE_EDITOR_SHORTCUT_IDS, tableEditorRegistry } from './registry/table-editor' import { TABLE_EDITOR_SHORTCUT_IDS, tableEditorRegistry } from './registry/table-editor'
import { UNIFIED_LOGS_SHORTCUT_IDS, unifiedLogsRegistry } from './registry/unified-logs' import { UNIFIED_LOGS_SHORTCUT_IDS, unifiedLogsRegistry } from './registry/unified-logs'
import { ShortcutDefinition } from './types' import { ShortcutDefinition } from './types'
import { PRODUCT_NAME } from '@/lib/constants/compute'
/** /**
* The canonical list of shortcut IDs. Add new shortcuts here first, then * The canonical list of shortcut IDs. Add new shortcuts here first, then
@@ -96,6 +97,7 @@ export const SHORTCUT_IDS = {
NAV_AUTH: 'nav.auth', NAV_AUTH: 'nav.auth',
NAV_STORAGE: 'nav.storage', NAV_STORAGE: 'nav.storage',
NAV_FUNCTIONS: 'nav.functions', NAV_FUNCTIONS: 'nav.functions',
NAV_COMPUTE: 'nav.compute',
NAV_REALTIME: 'nav.realtime', NAV_REALTIME: 'nav.realtime',
NAV_ADVISORS: 'nav.advisors', NAV_ADVISORS: 'nav.advisors',
NAV_OBSERVABILITY: 'nav.observability', NAV_OBSERVABILITY: 'nav.observability',
@@ -391,6 +393,13 @@ export const SHORTCUT_DEFINITIONS: Record<ShortcutId, ShortcutDefinition> = {
showInSettings: false, showInSettings: false,
referenceGroup: SHORTCUT_REFERENCE_GROUPS.NAVIGATION_GLOBAL, referenceGroup: SHORTCUT_REFERENCE_GROUPS.NAVIGATION_GLOBAL,
}, },
[SHORTCUT_IDS.NAV_COMPUTE]: {
id: SHORTCUT_IDS.NAV_COMPUTE,
label: `Go to ${PRODUCT_NAME}`,
sequence: ['G', 'C'],
showInSettings: false,
referenceGroup: SHORTCUT_REFERENCE_GROUPS.NAVIGATION_GLOBAL,
},
[SHORTCUT_IDS.NAV_REALTIME]: { [SHORTCUT_IDS.NAV_REALTIME]: {
id: SHORTCUT_IDS.NAV_REALTIME, id: SHORTCUT_IDS.NAV_REALTIME,
label: 'Go to Realtime', label: 'Go to Realtime',