import { useState, useEffect, useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@/components/ui/card'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, } from '@/components/ui/dialog'; import KBForm from '@/app/home/knowledge/components/kb-form/KBForm'; import KBDoc from '@/app/home/knowledge/components/kb-docs/KBDoc'; import KBRetrieveGeneric from '@/app/home/knowledge/components/kb-retrieve/KBRetrieveGeneric'; import { httpClient } from '@/app/infra/http/HttpClient'; import { useSidebarData } from '@/app/home/components/home-sidebar/SidebarDataContext'; import { useTranslation } from 'react-i18next'; import { KnowledgeBase } from '@/app/infra/entities/api'; import { CustomApiError } from '@/app/infra/entities/common'; import { toast } from 'sonner'; import { FileText, FolderOpen, Search, Trash2 } from 'lucide-react'; export default function KBDetailContent({ id }: { id: string }) { const isCreateMode = id === 'new'; const navigate = useNavigate(); const { t } = useTranslation(); const { refreshKnowledgeBases, knowledgeBases, setDetailEntityName } = useSidebarData(); // Set breadcrumb entity name useEffect(() => { if (isCreateMode) { setDetailEntityName(t('knowledge.createKnowledgeBase')); } else { const kb = knowledgeBases.find((k) => k.id === id); setDetailEntityName(kb?.name ?? id); } return () => setDetailEntityName(null); }, [id, isCreateMode, knowledgeBases, setDetailEntityName, t]); const [activeTab, setActiveTab] = useState('metadata'); const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); const [kbInfo, setKbInfo] = useState(null); const [formDirty, setFormDirty] = useState(false); const loadKbInfo = useCallback( async (kbId: string) => { try { const resp = await httpClient.getKnowledgeBase(kbId); setKbInfo(resp.base); } catch (e) { console.error('Failed to load KB info:', e); toast.error( t('knowledge.loadKnowledgeBaseFailed') + (e as CustomApiError).msg, ); } }, [t], ); // Load KB info for determining capabilities (e.g. doc_ingestion) useEffect(() => { if (!isCreateMode) { loadKbInfo(id); } }, [id, isCreateMode, loadKbInfo]); const hasDocumentCapability = (): boolean => { if (!kbInfo || !kbInfo.knowledge_engine) return false; return ( kbInfo.knowledge_engine.capabilities?.includes('doc_ingestion') ?? false ); }; function handleKbDeleted() { refreshKnowledgeBases(); navigate('/home/knowledge'); } function handleNewKbCreated(newKbId: string) { refreshKnowledgeBases(); navigate(`/home/knowledge?id=${encodeURIComponent(newKbId)}`); } function handleKbUpdated() { refreshKnowledgeBases(); loadKbInfo(id); } async function confirmDelete() { try { await httpClient.deleteKnowledgeBase(id); setShowDeleteConfirm(false); handleKbDeleted(); } catch (e) { toast.error( t('knowledge.deleteKnowledgeBaseFailed') + (e as CustomApiError).msg, ); } } const retrieveFunction = async (kbId: string, query: string) => { return await httpClient.retrieveKnowledgeBase(kbId, query); }; // ==================== Create Mode ==================== if (isCreateMode) { return (

{t('knowledge.createKnowledgeBase')}

); } // ==================== Edit Mode ==================== return ( <>
{/* Sticky Header: title + save button */}

{t('knowledge.editKnowledgeBase')}

{/* Horizontal Tabs */} {t('knowledge.metadata')} {hasDocumentCapability() && ( {t('knowledge.documents')} )} {t('knowledge.retrieve')} {/* Tab: Metadata */}
{/* Danger Zone Card */} {t('knowledge.dangerZone')} {t('knowledge.dangerZoneDescription')}

{t('knowledge.deleteKbAction')}

{t('knowledge.deleteKbHint')}

{/* Tab: Documents */} {hasDocumentCapability() && ( )} {/* Tab: Retrieve */}
{/* Delete confirmation dialog */} {t('common.confirmDelete')} {t('knowledge.deleteKnowledgeBaseConfirmation')}
{t('knowledge.deleteKnowledgeBaseConfirmation')}
); }