From 2757d82007cab32131e14d115db4090c9dc725de Mon Sep 17 00:00:00 2001 From: Supra4E8C Date: Mon, 15 Dec 2025 01:19:57 +0800 Subject: [PATCH] feat: improve iFlow cookie auth UX with duplicate config handling - Add 409 conflict handling for duplicate iFlow config files - Add key creation hint in cookie login section - Move extra actions button after delete button for consistency - Improve OAuth status badge display logic (hide when idle) - Add config toggle enable/disable i18n translations - Adjust item-actions spacing from sm to md --- src/pages/AuthFilesPage.tsx | 30 ++++++++++++------------------ src/styles/layout.scss | 4 ++++ 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/pages/AuthFilesPage.tsx b/src/pages/AuthFilesPage.tsx index c1f7252..5508321 100644 --- a/src/pages/AuthFilesPage.tsx +++ b/src/pages/AuthFilesPage.tsx @@ -79,6 +79,13 @@ function normalizeAuthIndexValue(value: unknown): string | null { return null; } +function isRuntimeOnlyAuthFile(file: AuthFileItem): boolean { + const raw = file['runtime_only'] ?? file.runtimeOnly; + if (typeof raw === 'boolean') return raw; + if (typeof raw === 'string') return raw.trim().toLowerCase() === 'true'; + return false; +} + // 解析认证文件的统计数据 function resolveAuthFileStats( file: AuthFileItem, @@ -356,11 +363,11 @@ export function AuthFilesPage() { // 删除全部 await authFilesApi.deleteAll(); showNotification(t('auth_files.delete_all_success'), 'success'); - setFiles([]); + setFiles((prev) => prev.filter((file) => isRuntimeOnlyAuthFile(file))); } else { // 删除筛选类型的文件 const filesToDelete = files.filter( - (f) => f.type === filter && !f['runtime_only'] + (f) => f.type === filter && !isRuntimeOnlyAuthFile(f) ); if (filesToDelete.length === 0) { @@ -564,9 +571,8 @@ export function AuthFilesPage() { // 渲染单个认证文件卡片 const renderFileCard = (item: AuthFileItem) => { - const fileStats = resolveAuthFileStats(item, keyStats); - const runtimeOnlyValue = item['runtime_only']; - const isRuntimeOnly = runtimeOnlyValue === true || runtimeOnlyValue === 'true'; + const fileStats = resolveAuthFileStats(item, keyStats); + const isRuntimeOnly = isRuntimeOnlyAuthFile(item); const typeColor = getTypeColor(item.type || 'unknown'); return ( @@ -601,19 +607,7 @@ export function AuthFilesPage() {
{isRuntimeOnly ? ( - <> -
{t('auth_files.type_virtual') || '虚拟认证文件'}
- - +
{t('auth_files.type_virtual') || '虚拟认证文件'}
) : ( <>