mirror of
https://github.com/supabase/supabase.git
synced 2026-10-10 03:45:06 +03:00
Merge pull request #17257 from supabase/chore/improve-command-k-menu
Minor improvements to command k menu
This commit is contained in:
5 files changed
+45
-16
No files matched your search
@@ -1,7 +1,7 @@
|
||||
import { CommandGroup } from 'cmdk-supabase'
|
||||
import { useCommandMenu } from './CommandMenuProvider'
|
||||
import { Badge } from '../Badge'
|
||||
import { CommandItem } from './Command.utils'
|
||||
import { CommandItem, copyToClipboard } from './Command.utils'
|
||||
import { IconAlertCircle } from './../Icon/icons/IconAlertCircle'
|
||||
import ChildItem from './ChildItem'
|
||||
|
||||
@@ -9,15 +9,6 @@ const APIKeys = ({ isSubItem = false }) => {
|
||||
const { setIsOpen, project } = useCommandMenu()
|
||||
const { apiKeys } = project ?? {}
|
||||
|
||||
const copyToClipboard = (str: string, callback = () => {}) => {
|
||||
const focused = window.document.hasFocus()
|
||||
if (focused) {
|
||||
window.navigator?.clipboard?.writeText(str).then(callback)
|
||||
} else {
|
||||
console.warn('Unable to copy to clipboard')
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<CommandGroup>
|
||||
{apiKeys?.anon !== undefined && (
|
||||
|
||||
@@ -12,6 +12,15 @@ import { LoadingLine } from '../LoadingLine/LoadingLine'
|
||||
type CommandPrimitiveElement = React.ElementRef<typeof CommandPrimitive>
|
||||
type CommandPrimitiveProps = React.ComponentPropsWithoutRef<typeof CommandPrimitive>
|
||||
|
||||
export const copyToClipboard = (str: string, callback = () => {}) => {
|
||||
const focused = window.document.hasFocus()
|
||||
if (focused) {
|
||||
window.navigator?.clipboard?.writeText(str).then(callback)
|
||||
} else {
|
||||
console.warn('Unable to copy to clipboard')
|
||||
}
|
||||
}
|
||||
|
||||
export const Command = React.forwardRef<CommandPrimitiveElement, CommandPrimitiveProps>(
|
||||
({ className, ...props }, ref) => (
|
||||
<CommandPrimitive
|
||||
|
||||
@@ -12,6 +12,7 @@ import { IconMonitor } from './../Icon/icons/IconMonitor'
|
||||
import { IconPhone } from './../Icon/icons/IconPhone'
|
||||
import { IconUser } from './../Icon/icons/IconUser'
|
||||
import { IconKey } from './../Icon/icons/IconKey'
|
||||
import { IconLink } from './../Icon/icons/IconLink'
|
||||
|
||||
import AiCommand from './AiCommand'
|
||||
import sharedItems from './utils/shared-nav-items.json'
|
||||
@@ -23,6 +24,7 @@ import {
|
||||
CommandItem,
|
||||
CommandLabel,
|
||||
CommandList,
|
||||
copyToClipboard,
|
||||
} from './Command.utils'
|
||||
import { COMMAND_ROUTES } from './Command.constants'
|
||||
import { useCommandMenu } from './CommandMenuProvider'
|
||||
@@ -35,6 +37,7 @@ import SearchableStudioItems from './SearchableStudioItems'
|
||||
import CommandMenuShortcuts from './CommandMenuShortcuts'
|
||||
import { BadgeExperimental } from './Command.Badges'
|
||||
import { AiIconAnimation } from '@ui/layout/ai-icon-animation'
|
||||
import ChildItem from './ChildItem'
|
||||
|
||||
export const CHAT_ROUTES = [
|
||||
COMMAND_ROUTES.AI, // this one is temporary
|
||||
@@ -63,7 +66,7 @@ const CommandMenu = ({ projectRef }: CommandMenuProps) => {
|
||||
const router = useRouter()
|
||||
|
||||
const commandInputRef = useRef<ElementRef<typeof CommandInput>>(null)
|
||||
const { isOpen, setIsOpen, search, setSearch, pages, setPages, currentPage, site } =
|
||||
const { isOpen, setIsOpen, search, setSearch, pages, setPages, currentPage, site, project } =
|
||||
useCommandMenu()
|
||||
const showCommandInput = !currentPage || !CHAT_ROUTES.includes(currentPage)
|
||||
|
||||
@@ -201,11 +204,27 @@ const CommandMenu = ({ projectRef }: CommandMenuProps) => {
|
||||
<CommandItem
|
||||
forceMount
|
||||
type="command"
|
||||
onSelect={() => setPages([...pages, COMMAND_ROUTES.API_KEYS])}
|
||||
onSelect={() => {
|
||||
setSearch('')
|
||||
setPages([...pages, COMMAND_ROUTES.API_KEYS])
|
||||
}}
|
||||
>
|
||||
<IconKey className="text-scale-1100" />
|
||||
<CommandLabel>Get API keys</CommandLabel>
|
||||
</CommandItem>
|
||||
{project?.apiUrl !== undefined && (
|
||||
<ChildItem
|
||||
isSubItem={false}
|
||||
onSelect={() => {
|
||||
copyToClipboard(project?.apiUrl ?? '')
|
||||
setIsOpen(false)
|
||||
}}
|
||||
className="space-x-2"
|
||||
>
|
||||
<IconLink className="text-scale-1100" />
|
||||
<CommandLabel>Copy API URL</CommandLabel>
|
||||
</ChildItem>
|
||||
)}
|
||||
</CommandGroup>
|
||||
)}
|
||||
|
||||
@@ -221,7 +240,7 @@ const CommandMenu = ({ projectRef }: CommandMenuProps) => {
|
||||
key={item.url}
|
||||
type="link"
|
||||
onSelect={() => {
|
||||
router.push(item.url)
|
||||
router.push(itemUrl)
|
||||
setIsOpen(false)
|
||||
}}
|
||||
>
|
||||
@@ -260,7 +279,13 @@ const CommandMenu = ({ projectRef }: CommandMenuProps) => {
|
||||
)}
|
||||
|
||||
<CommandGroup heading="Settings">
|
||||
<CommandItem type="link" onSelect={() => setPages([...pages, 'Theme'])}>
|
||||
<CommandItem
|
||||
type="link"
|
||||
onSelect={() => {
|
||||
setSearch('')
|
||||
setPages([...pages, 'Theme'])
|
||||
}}
|
||||
>
|
||||
<IconMonitor />
|
||||
Change theme
|
||||
</CommandItem>
|
||||
|
||||
@@ -23,7 +23,7 @@ export interface CommandMenuContextValue {
|
||||
/**
|
||||
* Project metadata for easy retrieval
|
||||
*/
|
||||
project?: { ref?: string; apiKeys?: { anon?: string; service?: string } }
|
||||
project?: { ref?: string; apiKeys?: { anon?: string; service?: string }; apiUrl?: string }
|
||||
/**
|
||||
* Any additional metadata that CMDK component can use in its AI prompts
|
||||
*/
|
||||
@@ -58,6 +58,7 @@ export interface CommandMenuProviderProps {
|
||||
* Project's API keys, for easy access through CMDK
|
||||
*/
|
||||
apiKeys?: { anon?: string; service?: string }
|
||||
apiUrl?: string
|
||||
/**
|
||||
* Opt in flag to use additional metadata in AI prompts
|
||||
*/
|
||||
@@ -77,6 +78,7 @@ const CommandMenuProvider = ({
|
||||
site,
|
||||
projectRef,
|
||||
apiKeys,
|
||||
apiUrl,
|
||||
metadata,
|
||||
isOptedInToAI = false,
|
||||
saveGeneratedSQL,
|
||||
@@ -89,7 +91,7 @@ const CommandMenuProvider = ({
|
||||
const currentPage = pages[pages.length - 1]
|
||||
|
||||
const actions: CommandMenuActions = { toggleTheme }
|
||||
const project = projectRef !== undefined ? { ref: projectRef, apiKeys } : undefined
|
||||
const project = projectRef !== undefined ? { ref: projectRef, apiKeys, apiUrl } : undefined
|
||||
|
||||
useKeyboardEvents({ setIsOpen, currentPage, setSearch, setPages })
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ const CommandMenuWrapper = ({ children }: PropsWithChildren<{}>) => {
|
||||
anon: settings?.autoApiService?.defaultApiKey ?? undefined,
|
||||
service: settings?.autoApiService?.serviceApiKey ?? undefined,
|
||||
}
|
||||
const apiUrl = `${settings?.autoApiService.protocol}://${settings?.autoApiService.endpoint}`
|
||||
|
||||
const { data } = useEntityDefinitionsQuery(
|
||||
{
|
||||
@@ -100,6 +101,7 @@ const CommandMenuWrapper = ({ children }: PropsWithChildren<{}>) => {
|
||||
site="studio"
|
||||
projectRef={ref}
|
||||
apiKeys={apiKeys}
|
||||
apiUrl={apiUrl}
|
||||
metadata={cmdkMetadata}
|
||||
isOptedInToAI={isOptedInToAI}
|
||||
saveGeneratedSQL={onSaveGeneratedSQL}
|
||||
|
||||
Reference in new issue
Block a user