From 9f451f8299040a8ed024c2cdf9f23186e1474cfd Mon Sep 17 00:00:00 2001 From: lzt404 <2596933790@qq.com> Date: Mon, 5 Oct 2026 13:49:19 +0800 Subject: [PATCH] fix(auth-files): prevent long quota labels from overlapping adjacent columns Fixes #345 --- src/components/AuthFileQuotaPanel.css | 3 +++ tests/auth-file-list-ui.cjs | 25 +++++++++++++++++++++++++ tests/fixtures/auth-file-list.tsx | 9 +++++++++ 3 files changed, 37 insertions(+) diff --git a/src/components/AuthFileQuotaPanel.css b/src/components/AuthFileQuotaPanel.css index b163f83..93cdbf7 100644 --- a/src/components/AuthFileQuotaPanel.css +++ b/src/components/AuthFileQuotaPanel.css @@ -14,6 +14,9 @@ } .credential-quota-compact .credential-quota-row { + /* Long labels must shrink within their quota window, not widen the + implicit grid track into the next window or the action column. */ + grid-template-columns: minmax(0, 1fr); align-content: start; gap: 5px; } diff --git a/tests/auth-file-list-ui.cjs b/tests/auth-file-list-ui.cjs index 4fd7caa..93e3050 100644 --- a/tests/auth-file-list-ui.cjs +++ b/tests/auth-file-list-ui.cjs @@ -182,6 +182,31 @@ const fs = require('node:fs/promises'); assert.deepEqual(await page.evaluate(() => window.authFileListFixture.requests.find(request => request.method === 'DELETE')?.query), { name: '12-account.json' }); assert.deepEqual(await page.evaluate(() => window.authFileListFixture.unhandled), []); + // Issue #345: long Antigravity labels/details must not size implicit grid + // tracks beyond the quota cell or cover the adjacent action buttons. + for (const theme of ['light', 'dark']) { + for (const width of [1800, 1505, 1280, 1172, 1024, 390]) { + await page.setViewportSize({ width, height: 1000 }); + await open(`theme=${theme}&locale=en&longQuota=1`); + for (const expanded of [false, true]) { + if (expanded) await card(1).locator('.credential-quota-more > summary').click(); + const overflow = await card(1).locator('.auth-list-quota').evaluate(cell => { + const bounds = cell.getBoundingClientRect(); + return [...cell.querySelectorAll('.credential-quota-rows, .credential-quota-row, .credential-quota-label, .credential-quota-label strong, .credential-quota-track, small')] + .filter(node => node.getClientRects().length) + .filter(node => { + const rect = node.getBoundingClientRect(); + const row = node.closest('.credential-quota-row')?.getBoundingClientRect() || bounds; + return rect.left < row.left - 1 || rect.right > row.right + 1 || rect.right > bounds.right + 1; + }).map(node => node.className || node.tagName); + }); + assert.deepEqual(overflow, [], `${theme} ${width} expanded=${expanded}: quota content stays inside its row and column`); + await assertFits(`long quota ${theme} ${width}`); + } + await page.screenshot({ path: path.join(screenshotDir, `long-quota-${theme}-${width}.png`), fullPage: true }); + } + } + const cases = ['light', 'dark'].flatMap(theme => [1800, 1280, 1024, 390].flatMap(width => ['zh-CN', 'en'].map(locale => ({ theme, width, locale })))); for (const { theme, width, locale } of cases) { await page.setViewportSize({ width, height: 1000 }); diff --git a/tests/fixtures/auth-file-list.tsx b/tests/fixtures/auth-file-list.tsx index da9c86b..c1aa946 100644 --- a/tests/fixtures/auth-file-list.tsx +++ b/tests/fixtures/auth-file-list.tsx @@ -18,6 +18,7 @@ const files: Record[] = Array.from({ length: smallList ? 3 : 12 name: `${String(index + 1).padStart(2, '0')}-account.json`, email: index === 0 ? 'long-fictional-account-for-layout@example.test' : `account-${index + 1}@example.test`, auth_index: `fixture-account-${index + 1}`, provider: smallList ? ['codex', 'devin', 'xai'][index] : index === 3 ? 'claude' : index === 4 ? 'xai' : 'codex', + ...(params.has('longQuota') ? { provider: 'antigravity' } : {}), source: 'file', size: 1800 + index * 350, updated_at: '2026-10-01T00:00:00Z', disabled: smallList ? index !== 1 : index === 2 || index === 6, status: (smallList ? index !== 1 : index === 2 || index === 6) ? 'disabled' : 'active', @@ -50,6 +51,14 @@ updateQuotaCache(Object.fromEntries(files.map((file, index) => { ] : []), ], }; + if (params.has('longQuota')) { + quota.rows = Array.from({ length: 4 }, (_, row) => ({ + label: `${row < 2 ? 'Gemini' : 'Claude'} Models ยท ${row % 2 ? 'Weekly' : 'Five Hour'} Limit Remaining`, + remainingPercent: row % 2 ? 100 : 75, + resetAtMs: startedAt + 3 * 3600000, + detail: 'You have used some of your five-hour limit, it will fully reset at the time shown above.', + })); + } return [quotaKey(file), quota]; })));