import { Ellipsis, Files, FlaskConical, Pencil, Plus, Trash2 } from 'lucide-react'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useNavigate, useParams } from 'react-router-dom'; import type { KnowledgeBaseView } from '@/api'; import { CreateCredentialDialog } from '@/components/dialog/CreateCredentialDialog.tsx'; import { CreateKnowledgeBaseDialog } from '@/components/dialog/CreateKnowledgeBaseDialog.tsx'; import { DeleteDialog } from '@/components/dialog/DeleteDialog.tsx'; import { EditKnowledgeBaseDialog } from '@/components/dialog/EditKnowledgeBaseDialog.tsx'; import { KnowledgeSearchDrawer } from '@/components/drawer/KnowledgeSearchDrawer.tsx'; import { KnowledgeDocumentsPanel } from '@/components/knowledge/KnowledgeDocumentsPanel.tsx'; import { Button } from '@/components/ui/button.tsx'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu.tsx'; import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, } from '@/components/ui/empty.tsx'; import { Separator } from '@/components/ui/separator.tsx'; import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarMenu, SidebarMenuAction, SidebarMenuButton, SidebarMenuItem, } from '@/components/ui/sidebar.tsx'; import { useKnowledgeBases } from '@/hooks/useKnowledgeBases.ts'; interface DetailPanelProps { knowledgeBase?: KnowledgeBaseView; onTest?: () => void; } function DetailPanel({ knowledgeBase, onTest }: DetailPanelProps) { const { t } = useTranslation(); if (!knowledgeBase) { return (
{t('knowledge.selectHint')} {t('knowledge.selectHintDescription')}
); } return (
{/* Header */}

{knowledgeBase.name}

{knowledgeBase.description ? (

{knowledgeBase.description}

) : null}
{/* Documents */}
); } export const KnowledgePage = () => { const navigate = useNavigate(); const { kbId: urlKbId } = useParams<{ kbId?: string }>(); const { t } = useTranslation(); const { knowledgeBases, remove, refetch } = useKnowledgeBases(); const [selectedKbId, setSelectedKbId] = useState(urlKbId); const [createDialogOpen, setCreateDialogOpen] = useState(false); const [credentialOpen, setCredentialOpen] = useState(false); const [credentialRefetchTrigger, setCredentialRefetchTrigger] = useState(0); const [editTarget, setEditTarget] = useState(null); const [deleteTarget, setDeleteTarget] = useState(null); const [testOpen, setTestOpen] = useState(false); const selectedKb = knowledgeBases.find((kb) => kb.id === selectedKbId); const handleCreated = async (knowledgeBaseId: string) => { await refetch(); setSelectedKbId(knowledgeBaseId); navigate(`/knowledge/${knowledgeBaseId}`); }; const handleConfirmDelete = async () => { if (!deleteTarget) return; const id = deleteTarget.id; await remove(id); await refetch(); if (selectedKbId === id) { setSelectedKbId(undefined); navigate('/knowledge'); } }; return (
{t('common.knowledge')}
{t('knowledge.subtitle')}
{t('knowledge.list.label')} {knowledgeBases.length === 0 ? ( {t('knowledge.list.emptyTitle')} {t('knowledge.list.emptyDescription')} ) : ( {knowledgeBases.map((kb) => { return ( { setSelectedKbId(kb.id); navigate(`/knowledge/${kb.id}`); }} > {kb.name} setEditTarget(kb)} > {t('common.edit')} setDeleteTarget(kb)} > {t('common.delete')} ); })} )}
setTestOpen(true)} />
setCredentialOpen(true)} credentialRefetchTrigger={credentialRefetchTrigger} /> setCredentialRefetchTrigger((n) => n + 1)} /> { if (!open) setEditTarget(null); }} knowledgeBase={editTarget} onUpdated={() => refetch()} /> { if (!open) setDeleteTarget(null); }} title={t('dialog-knowledge-base-delete.title')} description={t('dialog-knowledge-base-delete.description', { name: deleteTarget?.name ?? '', })} onConfirm={handleConfirmDelete} /> {selectedKb && ( )}
); };