From 8f3b14903464126e1e90cf8e6117072472ee5f13 Mon Sep 17 00:00:00 2001 From: Cole Goldsmith Date: Fri, 19 Sep 2025 15:21:18 -0500 Subject: [PATCH] add more mutation queries and fix backend to wait for updates --- frontend/components/knowledge-filter-list.tsx | 230 ++++------ .../components/knowledge-filter-panel.tsx | 392 ++++++++++-------- frontend/components/ui/textarea.tsx | 2 +- frontend/src/app/api/[...path]/route.ts | 50 ++- .../src/app/api/mutations/useCreateFilter.ts | 50 +++ .../src/app/api/mutations/useDeleteFilter.ts | 39 ++ .../api/queries/useGetFiltersSearchQuery.ts | 44 +- frontend/src/app/knowledge/page.tsx | 43 +- frontend/src/components/layout-wrapper.tsx | 9 +- src/services/knowledge_filter_service.py | 34 +- 10 files changed, 501 insertions(+), 392 deletions(-) create mode 100644 frontend/src/app/api/mutations/useCreateFilter.ts create mode 100644 frontend/src/app/api/mutations/useDeleteFilter.ts diff --git a/frontend/components/knowledge-filter-list.tsx b/frontend/components/knowledge-filter-list.tsx index 5815391a..134f09f1 100644 --- a/frontend/components/knowledge-filter-list.tsx +++ b/frontend/components/knowledge-filter-list.tsx @@ -1,31 +1,22 @@ "use client"; -import { useState, useEffect, useRef } from "react"; +import { useState } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; -import { Card, CardContent } from "@/components/ui/card"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; -import { - ChevronDown, - Filter, - Search, - X, - Loader2, - Plus, - Save, -} from "lucide-react"; +import { Filter, X, Loader2, Plus, Save } from "lucide-react"; import { cn } from "@/lib/utils"; import { useGetFiltersSearchQuery, type KnowledgeFilter, } from "@/src/app/api/queries/useGetFiltersSearchQuery"; +import { useCreateFilter } from "@/src/app/api/mutations/useCreateFilter"; import { Dialog, DialogContent, DialogDescription, - DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; @@ -56,43 +47,22 @@ export function KnowledgeFilterList({ const [createDescription, setCreateDescription] = useState(""); const [creating, setCreating] = useState(false); - const { - data, - isFetching: loading, - refetch, - } = useGetFiltersSearchQuery(searchQuery, 20, { enabled: true }); - const filters: KnowledgeFilter[] = (data ?? []) as KnowledgeFilter[]; + const { data, isFetching: loading } = useGetFiltersSearchQuery( + searchQuery, + 20 + ); - const deleteFilter = async (filterId: string, e: React.MouseEvent) => { - e.stopPropagation(); + const filters = data || []; - try { - const response = await fetch(`/api/knowledge-filter/${filterId}`, { - method: "DELETE", - }); - - if (response.ok) { - // If this was the selected filter, clear selection - if (selectedFilter?.id === filterId) { - onFilterSelect(null); - } - // Refresh list - refetch(); - } else { - console.error("Failed to delete knowledge filter"); - } - } catch (error) { - console.error("Error deleting knowledge filter:", error); - } - }; + const createFilterMutation = useCreateFilter(); const handleFilterSelect = (filter: KnowledgeFilter) => { onFilterSelect(filter); }; - const handleClearFilter = () => { - onFilterSelect(null); - }; + // const handleClearFilter = () => { + // onFilterSelect(null); + // }; const handleCreateNew = () => { setShowCreateModal(true); @@ -115,43 +85,19 @@ export function KnowledgeFilterList({ scoreThreshold: 0, }; - const response = await fetch("/api/knowledge-filter", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - name: createName.trim(), - description: createDescription.trim(), - queryData: JSON.stringify(defaultFilterData), - }), + const result = await createFilterMutation.mutateAsync({ + name: createName.trim(), + description: createDescription.trim(), + queryData: JSON.stringify(defaultFilterData), }); - const result = await response.json(); - if (response.ok && result.success) { - // Create the new filter object - const newFilter: KnowledgeFilter = { - id: result.filter.id, - name: createName.trim(), - description: createDescription.trim(), - query_data: JSON.stringify(defaultFilterData), - owner: result.filter.owner, - created_at: result.filter.created_at, - updated_at: result.filter.updated_at, - }; + // Select the new filter from API response + onFilterSelect(result.filter); - // Select the new filter - onFilterSelect(newFilter); - - // Close modal and reset form - setShowCreateModal(false); - setCreateName(""); - setCreateDescription(""); - // Refresh list to include newly created filter - refetch(); - } else { - console.error("Failed to create knowledge filter:", result.error); - } + // Close modal and reset form + setShowCreateModal(false); + setCreateName(""); + setCreateDescription(""); } catch (error) { console.error("Error creating knowledge filter:", error); } finally { @@ -169,25 +115,6 @@ export function KnowledgeFilterList({ return JSON.parse(queryData) as ParsedQueryData; }; - const getFilterSummary = (filter: KnowledgeFilter): string => { - try { - const parsed = JSON.parse(filter.query_data) as ParsedQueryData; - const parts = []; - - if (parsed.query) parts.push(`"${parsed.query}"`); - if (parsed.filters.data_sources.length > 0) - parts.push(`${parsed.filters.data_sources.length} sources`); - if (parsed.filters.document_types.length > 0) - parts.push(`${parsed.filters.document_types.length} types`); - if (parsed.filters.owners.length > 0) - parts.push(`${parsed.filters.owners.length} owners`); - - return parts.join(" • ") || "No filters"; - } catch { - return "Invalid filter"; - } - }; - return ( <>
@@ -199,6 +126,7 @@ export function KnowledgeFilterList({ variant="ghost" size="sm" onClick={handleCreateNew} + title="Create New Filter" className="h-8 px-3" > @@ -255,14 +183,6 @@ export function KnowledgeFilterList({
- )) )} @@ -277,62 +197,60 @@ export function KnowledgeFilterList({ knowledge base. -
-
-
- - setCreateName(e.target.value)} - className="mt-1" - /> -
-
- -