diff --git a/bun.lockb b/bun.lockb index 518de3c..a4c2940 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 4482f5e..0c29972 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@heroicons/react": "^2.0.18", "@tailwindcss/forms": "^0.5.6", "@tanstack/react-query": "^4.35.3", + "classnames": "^2.3.2", "ramda": "^0.29.0", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/src/App.tsx b/src/App.tsx index 6ec9c01..89f37b2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,12 +1,14 @@ -import {ChangeEvent, ReactNode, useCallback, useState} from "react"; +import {ReactNode, useCallback, useState} from "react"; import {FixedSizeList as List} from "react-window"; import Select, {createFilter, MenuListProps} from "react-select"; import * as R from 'ramda'; +import classNames from "classnames"; import {useQuery} from "@tanstack/react-query"; -import {LinkCollection, Option} from "./aliases"; -import AsyncSelect from "react-select/async"; +import {LinkCollection, type Option} from "./aliases"; +import {CheckIcon, ChevronUpDownIcon} from '@heroicons/react/20/solid' +import {Combobox} from '@headlessui/react' // TODO: Fix this for wrapping items, esp on phones const height = 35; @@ -82,6 +84,7 @@ type ResultNoteApi = { basename: string foundWords: string[] matches: SearchMatchApi[] + excerpt: string } type SearchMatchApi = { @@ -89,7 +92,9 @@ type SearchMatchApi = { offset: number } -export function OmnisearchSelect({ setSelected }: { setSelected: (value: Option) => void }) { +export function OmnisearchSelect({setSelected}: { + setSelected: (value: Option) => void +}) { const { data: metadata, isLoading, @@ -108,30 +113,87 @@ export function OmnisearchSelect({ setSelected }: { setSelected: (value: Option) }, }); - const [filter, setFilter] = useState('[]'); + const [query, setQuery] = useState('') + const [selectedPerson, setSelectedPerson] = useState(null); - const onChange = useCallback((e: ChangeEvent) => { - setFilter(e.target.value); - }, []); - - const { data: options } = useQuery({ - queryKey: ['obsidian-omnisearch', filter], + const {data: filteredPeople} = useQuery({ + queryKey: ['obsidian-omnisearch', query], initialData: [], queryFn: async () => { - const response = await fetch(`/search?q=${filter}`) - const fullData: ResultNoteApi[] = await response.json(); + if (query === '') { + return []; + } else { + const response = await fetch(`/search?q=${query}`) + const fullData: ResultNoteApi[] = await response.json(); - return fullData; + return fullData; + } } }); - return (<> - + return ( + Assigned to +
+ setQuery(event.target.value)} + displayValue={(person: ResultNoteApi) => person?.basename} + /> + + - {options.map(option => ( -
{option.basename}
- ))} - ); + {filteredPeople.length > 0 && ( + + {filteredPeople.map((person) => ( + + classNames( + 'relative cursor-default select-none py-2 pl-3 pr-9', + active ? 'bg-indigo-600 text-white' : 'text-gray-900' + ) + } + > + {({ + active, + selected + }) => ( + <> +
+ {person?.basename} + + {person?.path} + +
+ + {selected && ( + + + )} + + )} +
+ ))} +
+ )} +
+
); } export function App() {