2025-03-04 07:22:05 +08:00
|
|
|
import React, { useState, useEffect } from 'react';
|
|
|
|
import { useParams, useNavigate } from 'react-router-dom';
|
2025-03-07 23:59:53 +08:00
|
|
|
import { useSelector, useDispatch } from 'react-redux';
|
2025-03-08 07:05:33 +08:00
|
|
|
import { showNotification } from '../../../store/notification.slice';
|
2025-03-20 08:22:02 +08:00
|
|
|
import { fetchKnowledgeBases } from '../../../store/knowledgeBase/knowledgeBase.thunks';
|
2025-03-08 07:05:33 +08:00
|
|
|
import SvgIcon from '../../../components/SvgIcon';
|
|
|
|
import DatasetTab from './DatasetTab';
|
|
|
|
import SettingsTab from './SettingsTab';
|
2025-03-04 07:22:05 +08:00
|
|
|
|
|
|
|
export default function KnowledgeBaseDetail() {
|
|
|
|
const { id, tab } = useParams();
|
|
|
|
const navigate = useNavigate();
|
2025-03-07 23:59:53 +08:00
|
|
|
const dispatch = useDispatch();
|
2025-03-04 07:22:05 +08:00
|
|
|
const [activeTab, setActiveTab] = useState(tab === 'settings' ? 'settings' : 'datasets');
|
|
|
|
|
2025-03-07 23:59:53 +08:00
|
|
|
// Get knowledge base details from Redux store
|
2025-03-20 08:22:02 +08:00
|
|
|
const { data, status } = useSelector((state) => state.knowledgeBase.list);
|
|
|
|
const knowledgeBase = data?.items?.find((kb) => kb.id === id);
|
|
|
|
const isLoading = status === 'loading';
|
|
|
|
|
|
|
|
// Fetch knowledge bases if not available
|
|
|
|
useEffect(() => {
|
|
|
|
if (!data?.items?.length && status !== 'loading') {
|
|
|
|
dispatch(fetchKnowledgeBases());
|
|
|
|
}
|
|
|
|
}, [dispatch, data, status]);
|
2025-03-07 23:59:53 +08:00
|
|
|
|
2025-03-04 07:22:05 +08:00
|
|
|
// Update active tab when URL changes
|
|
|
|
useEffect(() => {
|
|
|
|
if (tab) {
|
|
|
|
setActiveTab(tab === 'settings' ? 'settings' : 'datasets');
|
|
|
|
}
|
|
|
|
}, [tab]);
|
|
|
|
|
2025-03-07 23:59:53 +08:00
|
|
|
// If knowledge base not found in Redux store, show notification and redirect
|
|
|
|
useEffect(() => {
|
2025-03-20 08:22:02 +08:00
|
|
|
if (!knowledgeBase && data?.items?.length > 0 && !isLoading) {
|
2025-03-07 23:59:53 +08:00
|
|
|
dispatch(
|
|
|
|
showNotification({
|
|
|
|
message: '未找到知识库,请返回知识库列表',
|
|
|
|
type: 'warning',
|
|
|
|
})
|
|
|
|
);
|
|
|
|
navigate('/knowledge-base');
|
|
|
|
}
|
2025-03-20 08:22:02 +08:00
|
|
|
}, [knowledgeBase, data, isLoading, dispatch, navigate]);
|
2025-03-04 07:22:05 +08:00
|
|
|
|
|
|
|
// Handle tab change
|
|
|
|
const handleTabChange = (tab) => {
|
|
|
|
setActiveTab(tab);
|
|
|
|
navigate(`/knowledge-base/${id}/${tab}`);
|
|
|
|
};
|
|
|
|
|
2025-03-07 23:59:53 +08:00
|
|
|
// Show loading state if knowledge base not loaded yet
|
2025-03-20 08:22:02 +08:00
|
|
|
if (isLoading || !knowledgeBase) {
|
2025-03-07 23:59:53 +08:00
|
|
|
return (
|
|
|
|
<div className='container-fluid px-4 py-5 text-center'>
|
|
|
|
<div className='spinner-border' role='status'>
|
|
|
|
<span className='visually-hidden'>加载中...</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2025-03-04 07:22:05 +08:00
|
|
|
return (
|
|
|
|
<div className='container-fluid px-4'>
|
|
|
|
<div className='row'>
|
|
|
|
{/* Sidebar */}
|
|
|
|
<div className='col-md-3 col-lg-2 border-end'>
|
|
|
|
<div className='py-4'>
|
2025-03-07 23:59:53 +08:00
|
|
|
<div className='h4 mb-3 text-center'>{knowledgeBase.name}</div>
|
2025-03-08 07:05:33 +08:00
|
|
|
<p className='text-center text-muted small mb-4'>
|
2025-03-20 08:22:02 +08:00
|
|
|
{knowledgeBase.desc || ''}
|
2025-03-08 07:05:33 +08:00
|
|
|
</p>
|
2025-03-04 07:22:05 +08:00
|
|
|
|
|
|
|
<hr />
|
|
|
|
|
|
|
|
<nav className='nav flex-column'>
|
|
|
|
<a
|
2025-03-04 08:37:47 +08:00
|
|
|
className={`nav-link link-dark link-underline-light d-flex align-items-center gap-2 ${
|
2025-03-04 07:22:05 +08:00
|
|
|
activeTab === 'datasets' ? 'active bg-light rounded fw-bold' : ''
|
|
|
|
}`}
|
|
|
|
href='#'
|
|
|
|
onClick={(e) => {
|
|
|
|
e.preventDefault();
|
|
|
|
handleTabChange('datasets');
|
|
|
|
}}
|
|
|
|
>
|
2025-03-04 08:37:47 +08:00
|
|
|
<SvgIcon className='dataset' />
|
2025-03-04 07:22:05 +08:00
|
|
|
数据集
|
|
|
|
</a>
|
|
|
|
<a
|
2025-03-04 08:37:47 +08:00
|
|
|
className={`nav-link link-dark link-underline-light d-flex align-items-center gap-1 ${
|
2025-03-04 07:22:05 +08:00
|
|
|
activeTab === 'settings' ? 'active bg-light rounded fw-bold' : ''
|
|
|
|
}`}
|
|
|
|
href='#'
|
|
|
|
onClick={(e) => {
|
|
|
|
e.preventDefault();
|
|
|
|
handleTabChange('settings');
|
|
|
|
}}
|
|
|
|
>
|
2025-03-04 08:37:47 +08:00
|
|
|
<SvgIcon className='setting-fill' />
|
2025-03-04 07:22:05 +08:00
|
|
|
设置
|
|
|
|
</a>
|
|
|
|
</nav>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
{/* Main content */}
|
|
|
|
<div className='col-md-9 col-lg-10'>
|
|
|
|
{/* Render the appropriate tab component */}
|
|
|
|
{activeTab === 'datasets' ? (
|
|
|
|
<DatasetTab knowledgeBase={knowledgeBase} />
|
|
|
|
) : (
|
|
|
|
<SettingsTab knowledgeBase={knowledgeBase} />
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|