amaniquery-frontend / src /components /KnowledgeBaseSelector.tsx
Benaah's picture
Upload folder using huggingface_hub
6a059d3 verified
Raw
History Blame Contribute Delete
5.67 kB
"use client"
/**
* Knowledge Base Selector - WeKnora Integration
*
* Allows users to select which knowledge bases to query
*/
import { useState } from "react"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover"
import { Checkbox } from "@/components/ui/checkbox"
import { Label } from "@/components/ui/label"
import { Database, Scale, Newspaper, FileText, ChevronDown, Check } from "lucide-react"
import { cn } from "@/lib/utils"
interface KnowledgeBase {
id: string
name: string
description: string
icon: React.ReactNode
docCount?: number
color: string
}
// Real namespaces from vector store
const KNOWLEDGE_BASES: KnowledgeBase[] = [
{
id: "kenya_law",
name: "Kenya Law",
description: "Constitution, Acts, Bills, Case Law",
icon: <Scale className="h-4 w-4" />,
color: "bg-blue-500"
},
{
id: "kenya_news",
name: "Kenya News",
description: "Current affairs and news articles",
icon: <Newspaper className="h-4 w-4" />,
color: "bg-green-500"
},
{
id: "parliament",
name: "Parliament",
description: "Bills, Hansard, Committee Reports",
icon: <FileText className="h-4 w-4" />,
color: "bg-purple-500"
},
{
id: "general",
name: "General",
description: "General knowledge base",
icon: <Database className="h-4 w-4" />,
color: "bg-orange-500"
}
]
interface KnowledgeBaseSelectorProps {
selected: string[]
onChange: (selected: string[]) => void
className?: string
}
export function KnowledgeBaseSelector({
selected,
onChange,
className
}: KnowledgeBaseSelectorProps) {
const [open, setOpen] = useState(false)
const toggleKnowledgeBase = (id: string) => {
if (selected.includes(id)) {
onChange(selected.filter(s => s !== id))
} else {
onChange([...selected, id])
}
}
const selectAll = () => {
onChange(KNOWLEDGE_BASES.map(kb => kb.id))
}
const clearAll = () => {
onChange([])
}
const selectedKBs = KNOWLEDGE_BASES.filter(kb => selected.includes(kb.id))
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
variant="outline"
role="combobox"
aria-expanded={open}
className={cn("justify-between min-w-[200px]", className)}
>
<div className="flex items-center gap-2">
<Database className="h-4 w-4 text-muted-foreground" />
<span>
{selected.length === 0
? "Select sources"
: selected.length === KNOWLEDGE_BASES.length
? "All sources"
: `${selected.length} sources`}
</span>
</div>
<ChevronDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-[320px] p-0" align="start">
<div className="border-b p-3 flex items-center justify-between">
<span className="text-sm font-medium">Knowledge Bases</span>
<div className="flex gap-2">
<Button variant="ghost" size="sm" onClick={selectAll}>
All
</Button>
<Button variant="ghost" size="sm" onClick={clearAll}>
Clear
</Button>
</div>
</div>
<div className="p-2 space-y-1">
{KNOWLEDGE_BASES.map((kb) => {
const isSelected = selected.includes(kb.id)
return (
<div
key={kb.id}
className={cn(
"flex items-center gap-3 p-2 rounded-md cursor-pointer transition-colors",
isSelected ? "bg-accent" : "hover:bg-accent/50"
)}
onClick={() => toggleKnowledgeBase(kb.id)}
>
<Checkbox
checked={isSelected}
onCheckedChange={() => toggleKnowledgeBase(kb.id)}
/>
<div className={cn("p-1.5 rounded", kb.color, "text-white")}>
{kb.icon}
</div>
<div className="flex-1">
<div className="flex items-center gap-2">
<Label className="font-medium cursor-pointer">{kb.name}</Label>
{kb.docCount && (
<Badge variant="secondary" className="text-xs">
{(kb.docCount / 1000).toFixed(0)}k docs
</Badge>
)}
</div>
<p className="text-xs text-muted-foreground">{kb.description}</p>
</div>
{isSelected && <Check className="h-4 w-4 text-primary" />}
</div>
)
})}
</div>
{selectedKBs.length > 0 && (
<div className="border-t p-2">
<div className="flex flex-wrap gap-1">
{selectedKBs.map(kb => (
<Badge
key={kb.id}
variant="secondary"
className="text-xs cursor-pointer"
onClick={() => toggleKnowledgeBase(kb.id)}
>
{kb.name} ×
</Badge>
))}
</div>
</div>
)}
</PopoverContent>
</Popover>
)
}
export default KnowledgeBaseSelector