fix(token): remove list copy action and clarify one-time copy

This commit is contained in:
yun-zhi-ztl 2026-03-15 14:02:24 +08:00
parent e188c8e060
commit 21ae36645c
4 changed files with 7 additions and 39 deletions

View file

@ -23,12 +23,11 @@ import { resolveTokenExpiresAt, toLocalDateTimeInputValue, type TokenExpirationM
interface CreateTokenDialogProps {
children: React.ReactNode
existingNames?: string[]
onCreated?: (token: CreateTokenResponse) => void
}
const MAX_TOKEN_NAME_LENGTH = 64
export function CreateTokenDialog({ children, existingNames = [], onCreated }: CreateTokenDialogProps) {
export function CreateTokenDialog({ children, existingNames = [] }: CreateTokenDialogProps) {
const { t, i18n } = useTranslation()
const [open, setOpen] = useState(false)
const [name, setName] = useState('')
@ -54,7 +53,6 @@ export function CreateTokenDialog({ children, existingNames = [], onCreated }: C
setCustomExpiresAt('')
setExpiresAtError(null)
queryClient.invalidateQueries({ queryKey: ['tokens'] })
onCreated?.(data)
},
})

View file

@ -1,7 +1,7 @@
import { useState } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { useTranslation } from 'react-i18next'
import { Copy, Pencil } from 'lucide-react'
import { Pencil } from 'lucide-react'
import { tokenApi } from '@/api/client'
import { Button } from '@/shared/ui/button'
import {
@ -31,7 +31,6 @@ export function TokenList() {
const { t, i18n } = useTranslation()
const queryClient = useQueryClient()
const [page, setPage] = useState(0)
const [createdTokens, setCreatedTokens] = useState<Record<number, string>>({})
const [deleteDialog, setDeleteDialog] = useState<{ open: boolean; tokenId?: number; name?: string }>({
open: false,
})
@ -113,21 +112,6 @@ export function TokenList() {
setDeleteDialog({ open: true, tokenId, name })
}
const handleCopyToken = async (tokenId: number) => {
const rawToken = createdTokens[tokenId]
if (!rawToken) {
toast.info(t('token.copyUnavailableTitle'), t('token.copyUnavailableDescription'), centeredToastOptions())
return
}
try {
await navigator.clipboard.writeText(rawToken)
toast.success(t('token.copySuccess'), undefined, centeredToastOptions())
} catch {
toast.error(t('token.copyFailed'), undefined, centeredToastOptions())
}
}
const handleEditExpiration = (token: ApiToken) => {
setExpirationDialog({
open: true,
@ -193,12 +177,7 @@ export function TokenList() {
<div className="space-y-4">
<div className="flex items-center justify-between">
<h2 className="text-xl font-semibold">{t('token.title')}</h2>
<CreateTokenDialog
existingNames={tokens.map((token) => token.name)}
onCreated={(token) => {
setCreatedTokens((current) => ({ ...current, [token.id]: token.token }))
}}
>
<CreateTokenDialog existingNames={tokens.map((token) => token.name)}>
<Button>{t('token.createNew')}</Button>
</CreateTokenDialog>
</div>
@ -236,15 +215,6 @@ export function TokenList() {
<TableCell>{formatDate(token.expiresAt, t('token.neverExpires'))}</TableCell>
<TableCell className="text-center">
<div className="flex justify-center gap-2">
<Button
variant="outline"
size="sm"
onClick={() => handleCopyToken(token.id)}
aria-label={createdTokens[token.id] ? t('token.copy') : t('token.copyUnavailableTitle')}
>
<Copy className="mr-1 h-4 w-4" />
{t('token.copy')}
</Button>
<Button
variant="outline"
size="sm"

View file

@ -426,7 +426,7 @@
"creating": "Creating...",
"create": "Create",
"successTitle": "Token Created",
"successDescription": "Copy and save this token now. It will only be shown once.",
"successDescription": "Copy and save this token now. It is only shown and copyable at creation time. If you need it again later, create a new token.",
"tokenLabel": "Token",
"nameDisplay": "Name",
"expirationLabel": "Expiration",
@ -565,7 +565,7 @@
"token": {
"title": "API Tokens",
"createNew": "Create Token",
"copyHint": "For security reasons, token plaintext is shown only once at creation time. If you lose it, create a new token.",
"copyHint": "For security reasons, token plaintext can only be copied once when it is created. It cannot be viewed or copied again later. If you still need it, create a new token.",
"empty": "No tokens created yet",
"emptyHint": "Click the button above to create your first token",
"name": "Name",

View file

@ -426,7 +426,7 @@
"creating": "创建中...",
"create": "创建",
"successTitle": "Token 创建成功",
"successDescription": "请立即复制并保存此 Token,它只会显示一次",
"successDescription": "请立即复制并保存此 Token。它只会在创建成功时展示和复制这一回,后续若仍需使用,请重新创建。",
"tokenLabel": "Token",
"nameDisplay": "名称",
"expirationLabel": "过期时间",
@ -565,7 +565,7 @@
"token": {
"title": "API Tokens",
"createNew": "创建新 Token",
"copyHint": "出于安全原因Token 明文只在创建时展示一次。若丢失,请重新创建新的 Token。",
"copyHint": "出于安全原因Token 明文只在创建成功时可复制一次,后续无法再次查看或复制。若仍需使用,请重新创建新的 Token。",
"empty": "还没有创建任何 Token",
"emptyHint": "点击上方按钮创建第一个 Token",
"name": "名称",