fix: prevent mobile dashboard overflow

This commit is contained in:
2026-05-09 16:21:08 +09:00
parent 7b0315940b
commit cd586c0c73
3 changed files with 35 additions and 9 deletions

View File

@@ -708,14 +708,14 @@ function Dashboard() {
</div> </div>
<div className="mt-6 grid gap-6 xl:grid-cols-[1.15fr_0.85fr]"> <div className="mt-6 grid gap-6 xl:grid-cols-[1.15fr_0.85fr]">
<Card> <Card className="min-w-0">
<CardHeader> <CardHeader>
<CardTitle>Usage metrics</CardTitle> <CardTitle>Usage metrics</CardTitle>
<CardDescription> <CardDescription>
CodexDash extracts numeric leaf nodes from the aggregated usage payload for quick overview cards. CodexDash extracts numeric leaf nodes from the aggregated usage payload for quick overview cards.
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
<CardContent> <CardContent className="min-w-0">
{metricCards.length === 0 ? ( {metricCards.length === 0 ? (
<div className="rounded-2xl border border-dashed border-white/10 bg-white/3 p-6 text-sm text-slate-400"> <div className="rounded-2xl border border-dashed border-white/10 bg-white/3 p-6 text-sm text-slate-400">
No usage data yet. Connect an OpenAI account and complete the sign-in flow to start refreshing. No usage data yet. Connect an OpenAI account and complete the sign-in flow to start refreshing.
@@ -725,9 +725,9 @@ function Dashboard() {
{metricCards.map((metric) => ( {metricCards.map((metric) => (
<div <div
key={metric.label} key={metric.label}
className="rounded-2xl border border-white/10 bg-white/4 p-4" className="min-w-0 rounded-2xl border border-white/10 bg-white/4 p-4"
> >
<div className="text-sm text-slate-400"> <div className="text-sm text-slate-400 break-words">
{titleizeMetric(metric.label)} {titleizeMetric(metric.label)}
</div> </div>
<div className="mt-3 text-2xl font-semibold text-white"> <div className="mt-3 text-2xl font-semibold text-white">

View File

@@ -2,15 +2,17 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/com
export function JsonViewer({ title, description, value }: { title: string; description: string; value: unknown }) { export function JsonViewer({ title, description, value }: { title: string; description: string; value: unknown }) {
return ( return (
<Card className="border-white/8 bg-slate-900/80"> <Card className="min-w-0 border-white/8 bg-slate-900/80">
<CardHeader> <CardHeader>
<CardTitle>{title}</CardTitle> <CardTitle>{title}</CardTitle>
<CardDescription>{description}</CardDescription> <CardDescription>{description}</CardDescription>
</CardHeader> </CardHeader>
<CardContent> <CardContent className="min-w-0">
<pre className="max-h-80 overflow-auto rounded-2xl bg-black/30 p-4 text-xs leading-6 text-slate-300"> <div className="min-w-0 max-h-80 overflow-x-auto overflow-y-auto rounded-2xl bg-black/30">
<pre className="min-w-0 whitespace-pre-wrap break-all p-4 text-xs leading-6 text-slate-300">
{JSON.stringify(value, null, 2)} {JSON.stringify(value, null, 2)}
</pre> </pre>
</div>
</CardContent> </CardContent>
</Card> </Card>
); );

View File

@@ -0,0 +1,24 @@
import { describe, expect, test } from 'bun:test';
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
const appSource = readFileSync(join(import.meta.dir, '../src/App.tsx'), 'utf8');
const jsonViewerSource = readFileSync(
join(import.meta.dir, '../src/components/json-viewer.tsx'),
'utf8',
);
describe('mobile overflow guards', () => {
test('usage metrics cards allow long metric labels to wrap on mobile', () => {
expect(appSource).toContain('className="grid gap-3 sm:grid-cols-2"');
expect(appSource).toContain('className="min-w-0 rounded-2xl border border-white/10 bg-white/4 p-4"');
expect(appSource).toContain('className="text-sm text-slate-400 break-words"');
});
test('merged payload viewer constrains JSON horizontally inside the card', () => {
expect(jsonViewerSource).toContain('className="min-w-0"');
expect(jsonViewerSource).toContain('overflow-x-auto');
expect(jsonViewerSource).toContain('whitespace-pre-wrap');
expect(jsonViewerSource).toContain('break-all');
});
});