import type { ApiKeyItem } from '@dify/contracts/api/console/apps/types.gen' import type { EnvironmentApiKey } from '@dify/contracts/enterprise-app-deploy/types.gen' import { IconButton } from '@langgenius/dify-ui/icon-button' import { useTranslation } from 'react-i18next' import { CopyFeedback } from '@/app/components/base/copy-feedback' import useTimestamp from '@/hooks/use-timestamp' type ApiKeyTableProps = { apiKeys: Array canManage: boolean // Dataset keys carry a knowledge-base scope; enable the SCOPE column to surface it. showScope?: boolean onDeleteRequest: (apiKeyId: string) => void } export function ApiKeyTable({ apiKeys, canManage, showScope = false, onDeleteRequest, }: ApiKeyTableProps) { const { t } = useTranslation() const { formatTime } = useTimestamp() const maskToken = (token: string) => `${token.slice(0, 3)}...${token.slice(-20)}` // Only dataset keys expose dataset_ids; an empty/absent list means the key can access // every knowledge base in the workspace. const scopeLabel = (apiKey: ApiKeyItem | EnvironmentApiKey) => { const datasetIds = (apiKey as { dataset_ids?: string[] }).dataset_ids if (!datasetIds?.length) return t(($) => $['apiKeyModal.scopeAllDatasets'], { ns: 'appApi' }) return t(($) => $['apiKeyModal.scopeCount'], { ns: 'appApi', count: datasetIds.length }) } return (
{showScope && ( )} {apiKeys.map((apiKey) => ( {showScope && } ))}
{t(($) => $['apiKeyModal.secretKey'], { ns: 'appApi' })} {t(($) => $['apiKeyModal.scope'], { ns: 'appApi' })} {t(($) => $['apiKeyModal.created'], { ns: 'appApi' })} {t(($) => $['apiKeyModal.lastUsed'], { ns: 'appApi' })} {t(($) => $['operation.settings'], { ns: 'common' })}
{maskToken(apiKey.token)}{scopeLabel(apiKey)} {formatTime( Number(apiKey.created_at), t(($) => $.dateTimeFormat, { ns: 'appLog' }) as string, )} {apiKey.last_used_at ? formatTime( Number(apiKey.last_used_at), t(($) => $.dateTimeFormat, { ns: 'appLog' }) as string, ) : t(($) => $.never, { ns: 'appApi' })}
{canManage && ( $['operation.delete'], { ns: 'common' })} ${maskToken(apiKey.token)}`} onClick={() => onDeleteRequest(apiKey.id)} > )}
) }