From 77b565f781d49bbe98c17cd8439456cc1b581a0e Mon Sep 17 00:00:00 2001 From: Frank Noirot Date: Tue, 6 Aug 2024 16:19:30 -0400 Subject: [PATCH] Add a search bar to the projects/home page (#3301) * Add a search bar to the projects/home page * Better hotkey config * Look at this (photo)Graph *in the voice of Nickelback* * Re-run CI * Look at this (photo)Graph *in the voice of Nickelback* * Re-run CI --------- Co-authored-by: github-actions[bot] --- src/components/ProjectSearchBar.tsx | 63 +++++++++++++++++++++++++++++ src/routes/Home.tsx | 16 +++++--- 2 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 src/components/ProjectSearchBar.tsx diff --git a/src/components/ProjectSearchBar.tsx b/src/components/ProjectSearchBar.tsx new file mode 100644 index 000000000..eb1674ee8 --- /dev/null +++ b/src/components/ProjectSearchBar.tsx @@ -0,0 +1,63 @@ +import { Project } from 'wasm-lib/kcl/bindings/Project' +import { CustomIcon } from './CustomIcon' +import { useEffect, useRef, useState } from 'react' +import { useHotkeys } from 'react-hotkeys-hook' +import Fuse from 'fuse.js' + +export function useProjectSearch(projects: Project[]) { + const [query, setQuery] = useState('') + const [searchResults, setSearchResults] = useState(projects) + + const fuse = new Fuse(projects, { + keys: [{ name: 'name', weight: 0.7 }], + includeScore: true, + }) + + useEffect(() => { + const results = fuse.search(query).map((result) => result.item) + setSearchResults(query.length > 0 ? results : projects) + }, [query, projects]) + + return { + searchResults, + query, + setQuery, + } +} + +export function ProjectSearchBar({ + setQuery, +}: { + setQuery: (query: string) => void +}) { + const inputRef = useRef(null) + useHotkeys( + 'Ctrl+.', + (event) => { + event.preventDefault() + inputRef.current?.focus() + }, + { enableOnFormTags: true } + ) + + return ( +
+
+ + setQuery(event.target.value)} + className="w-full text-sm bg-transparent focus:outline-none selection:bg-primary/20 dark:selection:bg-primary/40 dark:focus:outline-none" + placeholder="Search projects (^.)" + autoCapitalize="off" + autoComplete="off" + autoCorrect="off" + spellCheck="false" + /> +
+
+ ) +} diff --git a/src/routes/Home.tsx b/src/routes/Home.tsx index 3f88517be..a14594c04 100644 --- a/src/routes/Home.tsx +++ b/src/routes/Home.tsx @@ -39,6 +39,7 @@ import { listProjects, renameProjectDirectory, } from 'lib/tauri' +import { ProjectSearchBar, useProjectSearch } from 'components/ProjectSearchBar' // This route only opens in the Tauri desktop context for now, // as defined in Router.tsx, so we can use the Tauri APIs and types. @@ -154,6 +155,7 @@ const Home = () => { }) const { projects } = state.context const [searchParams, setSearchParams] = useSearchParams() + const { searchResults, query, setQuery } = useProjectSearch(projects) const sort = searchParams.get('sort_by') ?? 'modified:desc' const isSortByModified = sort?.includes('modified') || !sort || sort === null @@ -206,8 +208,8 @@ const Home = () => {
-
-
+
+

Your Projects

{
+ Sort by { Loading your Projects... ) : ( <> - {projects.length > 0 ? ( + {searchResults.length > 0 ? (
    - {projects.sort(getSortFunction(sort)).map((project) => ( + {searchResults.sort(getSortFunction(sort)).map((project) => ( {
) : (

- No Projects found, ready to make your first one? + No Projects found + {projects.length === 0 + ? ', ready to make your first one?' + : ` with the search term "${query}"`}

)}