diff options
Diffstat (limited to 'apps')
| -rw-r--r-- | apps/web/app/dashboard/search/page.tsx | 10 | ||||
| -rw-r--r-- | apps/web/components/dashboard/SortOrderToggle.tsx | 36 | ||||
| -rw-r--r-- | apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx | 6 | ||||
| -rw-r--r-- | apps/web/lib/hooks/bookmark-search.ts | 9 | ||||
| -rw-r--r-- | apps/web/lib/i18n/locales/en/translation.json | 1 |
5 files changed, 52 insertions, 10 deletions
diff --git a/apps/web/app/dashboard/search/page.tsx b/apps/web/app/dashboard/search/page.tsx index beae73b8..c3542a88 100644 --- a/apps/web/app/dashboard/search/page.tsx +++ b/apps/web/app/dashboard/search/page.tsx @@ -1,14 +1,22 @@ "use client"; -import { Suspense } from "react"; +import { Suspense, useEffect } from "react"; import BookmarksGrid from "@/components/dashboard/bookmarks/BookmarksGrid"; import { FullPageSpinner } from "@/components/ui/full-page-spinner"; import { useBookmarkSearch } from "@/lib/hooks/bookmark-search"; +import { useSortOrderStore } from "@/lib/store/useSortOrderStore"; function SearchComp() { const { data, hasNextPage, fetchNextPage, isFetchingNextPage } = useBookmarkSearch(); + const { setSortOrder } = useSortOrderStore(); + + useEffect(() => { + // also see related cleanup code in SortOrderToggle.tsx + setSortOrder("relevance"); + }, []); + return ( <div className="flex flex-col gap-3"> {data ? ( diff --git a/apps/web/components/dashboard/SortOrderToggle.tsx b/apps/web/components/dashboard/SortOrderToggle.tsx index 8c0f617d..ba3385ac 100644 --- a/apps/web/components/dashboard/SortOrderToggle.tsx +++ b/apps/web/components/dashboard/SortOrderToggle.tsx @@ -1,3 +1,6 @@ +"use client"; + +import { useEffect } from "react"; import { ButtonWithTooltip } from "@/components/ui/button"; import { DropdownMenu, @@ -5,15 +8,26 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { useIsSearchPage } from "@/lib/hooks/bookmark-search"; import { useTranslation } from "@/lib/i18n/client"; import { useSortOrderStore } from "@/lib/store/useSortOrderStore"; -import { Check, SortAsc, SortDesc } from "lucide-react"; +import { Check, ListFilter, SortAsc, SortDesc } from "lucide-react"; export default function SortOrderToggle() { const { t } = useTranslation(); + const isInSearchPage = useIsSearchPage(); const { sortOrder: currentSort, setSortOrder } = useSortOrderStore(); + // also see related on page enter sortOrder.relevance init + // in apps/web/app/dashboard/search/page.tsx + useEffect(() => { + if (!isInSearchPage && currentSort === "relevance") { + // reset to default sort order + setSortOrder("desc"); + } + }, [isInSearchPage, currentSort]); + return ( <DropdownMenu> <DropdownMenuTrigger asChild> @@ -22,14 +36,24 @@ export default function SortOrderToggle() { delayDuration={100} variant="ghost" > - {currentSort === "asc" ? ( - <SortAsc size={18} /> - ) : ( - <SortDesc size={18} /> - )} + {currentSort === "relevance" && <ListFilter size={18} />} + {currentSort === "asc" && <SortAsc size={18} />} + {currentSort === "desc" && <SortDesc size={18} />} </ButtonWithTooltip> </DropdownMenuTrigger> <DropdownMenuContent className="w-fit"> + {isInSearchPage && ( + <DropdownMenuItem + className="cursor-pointer justify-between" + onClick={() => setSortOrder("relevance")} + > + <div className="flex items-center"> + <ListFilter size={16} className="mr-2" /> + <span>{t("actions.sort.relevant_first")}</span> + </div> + {currentSort === "relevance" && <Check className="ml-2 h-4 w-4" />} + </DropdownMenuItem> + )} <DropdownMenuItem className="cursor-pointer justify-between" onClick={() => setSortOrder("desc")} diff --git a/apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx b/apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx index da65b9d9..968d0326 100644 --- a/apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx +++ b/apps/web/components/dashboard/bookmarks/UpdatableBookmarksGrid.tsx @@ -23,7 +23,11 @@ export default function UpdatableBookmarksGrid({ showEditorCard?: boolean; itemsPerPage?: number; }) { - const sortOrder = useSortOrderStore((state) => state.sortOrder); + let sortOrder = useSortOrderStore((state) => state.sortOrder); + if (sortOrder === "relevance") { + // Relevance is not supported in the `getBookmarks` endpoint. + sortOrder = "desc"; + } const finalQuery = { ...query, sortOrder, includeContent: false }; diff --git a/apps/web/lib/hooks/bookmark-search.ts b/apps/web/lib/hooks/bookmark-search.ts index 1bccd280..b6af94ee 100644 --- a/apps/web/lib/hooks/bookmark-search.ts +++ b/apps/web/lib/hooks/bookmark-search.ts @@ -6,6 +6,11 @@ import { keepPreviousData } from "@tanstack/react-query"; import { parseSearchQuery } from "@karakeep/shared/searchQueryParser"; +export function useIsSearchPage() { + const pathname = usePathname(); + return pathname.startsWith("/dashboard/search"); +} + function useSearchQuery() { const searchParams = useSearchParams(); const searchQuery = decodeURIComponent(searchParams.get("q") ?? ""); @@ -17,8 +22,8 @@ function useSearchQuery() { export function useDoBookmarkSearch() { const router = useRouter(); const { searchQuery, parsedSearchQuery } = useSearchQuery(); + const isInSearchPage = useIsSearchPage(); const [timeoutId, setTimeoutId] = useState<NodeJS.Timeout | undefined>(); - const pathname = usePathname(); useEffect(() => { return () => { @@ -49,7 +54,7 @@ export function useDoBookmarkSearch() { debounceSearch, searchQuery, parsedSearchQuery, - isInSearchPage: pathname.startsWith("/dashboard/search"), + isInSearchPage, }; } diff --git a/apps/web/lib/i18n/locales/en/translation.json b/apps/web/lib/i18n/locales/en/translation.json index 42a904a4..aef2d2a7 100644 --- a/apps/web/lib/i18n/locales/en/translation.json +++ b/apps/web/lib/i18n/locales/en/translation.json @@ -79,6 +79,7 @@ "ignore": "Ignore", "sort": { "title": "Sort", + "relevant_first": "Most Relevant First", "newest_first": "Newest First", "oldest_first": "Oldest First" } |
