/* * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ import { useCallback, useEffect, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { Dialog, DialogContent, DialogTitle } from '@/components/ui/dialog'; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command'; import { friendlyName, getActionInfo, getObjectKind, useGlobalSearch } from '@/hooks/useGlobalSearch'; import type { SearchIndexEntry } from '@/stores/schemaStore'; interface CommandPaletteProps { open: boolean; onOpenChange: (open: boolean) => void; } export function CommandPalette({ open, onOpenChange }: CommandPaletteProps) { const { t } = useTranslation(); const closePalette = useCallback(() => onOpenChange(false), [onOpenChange]); const { query, setQuery, debouncedQuery, groups, selectEntry, reset, schema } = useGlobalSearch(closePalette); const groupLabels: Record = useMemo( () => ({ link: t('globalSearch.pages', 'Pages'), form: t('globalSearch.formSections', 'Form Sections'), field: t('globalSearch.fields', 'Fields'), }), [t], ); useEffect(() => { if (!open) reset(); }, [open, reset]); return ( {t('globalSearch.title', 'Search')} ESC } /> {debouncedQuery.trim() ? t('globalSearch.noResults', 'No results found.') : t('globalSearch.typeToSearch', 'Type to search the admin panel.')} {Array.from(groups.entries()).map(([type, entries]) => ( {entries.map((entry, idx) => { const objectKind = schema ? getObjectKind(schema, entry.viewName) : null; const { label: actionLabel, Icon: ActionIcon } = getActionInfo(entry.type, objectKind, t); const itemValue = `${type}-${idx}-${entry.viewName}`; return ( selectEntry(entry)}>
{friendlyName(entry.text)} {entry.breadcrumb}
{actionLabel}
); })}
))}
); }