mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-02-04 01:25:07 +08:00
### What problem does this PR solve? Fixes: Bugs fixed - Removed invalid code, - Modified the user center style, - Added an automatic data source parsing switch. ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
157
web/src/pages/user-setting/mcp/index.tsx
Normal file
157
web/src/pages/user-setting/mcp/index.tsx
Normal file
@ -0,0 +1,157 @@
|
||||
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-medium">
|
||||
{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}
|
||||
></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={showEditModal('')}>
|
||||
<Plus className="size-3.5" /> {t('mcp.addMCP')}
|
||||
</Button>
|
||||
<Button onClick={showImportModal}>
|
||||
<Download className="size-3.5" />
|
||||
{t('mcp.import')}
|
||||
</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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user