mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-12 16:56:02 +00:00
feat(fe): complete kb ui
This commit is contained in:
@@ -4,20 +4,31 @@ import { KnowledgeBaseFile } from '@/app/infra/entities/api';
|
||||
import { columns, DocumentFile } from './documents/columns';
|
||||
import { DataTable } from './documents/data-table';
|
||||
import FileUploadZone from './FileUploadZone';
|
||||
import { toast } from 'sonner';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function KBDoc({ kbId }: { kbId: string }) {
|
||||
const [documentsList, setDocumentsList] = useState<DocumentFile[]>([]);
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
getDocumentsList();
|
||||
}, []);
|
||||
|
||||
const intervalId = setInterval(() => {
|
||||
getDocumentsList();
|
||||
}, 5000);
|
||||
|
||||
return () => {
|
||||
clearInterval(intervalId);
|
||||
};
|
||||
}, [kbId]);
|
||||
|
||||
async function getDocumentsList() {
|
||||
const resp = await httpClient.getKnowledgeBaseFiles(kbId);
|
||||
setDocumentsList(
|
||||
resp.files.map((file: KnowledgeBaseFile) => {
|
||||
return {
|
||||
id: file.file_id,
|
||||
id: file.id,
|
||||
name: file.file_name,
|
||||
status: file.status,
|
||||
};
|
||||
@@ -35,6 +46,19 @@ export default function KBDoc({ kbId }: { kbId: string }) {
|
||||
console.error('Upload failed:', error);
|
||||
};
|
||||
|
||||
const handleDelete = (id: string) => {
|
||||
httpClient
|
||||
.deleteKnowledgeBaseFile(kbId, id)
|
||||
.then(() => {
|
||||
getDocumentsList();
|
||||
toast.success(t('knowledge.documentsTab.fileDeleteSuccess'));
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Delete failed:', error);
|
||||
toast.error(t('knowledge.documentsTab.fileDeleteFailed'));
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container mx-auto py-2">
|
||||
<FileUploadZone
|
||||
@@ -42,7 +66,7 @@ export default function KBDoc({ kbId }: { kbId: string }) {
|
||||
onUploadSuccess={handleUploadSuccess}
|
||||
onUploadError={handleUploadError}
|
||||
/>
|
||||
<DataTable columns={columns()} data={documentsList} />
|
||||
<DataTable columns={columns(handleDelete)} data={documentsList} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
'use client';
|
||||
|
||||
import { ColumnDef } from '@tanstack/react-table';
|
||||
import { MoreHorizontal } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export type DocumentFile = {
|
||||
@@ -9,7 +19,9 @@ export type DocumentFile = {
|
||||
status: string;
|
||||
};
|
||||
|
||||
export const columns = (): ColumnDef<DocumentFile>[] => {
|
||||
export const columns = (
|
||||
onDelete: (id: string) => void,
|
||||
): ColumnDef<DocumentFile>[] => {
|
||||
const { t } = useTranslation();
|
||||
return [
|
||||
{
|
||||
@@ -20,5 +32,33 @@ export const columns = (): ColumnDef<DocumentFile>[] => {
|
||||
accessorKey: 'status',
|
||||
header: t('knowledge.documentsTab.status'),
|
||||
},
|
||||
{
|
||||
id: 'actions',
|
||||
cell: ({ row }) => {
|
||||
const document = row.original;
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" className="h-8 w-8 p-0">
|
||||
<span className="sr-only">
|
||||
{t('knowledge.documentsTab.actions')}
|
||||
</span>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuLabel>
|
||||
{t('knowledge.documentsTab.actions')}
|
||||
</DropdownMenuLabel>
|
||||
|
||||
<DropdownMenuItem onClick={() => onDelete(document.id)}>
|
||||
{t('knowledge.documentsTab.delete')}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
@@ -155,7 +155,7 @@ export interface ApiRespKnowledgeBaseFiles {
|
||||
}
|
||||
|
||||
export interface KnowledgeBaseFile {
|
||||
file_id: string;
|
||||
id: string;
|
||||
file_name: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
@@ -463,9 +463,7 @@ class HttpClient {
|
||||
uuid: string,
|
||||
file_id: string,
|
||||
): Promise<object> {
|
||||
return this.post(`/api/v1/knowledge/bases/${uuid}/files`, {
|
||||
file_id,
|
||||
});
|
||||
return this.delete(`/api/v1/knowledge/bases/${uuid}/files/${file_id}`);
|
||||
}
|
||||
|
||||
public getKnowledgeBaseFiles(
|
||||
@@ -474,6 +472,13 @@ class HttpClient {
|
||||
return this.get(`/api/v1/knowledge/bases/${uuid}/files`);
|
||||
}
|
||||
|
||||
public deleteKnowledgeBaseFile(
|
||||
uuid: string,
|
||||
file_id: string,
|
||||
): Promise<object> {
|
||||
return this.delete(`/api/v1/knowledge/bases/${uuid}/files/${file_id}`);
|
||||
}
|
||||
|
||||
// ============ Plugins API ============
|
||||
public getPlugins(): Promise<ApiRespPlugins> {
|
||||
return this.get('/api/v1/plugins');
|
||||
|
||||
Reference in New Issue
Block a user