mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 12:32:30 +08:00
### What problem does this PR solve? Fix: Modify the personal center style ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
159 lines
5.2 KiB
TypeScript
159 lines
5.2 KiB
TypeScript
import { CardContainer } from '@/components/card-container';
|
|
import { ConfirmDeleteDialog } from '@/components/confirm-delete-dialog';
|
|
import Spotlight from '@/components/spotlight';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Checkbox } from '@/components/ui/checkbox';
|
|
import { SearchInput } from '@/components/ui/input';
|
|
import { Label } from '@/components/ui/label';
|
|
import { RAGFlowPagination } from '@/components/ui/ragflow-pagination';
|
|
import { useListMcpServer } from '@/hooks/use-mcp-request';
|
|
import { pick } from 'lodash';
|
|
import {
|
|
Download,
|
|
LayoutList,
|
|
ListChecks,
|
|
Plus,
|
|
Trash2,
|
|
Upload,
|
|
} from 'lucide-react';
|
|
import { useCallback, useState } from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { ProfileSettingWrapperCard } from '../components/user-setting-header';
|
|
import { EditMcpDialog } from './edit-mcp-dialog';
|
|
import { ImportMcpDialog } from './import-mcp-dialog';
|
|
import { McpCard } from './mcp-card';
|
|
import { useBulkOperateMCP } from './use-bulk-operate-mcp';
|
|
import { useEditMcp } from './use-edit-mcp';
|
|
import { useImportMcp } from './use-import-mcp';
|
|
|
|
export default function McpServer() {
|
|
const { data, setPagination, searchString, handleInputChange, pagination } =
|
|
useListMcpServer();
|
|
const { editVisible, showEditModal, hideEditModal, handleOk, id, loading } =
|
|
useEditMcp();
|
|
const {
|
|
selectedList,
|
|
handleSelectChange,
|
|
handleDelete,
|
|
handleExportMcp,
|
|
handleSelectAll,
|
|
} = useBulkOperateMCP(data.mcp_servers);
|
|
const { t } = useTranslation();
|
|
const { importVisible, showImportModal, hideImportModal, onImportOk } =
|
|
useImportMcp();
|
|
|
|
const [isSelectionMode, setSelectionMode] = useState(false);
|
|
|
|
const handlePageChange = useCallback(
|
|
(page: number, pageSize?: number) => {
|
|
setPagination({ page, pageSize });
|
|
},
|
|
[setPagination],
|
|
);
|
|
|
|
const switchSelectionMode = useCallback(() => {
|
|
setSelectionMode((prev) => !prev);
|
|
}, []);
|
|
|
|
return (
|
|
<ProfileSettingWrapperCard
|
|
header={
|
|
<>
|
|
<div className="text-text-primary text-2xl font-semibold">
|
|
{t('mcp.mcpServers')}
|
|
</div>
|
|
<section className="flex items-center justify-between">
|
|
<div className="text-text-secondary">
|
|
{t('mcp.customizeTheListOfMcpServers')}
|
|
</div>
|
|
<div className="flex gap-5">
|
|
<SearchInput
|
|
className="w-40"
|
|
value={searchString}
|
|
onChange={handleInputChange}
|
|
placeholder={t('common.search')}
|
|
></SearchInput>
|
|
<Button variant={'secondary'} onClick={switchSelectionMode}>
|
|
{isSelectionMode ? (
|
|
<ListChecks className="size-3.5" />
|
|
) : (
|
|
<LayoutList className="size-3.5" />
|
|
)}
|
|
{t(`mcp.${isSelectionMode ? 'exitBulkManage' : 'bulkManage'}`)}
|
|
</Button>
|
|
<Button variant={'secondary'} onClick={showImportModal}>
|
|
<Download className="size-3.5" />
|
|
{t('mcp.import')}
|
|
</Button>
|
|
<Button onClick={showEditModal('')}>
|
|
<Plus className="size-3.5" /> {t('mcp.addMCP')}
|
|
</Button>
|
|
</div>
|
|
</section>
|
|
</>
|
|
}
|
|
>
|
|
{isSelectionMode && (
|
|
<section className="pb-5 flex items-center">
|
|
<Checkbox id="all" onCheckedChange={handleSelectAll} />
|
|
<Label
|
|
className="pl-2 text-text-primary cursor-pointer"
|
|
htmlFor="all"
|
|
>
|
|
{t('common.selectAll')}
|
|
</Label>
|
|
<span className="text-text-secondary pr-10 pl-5">
|
|
{t('mcp.selected')} {selectedList.length}
|
|
</span>
|
|
<div className="flex gap-10 items-center">
|
|
<Button variant={'secondary'} onClick={handleExportMcp}>
|
|
<Upload className="size-3.5"></Upload>
|
|
{t('mcp.export')}
|
|
</Button>
|
|
<ConfirmDeleteDialog onOk={handleDelete}>
|
|
<Button variant={'danger'}>
|
|
<Trash2 className="size-3.5 cursor-pointer" />
|
|
{t('common.delete')}
|
|
</Button>
|
|
</ConfirmDeleteDialog>
|
|
</div>
|
|
</section>
|
|
)}
|
|
<CardContainer>
|
|
{data.mcp_servers.map((item) => (
|
|
<McpCard
|
|
key={item.id}
|
|
data={item}
|
|
selectedList={selectedList}
|
|
handleSelectChange={handleSelectChange}
|
|
showEditModal={showEditModal}
|
|
isSelectionMode={isSelectionMode}
|
|
></McpCard>
|
|
))}
|
|
</CardContainer>
|
|
<div className="mt-8">
|
|
<RAGFlowPagination
|
|
{...pick(pagination, 'current', 'pageSize')}
|
|
total={pagination.total || 0}
|
|
onChange={handlePageChange}
|
|
></RAGFlowPagination>
|
|
</div>
|
|
{editVisible && (
|
|
<EditMcpDialog
|
|
hideModal={hideEditModal}
|
|
onOk={handleOk}
|
|
id={id}
|
|
loading={loading}
|
|
></EditMcpDialog>
|
|
)}
|
|
{importVisible && (
|
|
<ImportMcpDialog
|
|
hideModal={hideImportModal}
|
|
onOk={onImportOk}
|
|
></ImportMcpDialog>
|
|
)}
|
|
<Spotlight />
|
|
</ProfileSettingWrapperCard>
|
|
);
|
|
}
|