| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- import React from 'react'
- import { useLocation, useNavigate } from '@tanstack/react-router'
- import { ArrowRight, ChevronRight, Laptop, Moon, Sun } from 'lucide-react'
- import { useTranslation } from 'react-i18next'
- import { useSearch } from '@/context/search-provider'
- import { useTheme } from '@/context/theme-provider'
- import { useSidebarData } from '@/hooks/use-sidebar-data'
- import {
- CommandDialog,
- CommandEmpty,
- CommandGroup,
- CommandInput,
- CommandItem,
- CommandList,
- CommandSeparator,
- } from '@/components/ui/command'
- import { getNavGroupsForPath } from './layout/lib/workspace-registry'
- import { ScrollArea } from './ui/scroll-area'
- export function CommandMenu() {
- const { t } = useTranslation()
- const navigate = useNavigate()
- const { setTheme } = useTheme()
- const { open, setOpen } = useSearch()
- const { pathname } = useLocation()
- const sidebarData = useSidebarData()
- // 根据当前路径从工作区注册表获取对应的侧边栏配置
- const navGroups = getNavGroupsForPath(pathname, t) || sidebarData.navGroups
- const runCommand = React.useCallback(
- (command: () => unknown) => {
- setOpen(false)
- command()
- },
- [setOpen]
- )
- return (
- <CommandDialog modal open={open} onOpenChange={setOpen}>
- <CommandInput placeholder={t('Type a command or search...')} />
- <CommandList>
- <ScrollArea type='hover' className='h-72 pe-1'>
- <CommandEmpty>{t('No results found.')}</CommandEmpty>
- {navGroups.map((group) => (
- <CommandGroup key={group.id || group.title} heading={group.title}>
- {group.items.map((navItem, i) => {
- if (navItem.url)
- return (
- <CommandItem
- key={`${navItem.url}-${i}`}
- value={navItem.title}
- onSelect={() => {
- runCommand(() => navigate({ to: navItem.url }))
- }}
- >
- <div className='flex size-4 items-center justify-center'>
- <ArrowRight className='text-muted-foreground/80 size-2' />
- </div>
- {navItem.title}
- </CommandItem>
- )
- return navItem.items?.map((subItem, i) => (
- <CommandItem
- key={`${navItem.title}-${subItem.url}-${i}`}
- value={`${navItem.title}-${subItem.url}`}
- onSelect={() => {
- runCommand(() => navigate({ to: subItem.url }))
- }}
- >
- <div className='flex size-4 items-center justify-center'>
- <ArrowRight className='text-muted-foreground/80 size-2' />
- </div>
- {navItem.title} <ChevronRight /> {subItem.title}
- </CommandItem>
- ))
- })}
- </CommandGroup>
- ))}
- <CommandSeparator />
- <CommandGroup heading='Theme'>
- <CommandItem onSelect={() => runCommand(() => setTheme('light'))}>
- <Sun /> <span>{t('Light')}</span>
- </CommandItem>
- <CommandItem onSelect={() => runCommand(() => setTheme('dark'))}>
- <Moon className='scale-90' />
- <span>{t('Dark')}</span>
- </CommandItem>
- <CommandItem onSelect={() => runCommand(() => setTheme('system'))}>
- <Laptop />
- <span>{t('System')}</span>
- </CommandItem>
- </CommandGroup>
- </ScrollArea>
- </CommandList>
- </CommandDialog>
- )
- }
|