Files
TERES_web_frontend/src/pages/knowledge/KnowledgeBaseList.tsx

240 lines
6.9 KiB
TypeScript
Raw Normal View History

import React, { useState, useCallback } from 'react';
import {
Box,
Typography,
TextField,
Select,
MenuItem,
FormControl,
InputLabel,
Button,
InputAdornment,
Pagination,
Stack,
CircularProgress,
} from '@mui/material';
import {
Search as SearchIcon,
Add as AddIcon,
Refresh as RefreshIcon,
} from '@mui/icons-material';
import { useNavigate } from 'react-router-dom';
import { useKnowledgeList } from '@/hooks/knowledge_hooks';
import KnowledgeGridView from '@/components/KnowledgeGridView';
import type { IKnowledge } from '@/interfaces/database/knowledge';
const KnowledgeBaseList: React.FC = () => {
const navigate = useNavigate();
// 搜索和筛选状态
const [searchTerm, setSearchTerm] = useState('');
const [teamFilter, setTeamFilter] = useState('all');
const [currentPage, setCurrentPage] = useState(1);
const pageSize = 12; // 每页显示12个知识库
// 使用knowledge_hooks获取数据
const {
knowledgeBases,
loading,
error,
refresh,
} = useKnowledgeList({
keywords: searchTerm,
page: currentPage,
page_size: pageSize,
});
// 处理搜索
const handleSearch = useCallback((value: string) => {
setSearchTerm(value);
setCurrentPage(1); // 搜索时重置到第一页
}, []);
// 处理团队筛选
const handleTeamFilterChange = useCallback((value: string) => {
setTeamFilter(value);
setCurrentPage(1); // 筛选时重置到第一页
}, []);
// 处理分页变化
const handlePageChange = useCallback((_: React.ChangeEvent<unknown>, page: number) => {
setCurrentPage(page);
}, []);
// 处理刷新
const handleRefresh = useCallback(() => {
refresh();
}, [refresh]);
// 处理创建知识库
const handleCreateKnowledge = useCallback(() => {
navigate('/knowledge/create');
}, [navigate]);
// 处理编辑知识库
const handleEditKnowledge = useCallback((kb: IKnowledge) => {
navigate(`/knowledge/${kb.id}/edit`);
}, [navigate]);
// 处理查看知识库详情
const handleViewKnowledge = useCallback((kb: IKnowledge) => {
navigate(`/knowledge/${kb.id}`);
}, [navigate]);
// 处理删除知识库
const handleDeleteKnowledge = useCallback((kb: IKnowledge) => {
// TODO: 实现删除逻辑
console.log('删除知识库:', kb.id);
}, []);
// 根据团队筛选过滤知识库
const filteredKnowledgeBases = React.useMemo(() => {
if (!knowledgeBases) return [];
if (teamFilter === 'all') {
return knowledgeBases;
}
return knowledgeBases.filter(kb => {
if (teamFilter === 'me') return kb.permission === 'me';
if (teamFilter === 'team') return kb.permission === 'team';
return true;
});
}, [knowledgeBases, teamFilter]);
// 计算总页数
const totalPages = Math.ceil((knowledgeBases?.length || 0) / pageSize);
return (
<Box sx={{ p: 3 }}>
{/* 页面标题 */}
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 3 }}>
<Typography variant="h4" fontWeight={600}>
</Typography>
<Button
variant="contained"
startIcon={<AddIcon />}
onClick={handleCreateKnowledge}
sx={{ borderRadius: 2 }}
>
</Button>
</Box>
{/* 搜索和筛选区域 */}
<Box sx={{ display: 'flex', gap: 2, mb: 3, alignItems: 'center' }}>
<TextField
placeholder="搜索知识库..."
value={searchTerm}
onChange={(e) => handleSearch(e.target.value)}
sx={{ flex: 1, maxWidth: 400 }}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
/>
<FormControl sx={{ minWidth: 120 }}>
<InputLabel></InputLabel>
<Select
value={teamFilter}
label="团队筛选"
onChange={(e) => handleTeamFilterChange(e.target.value)}
>
<MenuItem value="all"></MenuItem>
<MenuItem value="me"></MenuItem>
<MenuItem value="team"></MenuItem>
</Select>
</FormControl>
<Button
variant="outlined"
startIcon={<RefreshIcon />}
onClick={handleRefresh}
disabled={loading}
>
</Button>
</Box>
{/* 错误提示 */}
{error && (
<Box sx={{ mb: 3, p: 2, bgcolor: 'error.light', borderRadius: 1 }}>
<Typography color="error">
: {error}
</Typography>
</Box>
)}
{/* 加载状态 */}
{loading && (
<Box sx={{ display: 'flex', justifyContent: 'center', py: 4 }}>
<CircularProgress />
</Box>
)}
{/* 知识库列表 */}
{!loading && (
<>
<KnowledgeGridView
knowledgeBases={filteredKnowledgeBases}
onEdit={handleEditKnowledge}
onDelete={handleDeleteKnowledge}
onView={handleViewKnowledge}
loading={loading}
/>
{/* 分页组件 */}
{totalPages > 1 && (
<Box sx={{ display: 'flex', justifyContent: 'center', mt: 4 }}>
<Stack spacing={2}>
<Pagination
count={totalPages}
page={currentPage}
onChange={handlePageChange}
color="primary"
size="large"
showFirstButton
showLastButton
/>
<Typography variant="body2" color="text.secondary" textAlign="center">
{knowledgeBases?.length || 0} {currentPage} {totalPages}
</Typography>
</Stack>
</Box>
)}
{/* 空状态 */}
{!loading && filteredKnowledgeBases.length === 0 && !error && (
<Box sx={{ textAlign: 'center', py: 8 }}>
<Typography variant="h6" color="text.secondary" gutterBottom>
{searchTerm || teamFilter !== 'all' ? '没有找到匹配的知识库' : '暂无知识库'}
</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
{searchTerm || teamFilter !== 'all'
? '尝试调整搜索条件或筛选器'
: '创建您的第一个知识库开始使用'
}
</Typography>
{(!searchTerm && teamFilter === 'all') && (
<Button
variant="contained"
startIcon={<AddIcon />}
onClick={handleCreateKnowledge}
>
</Button>
)}
</Box>
)}
</>
)}
</Box>
);
};
export default KnowledgeBaseList;