fix(ui): wrap quota card footer action buttons to prevent clipping Refresh button on narrow cards (#11464)

Validated in a combined sub-batch worktree off release/v3.8.51 tip. This PR's branch carried ~100 already-merged commits from a stale rebase (phantom-diff — every commit but the last matches history already on the release tip); cherry-picked only the genuine value commit (the flex-wrap fix itself) and pushed that to this branch.
- Focused tests: quota-card-expanded-footer-flex-wrap.test.ts, quota-card-expanded-sort-collapse.test.ts, quota-card-grid-mobile-7072.test.ts — part of sub-batch's 165/165 node:test run
- typecheck:core, file-size, changelog-integrity, complexity, cognitive-complexity — all OK
- Full-repo lint: 228 pre-existing dashboard react-hooks/* findings, unrelated to this diff

Thanks for the clear root cause (extra View credits button + missing flex-wrap on the footer + overflow-hidden on the outer Card clipping the trailing Refresh now button).
This commit is contained in:
adevwithpurpose
2026-08-26 05:12:50 +05:00
committed by GitHub
parent b84ae072ea
commit ae22c157f4
3 changed files with 43 additions and 7 deletions

View File

@@ -0,0 +1 @@
- fix(ui): wrap quota card footer action buttons to prevent clipping Refresh button on narrow cards — when extra action buttons such as `View credits` are present on Codex cards, allow the footer row to flex-wrap with `shrink-0` buttons so `Refresh now` remains visible and clickable across all responsive card widths

View File

@@ -418,10 +418,10 @@ export default function QuotaCardExpanded({
</button>
)}
<div className="flex items-center justify-between gap-2 pt-1.5 border-t border-border/40">
<div className="flex flex-wrap items-center justify-between gap-1.5 pt-1.5 border-t border-border/40">
{refreshedLabel && (
<span
className={`text-[10px] tabular-nums ${
className={`text-[10px] tabular-nums shrink-0 ${
hasStaleData ? "text-amber-500" : "text-text-muted"
}`}
title={
@@ -433,7 +433,7 @@ export default function QuotaCardExpanded({
{tr("updatedShort", "Updated")} {refreshedLabel}
</span>
)}
<div className="flex items-center gap-1.5 ml-auto">
<div className="flex flex-wrap items-center justify-end gap-1.5 ml-auto">
{canRedeemResetCredit && (
<button
type="button"
@@ -442,7 +442,7 @@ export default function QuotaCardExpanded({
e.stopPropagation();
onOpenResetCredits?.();
}}
className="inline-flex items-center gap-1 text-[11px] font-medium px-2 py-1 rounded-md border border-primary/40 text-primary bg-bg-subtle hover:bg-black/[0.04] dark:hover:bg-white/[0.04] disabled:opacity-40 disabled:cursor-not-allowed cursor-pointer"
className="inline-flex shrink-0 items-center gap-1 text-[11px] font-medium px-2 py-1 rounded-md border border-primary/40 text-primary bg-bg-subtle hover:bg-black/[0.04] dark:hover:bg-white/[0.04] disabled:opacity-40 disabled:cursor-not-allowed cursor-pointer"
>
<span
className={`material-symbols-outlined text-[12px] ${
@@ -461,7 +461,7 @@ export default function QuotaCardExpanded({
e.stopPropagation();
onOpenCutoff();
}}
className={`inline-flex items-center gap-1 text-[11px] font-medium px-2 py-1 rounded-md border bg-bg-subtle hover:bg-black/[0.04] dark:hover:bg-white/[0.04] disabled:opacity-40 disabled:cursor-not-allowed cursor-pointer ${
className={`inline-flex shrink-0 items-center gap-1 text-[11px] font-medium px-2 py-1 rounded-md border bg-bg-subtle hover:bg-black/[0.04] dark:hover:bg-white/[0.04] disabled:opacity-40 disabled:cursor-not-allowed cursor-pointer ${
hasCutoffOverrides ? "border-primary/40 text-primary" : "border-border"
}`}
>
@@ -474,7 +474,7 @@ export default function QuotaCardExpanded({
e.stopPropagation();
onOpenCost();
}}
className="inline-flex items-center gap-1 text-[11px] font-medium px-2 py-1 rounded-md border border-border bg-bg-subtle hover:bg-black/[0.04] dark:hover:bg-white/[0.04] cursor-pointer"
className="inline-flex shrink-0 items-center gap-1 text-[11px] font-medium px-2 py-1 rounded-md border border-border bg-bg-subtle hover:bg-black/[0.04] dark:hover:bg-white/[0.04] cursor-pointer"
>
<span className="material-symbols-outlined text-[12px]">bar_chart</span>
{t("usdCost")}
@@ -486,7 +486,7 @@ export default function QuotaCardExpanded({
e.stopPropagation();
onRefresh();
}}
className="inline-flex items-center gap-1 text-[11px] font-medium px-2 py-1 rounded-md border border-border bg-bg-subtle hover:bg-black/[0.04] dark:hover:bg-white/[0.04] disabled:opacity-40 disabled:cursor-not-allowed cursor-pointer"
className="inline-flex shrink-0 items-center gap-1 text-[11px] font-medium px-2 py-1 rounded-md border border-border bg-bg-subtle hover:bg-black/[0.04] dark:hover:bg-white/[0.04] disabled:opacity-40 disabled:cursor-not-allowed cursor-pointer"
>
<span
className={`material-symbols-outlined text-[12px] ${loading ? "animate-spin" : ""}`}

View File

@@ -0,0 +1,35 @@
import { test } from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
const COMPONENT_PATH = path.resolve(
path.dirname(fileURLToPath(import.meta.url)),
"../../src/app/(dashboard)/dashboard/usage/components/ProviderLimits/parts/QuotaCardExpanded.tsx"
);
test("QuotaCardExpanded footer enables flex-wrap to prevent action button clipping", () => {
const content = fs.readFileSync(COMPONENT_PATH, "utf8");
// Assert footer container has flex-wrap and border-t
assert.match(
content,
/className="[^"]*flex\s+flex-wrap[^"]*border-t[^"]*"/,
"Footer container must include flex-wrap to allow wrapping on narrow cards"
);
// Assert buttons container has flex-wrap
assert.match(
content,
/className="[^"]*flex\s+flex-wrap[^"]*ml-auto[^"]*"/,
"Action buttons container must include flex-wrap to prevent pushing Refresh now button off-screen"
);
// Assert Refresh now button has shrink-0
assert.ok(
content.includes("inline-flex shrink-0 items-center gap-1 text-[11px] font-medium") &&
content.includes('tr("forceRefresh", "Refresh now")'),
"Action buttons must include shrink-0 to prevent compression"
);
});