mirror of
https://github.com/supabase/supabase.git
synced 2026-05-06 14:05:05 +08:00
feat(studio): add D + letter shortcuts for Database sub-pages (#45546)
## Summary Adds a contextual `D + <letter>` chord pattern for jumping between Database sub-pages, mounted only while `DatabaseLayout` is active. Establishes the pattern we can repeat for other sections (Auth, Storage, Functions, etc.). Linear: [FE-3140](https://linear.app/supabase/issue/FE-3140/define-subnavigation-pattern-for-database-management-page) ## Pattern - Chords are 2-key sequences (`D`, `<letter>`) — no global leader, no `G` prefix. - Registration is contextual: `<DatabaseNavShortcuts />` lives inside `DatabaseLayout`, so the leading `D` is only "owned" while the user is under `/project/<ref>/database/*`. Doesn't burn a global key. - Hover tooltips on each sub-menu item show the chord, anchored to the label text (Linear-style). Powered by `<ShortcutTooltip>` already used in the main nav. - Items hidden by feature flags (Roles, Column Privileges, Replication) auto-disable the chord — no muscle-memory navigating to a 404. ## Shortcuts added | Sub-page | Chord | Notes | |---|---|---| | Tables | `D T` | | | Functions | `D F` | | | Triggers | `D R` | t**R**iggers — `T` taken by Tables | | Indexes | `D I` | | | Extensions | `D X` | e**X**tensions | | Schema Visualizer | `D V` | | | Enumerated Types | `D E` | | | Publications | `D U` | p**U**blications — avoids collision with Schema Visualizer's `D P` (Download as PNG) | | Column Privileges | `D C` | flag-gated | | Settings | `D ,` | mirrors global `G ,` for project settings — avoids collision with Schema Visualizer's `D S` (Download as SVG) | | Replication | `D L` | rep**L**ication — flag-gated | | Roles | `D O` | r**O**les — flag-gated | | Backups | `D B` | platform-only | | Migrations | `D M` | | External-link sub-menu items (Policies, Wrappers, Webhooks, Security Advisor, Performance Advisor, Query Performance) are intentionally not chorded — they route out of `/database/*` and don't belong to the section's namespace. ## Collision audit Other shortcuts active on database pages (table-list, schema-visualizer) were checked against the new chords: - **Schema Visualizer** (`/database/schemas`): `D P` (Download PNG), `D S` (Download SVG), `O A`, `O S`. Publications and Settings were remapped to `D U` and `D ,` to avoid the `D P` / `D S` clashes. - **List pages** (`/database/tables`, etc.): `Shift+F`, `Shift+N`, `O S`, `F C` — no overlap with `D + <letter>`. ## Files - `state/shortcuts/registry/database-nav.ts` — new registry module with the 14 chord definitions. - `state/shortcuts/registry.ts` — spreads the new IDs/definitions into the canonical registry. - `components/interfaces/DatabaseNavShortcuts.tsx` — null-rendering hook component that wires `useShortcut` for each chord, keyed off `useGenerateDatabaseMenu` so URLs and feature gating stay in sync with the sidebar. - `components/layouts/DatabaseLayout/DatabaseLayout.tsx` — mounts the component. - `components/layouts/DatabaseLayout/DatabaseMenu.utils.tsx` — tags each menu item with its `shortcutId`. - `components/ui/ProductMenu/ProductMenu.types.ts` — adds optional `shortcutId?: ShortcutId` field. - `components/ui/ProductMenu/ProductMenuItem.tsx` — renders the hover tooltip when an item has a `shortcutId`, anchored to the label span. ## Test plan - [ ] On `/project/<ref>/database/tables`, press `D F` — navigates to `/database/functions`. - [ ] On `/project/<ref>/database/schemas`, press `D P` — downloads the PNG (Schema Visualizer wins, no nav conflict). - [ ] On `/project/<ref>/database/schemas`, press `D U` — navigates to `/database/publications`. - [ ] On `/project/<ref>/database/tables`, press `D ,` — navigates to `/database/settings`. - [ ] Hover any sub-menu item with a chord — pill appears next to the label after ~1s. - [ ] On a project with the Replication flag off — `D L` does nothing. - [ ] Navigate to `/auth` — pressing `D F` does nothing (chord unmounts with the layout). - [ ] Type `D` then `F` slowly inside an input — does not navigate (input-focus guard).
This commit is contained in:
96
apps/studio/components/interfaces/DatabaseNavShortcuts.tsx
Normal file
96
apps/studio/components/interfaces/DatabaseNavShortcuts.tsx
Normal file
@@ -0,0 +1,96 @@
|
||||
import { useRouter } from 'next/router'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
|
||||
import { useGenerateDatabaseMenu } from '@/components/layouts/DatabaseLayout/DatabaseMenu.utils'
|
||||
import { SHORTCUT_IDS, type ShortcutId } from '@/state/shortcuts/registry'
|
||||
import { useShortcut } from '@/state/shortcuts/useShortcut'
|
||||
|
||||
export const DatabaseNavShortcuts = () => {
|
||||
const router = useRouter()
|
||||
const groups = useGenerateDatabaseMenu()
|
||||
|
||||
const urlByShortcut = useMemo(() => {
|
||||
const map = new Map<ShortcutId, string>()
|
||||
for (const group of groups) {
|
||||
for (const item of group.items) {
|
||||
if (item.shortcutId && item.url) map.set(item.shortcutId, item.url)
|
||||
}
|
||||
}
|
||||
return map
|
||||
}, [groups])
|
||||
|
||||
const navigate = useCallback(
|
||||
(id: ShortcutId) => {
|
||||
const url = urlByShortcut.get(id)
|
||||
if (url) router.push(url)
|
||||
},
|
||||
[router, urlByShortcut]
|
||||
)
|
||||
|
||||
useShortcut(SHORTCUT_IDS.NAV_DATABASE_TABLES, () => navigate(SHORTCUT_IDS.NAV_DATABASE_TABLES), {
|
||||
enabled: urlByShortcut.has(SHORTCUT_IDS.NAV_DATABASE_TABLES),
|
||||
})
|
||||
useShortcut(
|
||||
SHORTCUT_IDS.NAV_DATABASE_FUNCTIONS,
|
||||
() => navigate(SHORTCUT_IDS.NAV_DATABASE_FUNCTIONS),
|
||||
{ enabled: urlByShortcut.has(SHORTCUT_IDS.NAV_DATABASE_FUNCTIONS) }
|
||||
)
|
||||
useShortcut(
|
||||
SHORTCUT_IDS.NAV_DATABASE_TRIGGERS,
|
||||
() => navigate(SHORTCUT_IDS.NAV_DATABASE_TRIGGERS),
|
||||
{ enabled: urlByShortcut.has(SHORTCUT_IDS.NAV_DATABASE_TRIGGERS) }
|
||||
)
|
||||
useShortcut(
|
||||
SHORTCUT_IDS.NAV_DATABASE_INDEXES,
|
||||
() => navigate(SHORTCUT_IDS.NAV_DATABASE_INDEXES),
|
||||
{ enabled: urlByShortcut.has(SHORTCUT_IDS.NAV_DATABASE_INDEXES) }
|
||||
)
|
||||
useShortcut(
|
||||
SHORTCUT_IDS.NAV_DATABASE_EXTENSIONS,
|
||||
() => navigate(SHORTCUT_IDS.NAV_DATABASE_EXTENSIONS),
|
||||
{ enabled: urlByShortcut.has(SHORTCUT_IDS.NAV_DATABASE_EXTENSIONS) }
|
||||
)
|
||||
useShortcut(
|
||||
SHORTCUT_IDS.NAV_DATABASE_SCHEMA_VISUALIZER,
|
||||
() => navigate(SHORTCUT_IDS.NAV_DATABASE_SCHEMA_VISUALIZER),
|
||||
{ enabled: urlByShortcut.has(SHORTCUT_IDS.NAV_DATABASE_SCHEMA_VISUALIZER) }
|
||||
)
|
||||
useShortcut(SHORTCUT_IDS.NAV_DATABASE_ROLES, () => navigate(SHORTCUT_IDS.NAV_DATABASE_ROLES), {
|
||||
enabled: urlByShortcut.has(SHORTCUT_IDS.NAV_DATABASE_ROLES),
|
||||
})
|
||||
useShortcut(
|
||||
SHORTCUT_IDS.NAV_DATABASE_BACKUPS,
|
||||
() => navigate(SHORTCUT_IDS.NAV_DATABASE_BACKUPS),
|
||||
{ enabled: urlByShortcut.has(SHORTCUT_IDS.NAV_DATABASE_BACKUPS) }
|
||||
)
|
||||
useShortcut(
|
||||
SHORTCUT_IDS.NAV_DATABASE_MIGRATIONS,
|
||||
() => navigate(SHORTCUT_IDS.NAV_DATABASE_MIGRATIONS),
|
||||
{ enabled: urlByShortcut.has(SHORTCUT_IDS.NAV_DATABASE_MIGRATIONS) }
|
||||
)
|
||||
useShortcut(SHORTCUT_IDS.NAV_DATABASE_TYPES, () => navigate(SHORTCUT_IDS.NAV_DATABASE_TYPES), {
|
||||
enabled: urlByShortcut.has(SHORTCUT_IDS.NAV_DATABASE_TYPES),
|
||||
})
|
||||
useShortcut(
|
||||
SHORTCUT_IDS.NAV_DATABASE_PUBLICATIONS,
|
||||
() => navigate(SHORTCUT_IDS.NAV_DATABASE_PUBLICATIONS),
|
||||
{ enabled: urlByShortcut.has(SHORTCUT_IDS.NAV_DATABASE_PUBLICATIONS) }
|
||||
)
|
||||
useShortcut(
|
||||
SHORTCUT_IDS.NAV_DATABASE_COLUMN_PRIVILEGES,
|
||||
() => navigate(SHORTCUT_IDS.NAV_DATABASE_COLUMN_PRIVILEGES),
|
||||
{ enabled: urlByShortcut.has(SHORTCUT_IDS.NAV_DATABASE_COLUMN_PRIVILEGES) }
|
||||
)
|
||||
useShortcut(
|
||||
SHORTCUT_IDS.NAV_DATABASE_SETTINGS,
|
||||
() => navigate(SHORTCUT_IDS.NAV_DATABASE_SETTINGS),
|
||||
{ enabled: urlByShortcut.has(SHORTCUT_IDS.NAV_DATABASE_SETTINGS) }
|
||||
)
|
||||
useShortcut(
|
||||
SHORTCUT_IDS.NAV_DATABASE_REPLICATION,
|
||||
() => navigate(SHORTCUT_IDS.NAV_DATABASE_REPLICATION),
|
||||
{ enabled: urlByShortcut.has(SHORTCUT_IDS.NAV_DATABASE_REPLICATION) }
|
||||
)
|
||||
|
||||
return null
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import type { PropsWithChildren } from 'react'
|
||||
|
||||
import { ProjectLayout } from '../ProjectLayout'
|
||||
import { useGenerateDatabaseMenu } from './DatabaseMenu.utils'
|
||||
import { DatabaseNavShortcuts } from '@/components/interfaces/DatabaseNavShortcuts'
|
||||
import { ProductMenu } from '@/components/ui/ProductMenu'
|
||||
import { withAuth } from '@/hooks/misc/withAuth'
|
||||
|
||||
@@ -26,6 +27,7 @@ const DatabaseLayout = ({ children, title }: PropsWithChildren<DatabaseLayoutPro
|
||||
productMenu={<DatabaseProductMenu />}
|
||||
isBlocking={false}
|
||||
>
|
||||
<DatabaseNavShortcuts />
|
||||
{children}
|
||||
</ProjectLayout>
|
||||
)
|
||||
|
||||
@@ -12,6 +12,7 @@ import { useProjectAddonsQuery } from '@/data/subscriptions/project-addons-query
|
||||
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { IS_PLATFORM } from '@/lib/constants'
|
||||
import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
|
||||
|
||||
const ExternalLinkIcon = <ArrowUpRight strokeWidth={1} className="h-4 w-4" />
|
||||
|
||||
@@ -42,24 +43,70 @@ export const useGenerateDatabaseMenu = (): ProductMenuGroup[] => {
|
||||
{
|
||||
title: 'Database Management',
|
||||
items: [
|
||||
{ name: 'Schema Visualizer', key: 'schemas', url: getDatabaseURL('schemas') },
|
||||
{ name: 'Tables', key: 'tables', url: getDatabaseURL('tables') },
|
||||
{ name: 'Functions', key: 'functions', url: getDatabaseURL('functions') },
|
||||
{ name: 'Triggers', key: 'triggers', url: getDatabaseURL('triggers/data') },
|
||||
{ name: 'Enumerated Types', key: 'types', url: getDatabaseURL('types') },
|
||||
{ name: 'Extensions', key: 'extensions', url: getDatabaseURL('extensions') },
|
||||
{ name: 'Indexes', key: 'indexes', url: getDatabaseURL('indexes') },
|
||||
{ name: 'Publications', key: 'publications', url: getDatabaseURL('publications') },
|
||||
{
|
||||
name: 'Schema Visualizer',
|
||||
key: 'schemas',
|
||||
url: getDatabaseURL('schemas'),
|
||||
shortcutId: SHORTCUT_IDS.NAV_DATABASE_SCHEMA_VISUALIZER,
|
||||
},
|
||||
{
|
||||
name: 'Tables',
|
||||
key: 'tables',
|
||||
url: getDatabaseURL('tables'),
|
||||
shortcutId: SHORTCUT_IDS.NAV_DATABASE_TABLES,
|
||||
},
|
||||
{
|
||||
name: 'Functions',
|
||||
key: 'functions',
|
||||
url: getDatabaseURL('functions'),
|
||||
shortcutId: SHORTCUT_IDS.NAV_DATABASE_FUNCTIONS,
|
||||
},
|
||||
{
|
||||
name: 'Triggers',
|
||||
key: 'triggers',
|
||||
url: getDatabaseURL('triggers/data'),
|
||||
shortcutId: SHORTCUT_IDS.NAV_DATABASE_TRIGGERS,
|
||||
},
|
||||
{
|
||||
name: 'Enumerated Types',
|
||||
key: 'types',
|
||||
url: getDatabaseURL('types'),
|
||||
shortcutId: SHORTCUT_IDS.NAV_DATABASE_TYPES,
|
||||
},
|
||||
{
|
||||
name: 'Extensions',
|
||||
key: 'extensions',
|
||||
url: getDatabaseURL('extensions'),
|
||||
shortcutId: SHORTCUT_IDS.NAV_DATABASE_EXTENSIONS,
|
||||
},
|
||||
{
|
||||
name: 'Indexes',
|
||||
key: 'indexes',
|
||||
url: getDatabaseURL('indexes'),
|
||||
shortcutId: SHORTCUT_IDS.NAV_DATABASE_INDEXES,
|
||||
},
|
||||
{
|
||||
name: 'Publications',
|
||||
key: 'publications',
|
||||
url: getDatabaseURL('publications'),
|
||||
shortcutId: SHORTCUT_IDS.NAV_DATABASE_PUBLICATIONS,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Configuration',
|
||||
items: [
|
||||
showRoles && { name: 'Roles', key: 'roles', url: getDatabaseURL('roles') },
|
||||
showRoles && {
|
||||
name: 'Roles',
|
||||
key: 'roles',
|
||||
url: getDatabaseURL('roles'),
|
||||
shortcutId: SHORTCUT_IDS.NAV_DATABASE_ROLES,
|
||||
},
|
||||
columnLevelPrivileges && {
|
||||
name: 'Column Privileges',
|
||||
key: 'column-privileges',
|
||||
url: getDatabaseURL('column-privileges'),
|
||||
shortcutId: SHORTCUT_IDS.NAV_DATABASE_COLUMN_PRIVILEGES,
|
||||
},
|
||||
{
|
||||
name: 'Policies',
|
||||
@@ -67,7 +114,12 @@ export const useGenerateDatabaseMenu = (): ProductMenuGroup[] => {
|
||||
url: `/project/${ref}/auth/policies`,
|
||||
rightIcon: ExternalLinkIcon,
|
||||
},
|
||||
{ name: 'Settings', key: 'settings', url: getDatabaseURL('settings') },
|
||||
{
|
||||
name: 'Settings',
|
||||
key: 'settings',
|
||||
url: getDatabaseURL('settings'),
|
||||
shortcutId: SHORTCUT_IDS.NAV_DATABASE_SETTINGS,
|
||||
},
|
||||
].filter(Boolean) as ProductMenuGroupItem[],
|
||||
},
|
||||
{
|
||||
@@ -79,13 +131,20 @@ export const useGenerateDatabaseMenu = (): ProductMenuGroup[] => {
|
||||
key: 'replication',
|
||||
url: getDatabaseURL('replication'),
|
||||
label: enablePgReplicate ? 'New' : undefined,
|
||||
shortcutId: SHORTCUT_IDS.NAV_DATABASE_REPLICATION,
|
||||
},
|
||||
IS_PLATFORM && {
|
||||
name: 'Backups',
|
||||
key: 'backups',
|
||||
url: pitrEnabled ? getDatabaseURL('backups/pitr') : getDatabaseURL('backups/scheduled'),
|
||||
shortcutId: SHORTCUT_IDS.NAV_DATABASE_BACKUPS,
|
||||
},
|
||||
{
|
||||
name: 'Migrations',
|
||||
key: 'migrations',
|
||||
url: getDatabaseURL('migrations'),
|
||||
shortcutId: SHORTCUT_IDS.NAV_DATABASE_MIGRATIONS,
|
||||
},
|
||||
{ name: 'Migrations', key: 'migrations', url: getDatabaseURL('migrations') },
|
||||
showWrappers && {
|
||||
name: 'Wrappers',
|
||||
key: 'wrappers',
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
import type { ShortcutId } from '@/state/shortcuts/registry'
|
||||
|
||||
export interface ProductMenuGroup {
|
||||
title?: string
|
||||
/** Set to "main" if page is on a '/' route */
|
||||
@@ -25,6 +27,7 @@ export interface ProductMenuGroupItem {
|
||||
childIcon?: ReactNode
|
||||
childItems?: ProductMenuGroupItem[]
|
||||
pages?: string[]
|
||||
shortcutId?: ShortcutId
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,7 @@ import Link from 'next/link'
|
||||
import { Badge, Button, Menu } from 'ui'
|
||||
|
||||
import { ProductMenuGroupItem } from './ProductMenu.types'
|
||||
import { ShortcutTooltip } from '@/components/ui/ShortcutTooltip'
|
||||
|
||||
interface ProductMenuItemProps {
|
||||
item: ProductMenuGroupItem
|
||||
@@ -18,16 +19,26 @@ export const ProductMenuItem = ({
|
||||
hoverText = '',
|
||||
onClick,
|
||||
}: ProductMenuItemProps) => {
|
||||
const { name = '', url = '', icon, rightIcon, isExternal, label, disabled } = item
|
||||
const { name = '', url = '', icon, rightIcon, isExternal, label, disabled, shortcutId } = item
|
||||
|
||||
const labelNode = shortcutId ? (
|
||||
<ShortcutTooltip shortcutId={shortcutId} side="right" delayDuration={1000}>
|
||||
<span className="truncate min-w-0">{name}</span>
|
||||
</ShortcutTooltip>
|
||||
) : (
|
||||
<span className="truncate flex-1 min-w-0">{name}</span>
|
||||
)
|
||||
|
||||
const menuItem = (
|
||||
<Menu.Item icon={icon} active={isActive} onClick={onClick}>
|
||||
<div className="flex w-full items-center justify-between gap-1">
|
||||
<div
|
||||
className="flex items-center gap-1 min-w-0 flex-1"
|
||||
title={hoverText ? hoverText : typeof name === 'string' ? name : ''}
|
||||
title={
|
||||
shortcutId ? undefined : hoverText ? hoverText : typeof name === 'string' ? name : ''
|
||||
}
|
||||
>
|
||||
<span className="truncate flex-1 min-w-0">{name}</span>
|
||||
{labelNode}
|
||||
{label !== undefined && (
|
||||
<Badge
|
||||
className="shrink-0"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DATABASE_NAV_SHORTCUT_IDS, databaseNavRegistry } from './registry/database-nav'
|
||||
import { LIST_PAGE_SHORTCUT_IDS, listPageRegistry } from './registry/list-page'
|
||||
import {
|
||||
SCHEMA_VISUALIZER_SHORTCUT_IDS,
|
||||
@@ -64,6 +65,9 @@ export const SHORTCUT_IDS = {
|
||||
|
||||
// Shared list-page shortcuts (database/* listing pages, etc.)
|
||||
...LIST_PAGE_SHORTCUT_IDS,
|
||||
|
||||
// Database sub-page navigation chords
|
||||
...DATABASE_NAV_SHORTCUT_IDS,
|
||||
} as const
|
||||
|
||||
/**
|
||||
@@ -321,4 +325,7 @@ export const SHORTCUT_DEFINITIONS: Record<ShortcutId, ShortcutDefinition> = {
|
||||
|
||||
// Shared list-page shortcut registration
|
||||
...listPageRegistry,
|
||||
|
||||
// Database sub-page navigation chord registration
|
||||
...databaseNavRegistry,
|
||||
}
|
||||
|
||||
117
apps/studio/state/shortcuts/registry/database-nav.ts
Normal file
117
apps/studio/state/shortcuts/registry/database-nav.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import { RegistryDefinations } from '../types'
|
||||
|
||||
/**
|
||||
* Contextual chords for jumping between Database sub-pages — `D + <letter>`.
|
||||
*
|
||||
* Active only while DatabaseLayout is mounted (i.e. the user is somewhere
|
||||
* under `/project/<ref>/database/*`). The chord intentionally lives on the
|
||||
* page rather than globally so the leading `D` doesn't burn a global key for
|
||||
* a destination most users only care about while already in the section.
|
||||
*
|
||||
*/
|
||||
export const DATABASE_NAV_SHORTCUT_IDS = {
|
||||
NAV_DATABASE_TABLES: 'nav.database-tables',
|
||||
NAV_DATABASE_FUNCTIONS: 'nav.database-functions',
|
||||
NAV_DATABASE_TRIGGERS: 'nav.database-triggers',
|
||||
NAV_DATABASE_INDEXES: 'nav.database-indexes',
|
||||
NAV_DATABASE_EXTENSIONS: 'nav.database-extensions',
|
||||
NAV_DATABASE_SCHEMA_VISUALIZER: 'nav.database-schema-visualizer',
|
||||
NAV_DATABASE_ROLES: 'nav.database-roles',
|
||||
NAV_DATABASE_BACKUPS: 'nav.database-backups',
|
||||
NAV_DATABASE_MIGRATIONS: 'nav.database-migrations',
|
||||
NAV_DATABASE_TYPES: 'nav.database-types',
|
||||
NAV_DATABASE_PUBLICATIONS: 'nav.database-publications',
|
||||
NAV_DATABASE_COLUMN_PRIVILEGES: 'nav.database-column-privileges',
|
||||
NAV_DATABASE_SETTINGS: 'nav.database-settings',
|
||||
NAV_DATABASE_REPLICATION: 'nav.database-replication',
|
||||
}
|
||||
|
||||
export type DatabaseNavShortcutId =
|
||||
(typeof DATABASE_NAV_SHORTCUT_IDS)[keyof typeof DATABASE_NAV_SHORTCUT_IDS]
|
||||
|
||||
export const databaseNavRegistry: RegistryDefinations<DatabaseNavShortcutId> = {
|
||||
[DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_TABLES]: {
|
||||
id: DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_TABLES,
|
||||
label: 'Go to Tables',
|
||||
sequence: ['D', 'T'],
|
||||
showInSettings: false,
|
||||
},
|
||||
[DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_FUNCTIONS]: {
|
||||
id: DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_FUNCTIONS,
|
||||
label: 'Go to Functions',
|
||||
sequence: ['D', 'F'],
|
||||
showInSettings: false,
|
||||
},
|
||||
[DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_TRIGGERS]: {
|
||||
id: DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_TRIGGERS,
|
||||
label: 'Go to Triggers',
|
||||
sequence: ['D', 'R'],
|
||||
showInSettings: false,
|
||||
},
|
||||
[DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_INDEXES]: {
|
||||
id: DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_INDEXES,
|
||||
label: 'Go to Indexes',
|
||||
sequence: ['D', 'I'],
|
||||
showInSettings: false,
|
||||
},
|
||||
[DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_EXTENSIONS]: {
|
||||
id: DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_EXTENSIONS,
|
||||
label: 'Go to Extensions',
|
||||
sequence: ['D', 'X'],
|
||||
showInSettings: false,
|
||||
},
|
||||
[DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_SCHEMA_VISUALIZER]: {
|
||||
id: DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_SCHEMA_VISUALIZER,
|
||||
label: 'Go to Schema Visualizer',
|
||||
sequence: ['D', 'V'],
|
||||
showInSettings: false,
|
||||
},
|
||||
[DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_ROLES]: {
|
||||
id: DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_ROLES,
|
||||
label: 'Go to Roles',
|
||||
sequence: ['D', 'O'],
|
||||
showInSettings: false,
|
||||
},
|
||||
[DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_BACKUPS]: {
|
||||
id: DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_BACKUPS,
|
||||
label: 'Go to Backups',
|
||||
sequence: ['D', 'B'],
|
||||
showInSettings: false,
|
||||
},
|
||||
[DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_MIGRATIONS]: {
|
||||
id: DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_MIGRATIONS,
|
||||
label: 'Go to Migrations',
|
||||
sequence: ['D', 'M'],
|
||||
showInSettings: false,
|
||||
},
|
||||
[DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_TYPES]: {
|
||||
id: DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_TYPES,
|
||||
label: 'Go to Enumerated Types',
|
||||
sequence: ['D', 'E'],
|
||||
showInSettings: false,
|
||||
},
|
||||
[DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_PUBLICATIONS]: {
|
||||
id: DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_PUBLICATIONS,
|
||||
label: 'Go to Publications',
|
||||
sequence: ['D', 'U'],
|
||||
showInSettings: false,
|
||||
},
|
||||
[DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_COLUMN_PRIVILEGES]: {
|
||||
id: DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_COLUMN_PRIVILEGES,
|
||||
label: 'Go to Column Privileges',
|
||||
sequence: ['D', 'C'],
|
||||
showInSettings: false,
|
||||
},
|
||||
[DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_SETTINGS]: {
|
||||
id: DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_SETTINGS,
|
||||
label: 'Go to Database Settings',
|
||||
sequence: ['D', ','],
|
||||
showInSettings: false,
|
||||
},
|
||||
[DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_REPLICATION]: {
|
||||
id: DATABASE_NAV_SHORTCUT_IDS.NAV_DATABASE_REPLICATION,
|
||||
label: 'Go to Replication',
|
||||
sequence: ['D', 'L'],
|
||||
showInSettings: false,
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user