From 1efc5963cbfc7794443a9e07d9305efae5d30acb Mon Sep 17 00:00:00 2001 From: billionaireDY Date: Fri, 7 Jun 2024 16:57:43 +0900 Subject: [PATCH] [#noissue] fix: fix search to fuzzy search --- web-frontend/src/main/v3/packages/ui/package.json | 1 + .../ui/src/components/Agent/AgentListFetcher.tsx | 11 ++++++++--- .../ui/src/components/Host/HostListFetcher.tsx | 14 ++++++++++---- .../ui/src/components/VirtualList/VirtualList.tsx | 15 ++++++++++++--- web-frontend/src/main/v3/yarn.lock | 5 +++++ 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/web-frontend/src/main/v3/packages/ui/package.json b/web-frontend/src/main/v3/packages/ui/package.json index a71e070bb771..ea7c58e8f2fb 100644 --- a/web-frontend/src/main/v3/packages/ui/package.json +++ b/web-frontend/src/main/v3/packages/ui/package.json @@ -79,6 +79,7 @@ "cmdk": "^0.2.0", "date-fns": "^2.28.0", "deepmerge": "^4.3.1", + "fuse.js": "^7.0.0", "google-libphonenumber": "^3.2.34", "highlight.js": "^11.9.0", "lodash.clonedeep": "^4.5.0", diff --git a/web-frontend/src/main/v3/packages/ui/src/components/Agent/AgentListFetcher.tsx b/web-frontend/src/main/v3/packages/ui/src/components/Agent/AgentListFetcher.tsx index bdd75547274c..fb5c81fe7f24 100644 --- a/web-frontend/src/main/v3/packages/ui/src/components/Agent/AgentListFetcher.tsx +++ b/web-frontend/src/main/v3/packages/ui/src/components/Agent/AgentListFetcher.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import Fuse from 'fuse.js'; import { RxCheck } from 'react-icons/rx'; import { LuChevronRight, LuChevronDown } from 'react-icons/lu'; import { AGENT_LIST_SORT, useGetAgentList } from '@pinpoint-fe/hooks'; @@ -33,9 +34,13 @@ export const AgentListFetcher = ({ const [openStates, setOpenStates] = React.useState([]); const filteredList = React.useMemo(() => { return data?.reduce((acc, curr) => { - const filteredInstanceList = curr.instancesList.filter((instance) => - new RegExp(filterKeyword, 'i').test(instance.agentId), - ); + const fuzzySearch = new Fuse(curr.instancesList, { + keys: ['agentId'], + threshold: 0.3, + }); + const filteredInstanceList = filterKeyword + ? fuzzySearch.search(filterKeyword).map(({ item }) => item) + : curr.instancesList; if (filteredInstanceList.length > 0) { acc.push({ ...curr, diff --git a/web-frontend/src/main/v3/packages/ui/src/components/Host/HostListFetcher.tsx b/web-frontend/src/main/v3/packages/ui/src/components/Host/HostListFetcher.tsx index 9045c5459215..22e8e435a894 100644 --- a/web-frontend/src/main/v3/packages/ui/src/components/Host/HostListFetcher.tsx +++ b/web-frontend/src/main/v3/packages/ui/src/components/Host/HostListFetcher.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import Fuse from 'fuse.js'; import { RxCheck } from 'react-icons/rx'; import { useGetSystemMetricHostData } from '@pinpoint-fe/hooks'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../ui'; @@ -21,10 +22,15 @@ export const HostListFetcher = ({ style, }: HostListFetcherProps) => { const { data } = useGetSystemMetricHostData(); - const filteredList = React.useMemo( - () => data?.filter((host) => host.toLowerCase().includes(filterKeyword.toLowerCase())), - [data, filterKeyword], - ); + const fuzzySearch = React.useMemo(() => { + return new Fuse(data || [], { + threshold: 0.3, + }); + }, [data]); + + const filteredList = filterKeyword + ? fuzzySearch.search(filterKeyword).map(({ item }) => item) + : data; React.useEffect(() => { if (selectedHost) { diff --git a/web-frontend/src/main/v3/packages/ui/src/components/VirtualList/VirtualList.tsx b/web-frontend/src/main/v3/packages/ui/src/components/VirtualList/VirtualList.tsx index f4846be92f25..2c30a9440aa9 100644 --- a/web-frontend/src/main/v3/packages/ui/src/components/VirtualList/VirtualList.tsx +++ b/web-frontend/src/main/v3/packages/ui/src/components/VirtualList/VirtualList.tsx @@ -1,4 +1,6 @@ +import React from 'react'; import { Virtuoso } from 'react-virtuoso'; +import Fuse from 'fuse.js'; import { cn } from '../../lib/utils'; export interface VirtualListProps { @@ -24,9 +26,16 @@ export const VirtualList = ({ onClickItem, itemAs: ListComponent = 'div', }: VirtualListProps) => { - const filteredList = list?.filter((l) => { - return new RegExp(filterKeyword, 'i').test(`${filterKey ? l[filterKey] : l}`); - }); + const fuzzySearch = React.useMemo(() => { + return new Fuse(list || [], { + keys: filterKey ? [filterKey as string] : [], + threshold: 0.3, + }); + }, [filterKey, list]); + + const filteredList = filterKeyword + ? fuzzySearch.search(filterKeyword).map(({ item }) => item) + : list; if (filteredList?.length === 0) { return
{empty}
; diff --git a/web-frontend/src/main/v3/yarn.lock b/web-frontend/src/main/v3/yarn.lock index 56868dfabe7b..e411ed23125d 100644 --- a/web-frontend/src/main/v3/yarn.lock +++ b/web-frontend/src/main/v3/yarn.lock @@ -10752,6 +10752,11 @@ functions-have-names@^1.2.3: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== +fuse.js@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-7.0.0.tgz#6573c9fcd4c8268e403b4fc7d7131ffcf99a9eb2" + integrity sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q== + gauge@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395"