import PropTypes from 'prop-types'; import { useState } from 'react'; import { useSelector } from 'react-redux'; import { Popover, TableRow, MenuItem, TableCell, IconButton, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Button, Tooltip, Stack, ButtonGroup } from '@mui/material'; import TableSwitch from 'ui-component/Switch'; import { renderQuota, showSuccess, timestamp2string } from 'utils/common'; import { IconDotsVertical, IconEdit, IconTrash, IconCaretDownFilled } from '@tabler/icons-react'; const COPY_OPTIONS = [ { key: 'next', text: 'ChatGPT Next', url: 'https://chat.oneapi.pro/#/?settings={"key":"sk-{key}","url":"{serverAddress}"}', encode: false }, { key: 'ama', text: 'BotGem', url: 'ama://set-api-key?server={serverAddress}&key=sk-{key}', encode: true }, { key: 'opencat', text: 'OpenCat', url: 'opencat://team/join?domain={serverAddress}&token=sk-{key}', encode: true } ]; function replacePlaceholders(text, key, serverAddress) { return text.replace('{key}', key).replace('{serverAddress}', serverAddress); } function createMenu(menuItems) { return ( <> {menuItems.map((menuItem, index) => ( {menuItem.icon} {menuItem.text} ))} ); } export default function TokensTableRow({ item, manageToken, handleOpenModal, setModalTokenId }) { const [open, setOpen] = useState(null); const [menuItems, setMenuItems] = useState(null); const [openDelete, setOpenDelete] = useState(false); const [statusSwitch, setStatusSwitch] = useState(item.status); const siteInfo = useSelector((state) => state.siteInfo); const handleDeleteOpen = () => { handleCloseMenu(); setOpenDelete(true); }; const handleDeleteClose = () => { setOpenDelete(false); }; const handleOpenMenu = (event, type) => { switch (type) { case 'copy': setMenuItems(copyItems); break; case 'link': setMenuItems(linkItems); break; default: setMenuItems(actionItems); } setOpen(event.currentTarget); }; const handleCloseMenu = () => { setOpen(null); }; const handleStatus = async () => { const switchVlue = statusSwitch === 1 ? 2 : 1; const { success } = await manageToken(item.id, 'status', switchVlue); if (success) { setStatusSwitch(switchVlue); } }; const handleDelete = async () => { handleCloseMenu(); await manageToken(item.id, 'delete', ''); }; const actionItems = createMenu([ { text: '编辑', icon: , onClick: () => { handleCloseMenu(); handleOpenModal(); setModalTokenId(item.id); }, color: undefined }, { text: '删除', icon: , onClick: handleDeleteOpen, color: 'error.main' } ]); const handleCopy = (option, type) => { let serverAddress = ''; if (siteInfo?.server_address) { serverAddress = siteInfo.server_address; } else { serverAddress = window.location.host; } if (option.encode) { serverAddress = encodeURIComponent(serverAddress); } let url = option.url; if (option.key === 'next' && siteInfo?.chat_link) { url = siteInfo.chat_link + `/#/?settings={"key":"sk-{key}","url":"{serverAddress}"}`; } const key = item.key; const text = replacePlaceholders(url, key, serverAddress); if (type === 'link') { window.open(text); } else { navigator.clipboard.writeText(text); showSuccess('已复制到剪贴板!'); } handleCloseMenu(); }; const copyItems = createMenu( COPY_OPTIONS.map((option) => ({ text: option.text, icon: undefined, onClick: () => handleCopy(option, 'copy'), color: undefined })) ); const linkItems = createMenu( COPY_OPTIONS.map((option) => ({ text: option.text, icon: undefined, onClick: () => handleCopy(option, 'link'), color: undefined })) ); return ( <> {item.name} { switch (statusSwitch) { case 1: return '已启用'; case 2: return '已禁用'; case 3: return '已过期'; case 4: return '已耗尽'; default: return '未知'; } })()} placement="top" > {renderQuota(item.used_quota)} {item.unlimited_quota ? '无限制' : renderQuota(item.remain_quota, 2)} {timestamp2string(item.created_time)} {item.expired_time === -1 ? '永不过期' : timestamp2string(item.expired_time)} handleOpenMenu(e, 'action')} sx={{ color: 'rgb(99, 115, 129)' }}> {menuItems} 删除Token 是否删除Token {item.name}? ); } TokensTableRow.propTypes = { item: PropTypes.object, manageToken: PropTypes.func, handleOpenModal: PropTypes.func, setModalTokenId: PropTypes.func };