diff --git a/package.json b/package.json index aef945f1..e0974557 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "jszip": "^3.6.0", "jwt-decode": "^3.1.2", "lodash": "^4.17.21", + "match-sorter": "^6.3.1", "notistack": "^2.0.2", "pb-util": "^1.0.1", "query-string": "^6.8.3", diff --git a/src/hooks/useBasicSearch.ts b/src/hooks/useBasicSearch.ts index 47825662..13f6437d 100644 --- a/src/hooks/useBasicSearch.ts +++ b/src/hooks/useBasicSearch.ts @@ -1,17 +1,16 @@ import { useState } from "react"; import { useDebouncedCallback } from "use-debounce"; +import { matchSorter } from "match-sorter"; export default function useBasicSearch( list: T[], - predicate: (item: T, query: string) => boolean, + keys: string[], debounce: number = 400 ) { const [query, setQuery] = useState(""); const [handleQuery] = useDebouncedCallback(setQuery, debounce); - const results = query - ? list.filter((user) => predicate(user, query.toLowerCase())) - : list; + const results = query ? matchSorter(list, query, { keys }) : list; return [results, query, handleQuery] as const; } diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index c002810b..c9a21af7 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -46,6 +46,7 @@ import { SETTINGS } from "@src/config/dbPaths"; import { APP_BAR_HEIGHT } from "@src/components/Navigation"; const useHomeViewState = createPersistedState("__ROWY__HOME_VIEW"); +const SEARCH_KEYS = ["id", "name", "section", "description"]; export default function HomePage() { const { userDoc, userRoles } = useAppContext(); @@ -53,11 +54,7 @@ export default function HomePage() { const [results, query, handleQuery] = useBasicSearch( tables ?? [], - (table, query) => - table.id.toLowerCase().includes(query) || - table.name.toLowerCase().includes(query) || - table.section.toLowerCase().includes(query) || - table.description.toLowerCase().includes(query) + SEARCH_KEYS ); const [view, setView] = useHomeViewState("grid"); diff --git a/src/pages/Settings/UserManagement.tsx b/src/pages/Settings/UserManagement.tsx index b2670b69..6d10e0d2 100644 --- a/src/pages/Settings/UserManagement.tsx +++ b/src/pages/Settings/UserManagement.tsx @@ -20,6 +20,8 @@ import useCollection from "@src/hooks/useCollection"; import useBasicSearch from "@src/hooks/useBasicSearch"; import { USERS } from "@src/config/dbPaths"; +const SEARCH_KEYS = ["id", "user.displayName", "user.email"]; + export interface User { id: string; user: { @@ -35,13 +37,7 @@ export default function UserManagementPage() { const users: User[] = usersState.documents ?? []; const loading = usersState.loading || !Array.isArray(usersState.documents); - const [results, query, handleQuery] = useBasicSearch( - users, - (user, query) => - user.id.toLowerCase() === query || - user.user.displayName.toLowerCase().includes(query) || - user.user.email.toLowerCase().includes(query) - ); + const [results, query, handleQuery] = useBasicSearch(users, SEARCH_KEYS); return ( diff --git a/yarn.lock b/yarn.lock index f8354670..d13cecfd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1481,6 +1481,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.12.5": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.0.tgz#b8d142fc0f7664fb3d9b5833fd40dcbab89276c0" + integrity sha512-etcO/ohMNaNA2UBdaXBBSX/3aEzFMRrVfaPv8Ptc0k+cWpWW0QFiGZ2XnVqQZI1Cf734LbPGmqBKWESfW4x/dQ== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/runtime@^7.13.10", "@babel/runtime@^7.8.4": version "7.15.3" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.3.tgz#2e1c2880ca118e5b2f9988322bd8a7656a32502b" @@ -11103,6 +11110,14 @@ marked@^0.7.0: resolved "https://registry.yarnpkg.com/marked/-/marked-0.7.0.tgz#b64201f051d271b1edc10a04d1ae9b74bb8e5c0e" integrity sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg== +match-sorter@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-6.3.1.tgz#98cc37fda756093424ddf3cbc62bfe9c75b92bda" + integrity sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw== + dependencies: + "@babel/runtime" "^7.12.5" + remove-accents "0.4.2" + material-colors@^1.2.1: version "1.2.6" resolved "https://registry.yarnpkg.com/material-colors/-/material-colors-1.2.6.tgz#6d1958871126992ceecc72f4bcc4d8f010865f46" @@ -14839,6 +14854,11 @@ remark-rehype@^10.0.0: mdast-util-to-hast "^12.1.0" unified "^10.0.0" +remove-accents@0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.4.2.tgz#0a43d3aaae1e80db919e07ae254b285d9e1c7bb5" + integrity sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U= + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"