diff --git a/frontend/components/knowledge-filter-panel.tsx b/frontend/components/knowledge-filter-panel.tsx index e8c26e37..d0dd8196 100644 --- a/frontend/components/knowledge-filter-panel.tsx +++ b/frontend/components/knowledge-filter-panel.tsx @@ -321,7 +321,7 @@ export function KnowledgeFilterPanel() { className="font-mono placeholder:font-mono" onChange={(e) => setQuery(e.target.value)} rows={2} - disabled={!!queryOverride} + disabled={!!queryOverride && !createMode} /> diff --git a/frontend/components/knowledge-search-input.tsx b/frontend/components/knowledge-search-input.tsx new file mode 100644 index 00000000..fd840628 --- /dev/null +++ b/frontend/components/knowledge-search-input.tsx @@ -0,0 +1,100 @@ +import { useKnowledgeFilter } from "@/contexts/knowledge-filter-context"; +import { + ChangeEvent, + FormEvent, + useCallback, + useEffect, + useState, +} from "react"; +import { filterAccentClasses } from "./knowledge-filter-panel"; +import { ArrowRight, Search, X } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { cn } from "@/lib/utils"; + +export const KnowledgeSearchInput = () => { + const { + selectedFilter, + setSelectedFilter, + parsedFilterData, + queryOverride, + setQueryOverride, + } = useKnowledgeFilter(); + + const [searchQueryInput, setSearchQueryInput] = useState(queryOverride || ""); + + const handleSearch = useCallback( + (e?: FormEvent) => { + if (e) e.preventDefault(); + setQueryOverride(searchQueryInput.trim()); + }, + [searchQueryInput, setQueryOverride] + ); + + // Reset the query text when the selected filter changes + useEffect(() => { + setSearchQueryInput(queryOverride); + }, [queryOverride]); + + return ( +
+
+ {selectedFilter?.name && ( +
+ {selectedFilter?.name} + setSelectedFilter(null)} + /> +
+ )} + + ) => + setSearchQueryInput(e.target.value) + } + /> + {queryOverride && ( + + )} + +
+
+ ); +}; diff --git a/frontend/src/app/knowledge/chunks/page.tsx b/frontend/src/app/knowledge/chunks/page.tsx index cb96eddc..c6a3d5e8 100644 --- a/frontend/src/app/knowledge/chunks/page.tsx +++ b/frontend/src/app/knowledge/chunks/page.tsx @@ -6,15 +6,13 @@ import { useRouter, useSearchParams } from "next/navigation"; import { ProtectedRoute } from "@/components/protected-route"; import { Button } from "@/components/ui/button"; import { useKnowledgeFilter } from "@/contexts/knowledge-filter-context"; -import { useTask } from "@/contexts/task-context"; import { type ChunkResult, type File, useGetSearchQuery, } from "../../api/queries/useGetSearchQuery"; -import { Label } from "@/components/ui/label"; import { Checkbox } from "@/components/ui/checkbox"; -import { Input } from "@/components/ui/input"; +import { KnowledgeSearchInput } from "@/components/knowledge-search-input"; const getFileTypeLabel = (mimetype: string) => { if (mimetype === "application/pdf") return "PDF"; @@ -26,8 +24,7 @@ const getFileTypeLabel = (mimetype: string) => { function ChunksPageContent() { const router = useRouter(); const searchParams = useSearchParams(); - const { isMenuOpen } = useTask(); - const { parsedFilterData, isPanelOpen } = useKnowledgeFilter(); + const { parsedFilterData, queryOverride } = useKnowledgeFilter(); const filename = searchParams.get("filename"); const [chunks, setChunks] = useState([]); @@ -47,25 +44,25 @@ function ChunksPageContent() { [chunks] ); - const [selectAll, setSelectAll] = useState(false); - const [queryInputText, setQueryInputText] = useState( - parsedFilterData?.query ?? "" - ); + // const [selectAll, setSelectAll] = useState(false); // Use the same search query as the knowledge page, but we'll filter for the specific file - const { data = [], isFetching } = useGetSearchQuery("*", parsedFilterData); + const { data = [], isFetching } = useGetSearchQuery( + queryOverride, + parsedFilterData + ); - useEffect(() => { - if (queryInputText === "") { - setChunksFilteredByQuery(chunks); - } else { - setChunksFilteredByQuery( - chunks.filter((chunk) => - chunk.text.toLowerCase().includes(queryInputText.toLowerCase()) - ) - ); - } - }, [queryInputText, chunks]); + // useEffect(() => { + // if (queryInputText === "") { + // setChunksFilteredByQuery(chunks); + // } else { + // setChunksFilteredByQuery( + // chunks.filter((chunk) => + // chunk.text.toLowerCase().includes(queryInputText.toLowerCase()) + // ) + // ); + // } + // }, [queryInputText, chunks]); const handleCopy = useCallback((text: string, index: number) => { // Trim whitespace and remove new lines/tabs for cleaner copy @@ -89,13 +86,13 @@ function ChunksPageContent() { }, [data, filename]); // Set selected state for all checkboxes when selectAll changes - useEffect(() => { - if (selectAll) { - setSelectedChunks(new Set(chunks.map((_, index) => index))); - } else { - setSelectedChunks(new Set()); - } - }, [selectAll, setSelectedChunks, chunks]); + // useEffect(() => { + // if (selectAll) { + // setSelectedChunks(new Set(chunks.map((_, index) => index))); + // } else { + // setSelectedChunks(new Set()); + // } + // }, [selectAll, setSelectedChunks, chunks]); const handleBack = useCallback(() => { router.push("/knowledge"); @@ -131,25 +128,17 @@ function ChunksPageContent() { } return ( -
-
+
+
{/* Header */} -
-
-

@@ -157,39 +146,12 @@ function ChunksPageContent() { {filename.replace(/\.[^/.]+$/, "")}

-
-
- : null} - id="search-query" - type="text" - defaultValue={parsedFilterData?.query} - value={queryInputText} - onChange={(e) => setQueryInputText(e.target.value)} - placeholder="Search chunks..." - /> -
-
- - setSelectAll(!!handleSelectAll) - } - /> - -
-
+ {/* Search input */} +
{/* Content Area - matches knowledge page structure */} -
+
{isFetching ? (
@@ -211,7 +173,23 @@ function ChunksPageContent() {
) : (
- {chunksFilteredByQuery.map((chunk, index) => ( + {/* TODO - add chunk selection when sync and delete are ready */} + {/*
+ + setSelectAll(!!handleSelectAll) + } + /> + +
*/} + {chunks.map((chunk, index) => (
([]); const [showBulkDeleteDialog, setShowBulkDeleteDialog] = useState(false); @@ -74,14 +66,6 @@ function SearchPage() { parsedFilterData ); - const handleSearch = useCallback( - (e?: FormEvent) => { - if (e) e.preventDefault(); - setQueryOverride(searchQueryInput.trim()); - }, - [searchQueryInput, setQueryOverride] - ); - // Convert TaskFiles to File format and merge with backend results const taskFilesAsFiles: File[] = taskFiles.map((taskFile) => { return { @@ -246,11 +230,6 @@ function SearchPage() { } }; - // Reset the query text when the selected filter changes - useEffect(() => { - setSearchQueryInput(queryOverride); - }, [queryOverride]); - return ( <>
@@ -260,78 +239,9 @@ function SearchPage() { {/* Search Input Area */}
-
-
- {selectedFilter?.name && ( -
- {selectedFilter?.name} - setSelectedFilter(null)} - /> -
- )} - - ) => - setSearchQueryInput(e.target.value) - } - /> - {queryOverride && ( - - )} - -
- {/* */} - {/* //TODO: Implement sync button */} - {/* */} - {selectedRows.length > 0 && ( - - )} -
+ {selectedRows.length > 0 && ( + + )}