import Button from '@/components/ui/Button' import Dialog from '@/components/ui/Dialog' import { GLOBAL_SEARCH } from '@/constants/permission.constant' import withHeaderItem from '@/utils/hoc/withHeaderItem' import useThemeClass from '@/utils/hooks/useThemeClass' import classNames from 'classnames' import { useEffect, useRef, useState } from 'react' import Highlighter from 'react-highlight-words' import { FaChevronRight, FaSearch } from 'react-icons/fa'; import { Link } from 'react-router-dom' import { PermissionCheck } from '../shared' import { Badge, Checkbox, Pagination } from '../ui' import { useLocalization } from '@/utils/hooks/useLocalization' import { getSearch, getSystems } from '@/services/global-search.service' type SearchData = { title: string url: string icon?: string category?: string categoryTitle?: string } type SearchResult = { title: string badge?: string data: SearchData[] } const ListItem = (props: { icon?: string label: string url: string isLast?: boolean keyWord: string onNavigate: () => void }) => { const { icon, label, url = '', isLast, keyWord, onNavigate } = props const { textTheme } = useThemeClass() return (
{/*
{icon && navigationIcon[icon]}
*/}
) } const _Search = ({ className }: { className?: string }) => { const [searchDialogOpen, setSearchDialogOpen] = useState(false) const [searchResult, setSearchResult] = useState([]) const [systems, setSystems] = useState([]) const [noResult, setNoResult] = useState(false) const [totalCount, setTotalCount] = useState(0) const [currentPage, setCurrentPage] = useState(1) const [currentSystems, setCurrentSystems] = useState([]) const { translate } = useLocalization() const inputRef = useRef(null) const handleReset = () => { setNoResult(false) setCurrentPage(1) setTotalCount(0) setSearchResult([]) } const handleSearchOpen = async () => { const result = await getSystems() if (result?.data) { setSystems(result.data) setCurrentSystems(result.data) } setSearchDialogOpen(true) } const handleSearchClose = () => { setSearchDialogOpen(false) if (noResult) { setTimeout(() => { handleReset() }, 300) } } const handleSearch = async () => { const q = inputRef.current?.value if (!q || q.length < 3) return const result = await getSearch({ query: q, system: currentSystems, page: currentPage }) if (!result.data?.totalCount || !result.data.items?.length) { setNoResult(true) setTotalCount(0) setSearchResult([]) return } setTotalCount(result.data.totalCount) const results = result.data.items.reduce((acc, curr) => { const a = acc.find((item) => item.title === curr.group && item.badge === curr.system) if (a) { a.data.push({ title: curr.term, url: curr.url, }) } else { acc.push({ title: curr.group, badge: curr.system, data: [ { title: curr.term, url: curr.url, }, ], }) } return acc }, [] as SearchResult[]) setSearchResult(results) } useEffect(() => { handleSearch() }, [currentPage]) useEffect(() => { if (searchDialogOpen) { const timeout = setTimeout(() => inputRef.current?.focus(), 100) return () => { clearTimeout(timeout) } } }, [searchDialogOpen]) const handleNavigate = () => { handleSearchClose() } return (
e.key === 'Enter' && handleSearch()} />
{translate('::App.SearchIn')} setCurrentSystems(value as string[])} > {systems.map((system) => ( {system} ))}
{searchResult.map((result) => (
{result.title}
{result.data.map((data, index) => ( ))}
))} {searchResult.length === 0 && noResult && (
{translate('::App.NoResults')}
'{inputRef.current?.value}'
)}
) } const Search = withHeaderItem(_Search) export default Search