- Split monolithic 922-line TokensTable.js into modular components: * useTokensData.js: Custom hook for centralized state and logic management * TokensColumnDefs.js: Column definitions and rendering functions * TokensTable.jsx: Pure table component for rendering * TokensActions.jsx: Actions area (add, copy, delete tokens) * TokensFilters.jsx: Search form component with keyword and token filters * TokensDescription.jsx: Description area with compact mode toggle * index.jsx: Main orchestrator component - Features preserved: * Token status management with switch controls * Quota progress bars and visual indicators * Model limitations display with vendor avatars * IP restrictions handling and display * Chat integrations with dropdown menu * Batch operations (copy, delete) with confirmations * Key visibility toggle and copy functionality * Compact mode for responsive layouts * Search and filtering capabilities * Pagination and loading states - Improvements: * Better separation of concerns * Enhanced reusability and testability * Simplified maintenance and debugging * Consistent modular architecture pattern * Performance optimizations with useMemo * Backward compatibility maintained This refactoring follows the same successful pattern used for LogsTable, MjLogsTable, and TaskLogsTable, significantly improving code maintainability while preserving all existing functionality.
113 lines
2.7 KiB
JavaScript
113 lines
2.7 KiB
JavaScript
import React from 'react';
|
|
import { Button, Modal, Space } from '@douyinfe/semi-ui';
|
|
import { showError } from '../../../helpers';
|
|
|
|
const TokensActions = ({
|
|
selectedKeys,
|
|
setEditingToken,
|
|
setShowEdit,
|
|
batchCopyTokens,
|
|
batchDeleteTokens,
|
|
copyText,
|
|
t,
|
|
}) => {
|
|
// Handle copy selected tokens with options
|
|
const handleCopySelectedTokens = () => {
|
|
if (selectedKeys.length === 0) {
|
|
showError(t('请至少选择一个令牌!'));
|
|
return;
|
|
}
|
|
|
|
Modal.info({
|
|
title: t('复制令牌'),
|
|
icon: null,
|
|
content: t('请选择你的复制方式'),
|
|
footer: (
|
|
<Space>
|
|
<Button
|
|
type='tertiary'
|
|
onClick={async () => {
|
|
let content = '';
|
|
for (let i = 0; i < selectedKeys.length; i++) {
|
|
content +=
|
|
selectedKeys[i].name + ' sk-' + selectedKeys[i].key + '\n';
|
|
}
|
|
await copyText(content);
|
|
Modal.destroyAll();
|
|
}}
|
|
>
|
|
{t('名称+密钥')}
|
|
</Button>
|
|
<Button
|
|
onClick={async () => {
|
|
let content = '';
|
|
for (let i = 0; i < selectedKeys.length; i++) {
|
|
content += 'sk-' + selectedKeys[i].key + '\n';
|
|
}
|
|
await copyText(content);
|
|
Modal.destroyAll();
|
|
}}
|
|
>
|
|
{t('仅密钥')}
|
|
</Button>
|
|
</Space>
|
|
),
|
|
});
|
|
};
|
|
|
|
// Handle delete selected tokens with confirmation
|
|
const handleDeleteSelectedTokens = () => {
|
|
if (selectedKeys.length === 0) {
|
|
showError(t('请至少选择一个令牌!'));
|
|
return;
|
|
}
|
|
|
|
Modal.confirm({
|
|
title: t('批量删除令牌'),
|
|
content: (
|
|
<div>
|
|
{t('确定要删除所选的 {{count}} 个令牌吗?', { count: selectedKeys.length })}
|
|
</div>
|
|
),
|
|
onOk: () => batchDeleteTokens(),
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div className="flex flex-wrap gap-2 w-full md:w-auto order-2 md:order-1">
|
|
<Button
|
|
type="primary"
|
|
className="flex-1 md:flex-initial"
|
|
onClick={() => {
|
|
setEditingToken({
|
|
id: undefined,
|
|
});
|
|
setShowEdit(true);
|
|
}}
|
|
size="small"
|
|
>
|
|
{t('添加令牌')}
|
|
</Button>
|
|
|
|
<Button
|
|
type='tertiary'
|
|
className="flex-1 md:flex-initial"
|
|
onClick={handleCopySelectedTokens}
|
|
size="small"
|
|
>
|
|
{t('复制所选令牌')}
|
|
</Button>
|
|
|
|
<Button
|
|
type='danger'
|
|
className="w-full md:w-auto"
|
|
onClick={handleDeleteSelectedTokens}
|
|
size="small"
|
|
>
|
|
{t('删除所选令牌')}
|
|
</Button>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default TokensActions;
|