Skip to content

Commit 62165df

Browse files
authored
Merge pull request #450 from cloudflare/fix-db-table
fix: make database table responsive instead of stretching parent
2 parents 6716b94 + ad363d7 commit 62165df

3 files changed

Lines changed: 62 additions & 54 deletions

File tree

src/routes/chat/components/database-viewer.tsx

Lines changed: 60 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ export function DatabaseViewer({ agentId, enabled }: DatabaseViewerProps) {
7272
};
7373

7474
return (
75-
<div className="flex-1 flex flex-col overflow-hidden bg-kumo-base text-text-primary">
76-
<div className="flex items-center gap-2 px-3 py-2 border-b border-bg-2 bg-bg-4/40">
75+
<div className="flex-1 flex flex-col min-h-0 min-w-0 overflow-hidden bg-kumo-base text-text-primary">
76+
<div className="flex shrink-0 items-center gap-2 px-3 py-2 border-b border-bg-2 bg-bg-4/40">
7777
<DatabaseIcon className="size-4 text-text-50/70" />
7878
<span className="text-xs font-mono text-text-50/70">App database</span>
7979
<span className="text-xs text-text-50/40 ml-2">read-only</span>
@@ -98,13 +98,13 @@ export function DatabaseViewer({ agentId, enabled }: DatabaseViewerProps) {
9898
</div>
9999

100100
{error && (
101-
<div className="px-3 py-2 text-xs text-red-400 bg-red-500/10 border-b border-red-500/20">
101+
<div className="shrink-0 px-3 py-2 text-xs text-red-400 bg-red-500/10 border-b border-red-500/20">
102102
{error}
103103
</div>
104104
)}
105105

106-
<div className="flex-1 flex overflow-hidden">
107-
<div className="w-56 border-r border-bg-2 overflow-y-auto bg-bg-4/20 flex flex-col">
106+
<div className="flex-1 flex min-h-0 min-w-0 overflow-hidden">
107+
<div className="w-56 shrink-0 border-r border-bg-2 overflow-y-auto bg-bg-4/20 flex flex-col min-h-0">
108108
<div className="px-3 py-2 text-[10px] uppercase tracking-wider text-text-50/40 font-mono">
109109
Tables
110110
</div>
@@ -123,80 +123,87 @@ export function DatabaseViewer({ agentId, enabled }: DatabaseViewerProps) {
123123
key={t.name}
124124
onClick={() => selectTable(t.name)}
125125
className={cn(
126-
'flex items-center justify-between px-3 py-1.5 text-xs font-mono text-left hover:bg-kumo-elevated transition-colors',
126+
'flex items-center justify-between px-3 py-1.5 text-xs font-mono text-left hover:bg-kumo-elevated transition-colors min-w-0',
127127
selectedTable === t.name && 'bg-kumo-elevated text-text-primary',
128128
)}
129129
>
130130
<span className="truncate">{t.name}</span>
131-
<span className="text-text-50/40 ml-2">{t.rowCount}</span>
131+
<span className="text-text-50/40 ml-2 shrink-0">{t.rowCount}</span>
132132
</button>
133133
))}
134134
</div>
135135

136-
<div className="flex-1 flex flex-col overflow-hidden">
136+
<div className="flex-1 flex flex-col min-h-0 min-w-0 overflow-hidden">
137137
{!selectedTable && (
138138
<div className="flex-1 flex items-center justify-center text-text-50/50 text-sm">
139139
Select a table to view rows
140140
</div>
141141
)}
142142
{selectedTable && (
143143
<>
144-
<div className="flex-1 overflow-auto">
145-
{loadingQuery && !queryResult && (
146-
<div className="p-4 text-xs text-text-50/50">Loading rows…</div>
147-
)}
148-
{queryResult && queryResult.rows.length === 0 && (
149-
<div className="p-4 text-xs text-text-50/50">No rows.</div>
150-
)}
151-
{queryResult && queryResult.rows.length > 0 && (
152-
<table className="w-full text-xs font-mono">
153-
<thead className="sticky top-0 bg-bg-4 border-b border-bg-2">
154-
<tr>
155-
{queryResult.columns.map((col) => (
144+
<div className="relative flex-1 min-h-0 min-w-0">
145+
<div className="absolute inset-0 overflow-auto">
146+
{loadingQuery && !queryResult && (
147+
<div className="p-4 text-xs text-text-50/50">Loading rows…</div>
148+
)}
149+
{queryResult && queryResult.rows.length === 0 && (
150+
<div className="p-4 text-xs text-text-50/50">No rows.</div>
151+
)}
152+
{queryResult && queryResult.rows.length > 0 && (
153+
<table className="w-max min-w-full text-xs font-mono border-collapse">
154+
<thead className="sticky top-0 z-10 bg-bg-4 border-b border-bg-2">
155+
<tr>
156+
{queryResult.columns.map((col) => (
156157
<th
157158
key={col}
158159
onClick={() => onColumnHeaderClick(col)}
159-
className="px-3 py-1.5 text-left font-medium text-text-50/70 cursor-pointer select-none hover:bg-kumo-elevated"
160+
className="px-3 py-1.5 text-left font-medium text-text-50/70 cursor-pointer select-none hover:bg-kumo-elevated whitespace-nowrap max-w-64"
160161
>
161-
{col}
162-
{orderBy === col && (
163-
<span className="ml-1 text-text-primary">
164-
{orderDir === 'asc' ? '↑' : '↓'}
165-
</span>
166-
)}
162+
<span className="block truncate max-w-64">
163+
{col}
164+
{orderBy === col && (
165+
<span className="ml-1 text-text-primary">
166+
{orderDir === 'asc' ? '↑' : '↓'}
167+
</span>
168+
)}
169+
</span>
167170
</th>
168-
))}
169-
</tr>
170-
</thead>
171-
<tbody>
172-
{queryResult.rows.map((row, i) => (
173-
<tr
174-
key={i}
175-
className="border-b border-bg-2/50 hover:bg-kumo-elevated/30"
176-
>
177-
{queryResult.columns.map((col) => (
178-
<td key={col} className="px-3 py-1.5 align-top">
171+
))}
172+
</tr>
173+
</thead>
174+
<tbody>
175+
{queryResult.rows.map((row, i) => (
176+
<tr
177+
key={i}
178+
className="border-b border-bg-2/50 hover:bg-kumo-elevated/30"
179+
>
180+
{queryResult.columns.map((col) => (
181+
<td
182+
key={col}
183+
className="px-3 py-1.5 align-top max-w-64 overflow-hidden whitespace-nowrap"
184+
>
179185
<CellValue
180186
value={row[col]}
181187
onExpand={(v) =>
182188
setExpandedCell({ column: col, value: v })
183189
}
184190
/>
185191
</td>
186-
))}
187-
</tr>
188-
))}
189-
</tbody>
190-
</table>
191-
)}
192+
))}
193+
</tr>
194+
))}
195+
</tbody>
196+
</table>
197+
)}
198+
</div>
192199
</div>
193200
{queryResult && (
194-
<div className="flex items-center gap-3 px-3 py-2 border-t border-bg-2 bg-bg-4/40 text-xs">
195-
<span className="text-text-50/60">
201+
<div className="flex items-center gap-3 px-3 py-2 border-t border-bg-2 bg-bg-4/40 text-xs shrink-0 min-w-0">
202+
<span className="text-text-50/60 shrink-0">
196203
{queryResult.totalCount.toLocaleString()} rows
197204
</span>
198205
<span className="text-text-50/30">·</span>
199-
<span className="text-text-50/60">
206+
<span className="text-text-50/60 shrink-0">
200207
Page {page + 1} / {totalPages}
201208
</span>
202209
<button
@@ -213,7 +220,7 @@ export function DatabaseViewer({ agentId, enabled }: DatabaseViewerProps) {
213220
>
214221
<ChevronRight className="size-3.5" />
215222
</button>
216-
<div className="ml-auto flex items-center gap-1">
223+
<div className="ml-auto flex items-center gap-1 shrink-0">
217224
<span className="text-text-50/50">per page</span>
218225
<select
219226
value={pageSize}
@@ -294,11 +301,11 @@ function CellValue({
294301
}
295302
if (typeof value === 'string') {
296303
if (value.length <= MAX_INLINE_CELL_LEN) {
297-
return <span className="break-all">{value}</span>;
304+
return <span className="truncate max-w-64 inline-block align-bottom" title={value}>{value}</span>;
298305
}
299306
return (
300307
<button
301-
className="text-left text-text-primary/80 hover:text-text-primary underline-offset-2 hover:underline truncate block w-full"
308+
className="text-left text-text-primary/80 hover:text-text-primary underline-offset-2 hover:underline truncate max-w-64 inline-block align-bottom"
302309
onClick={() => onExpand(value)}
303310
title="Click to view full value"
304311
>
@@ -308,12 +315,13 @@ function CellValue({
308315
}
309316
const repr = typeof value === 'object' ? JSON.stringify(value) : String(value);
310317
if (repr.length <= MAX_INLINE_CELL_LEN) {
311-
return <span>{repr}</span>;
318+
return <span className="truncate max-w-64 inline-block align-bottom" title={repr}>{repr}</span>;
312319
}
313320
return (
314321
<button
315-
className="text-left text-text-primary/80 hover:text-text-primary underline-offset-2 hover:underline truncate block w-full"
322+
className="text-left text-text-primary/80 hover:text-text-primary underline-offset-2 hover:underline truncate max-w-64 inline-block align-bottom"
316323
onClick={() => onExpand(value)}
324+
title="Click to view full value"
317325
>
318326
{repr.slice(0, MAX_INLINE_CELL_LEN)}
319327
</button>

src/routes/chat/components/main-content-panel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ export function MainContentPanel(props: MainContentPanelProps) {
450450

451451
return (
452452
<motion.div
453-
className="flex-1 flex flex-col overflow-hidden"
453+
className="flex-1 flex flex-col min-h-0 min-w-0 overflow-hidden"
454454
initial={{ opacity: 0, scale: 0.84 }}
455455
animate={{ opacity: 1, scale: 1 }}
456456
transition={{ duration: 0.3, ease: 'easeInOut' }}

src/routes/chat/components/view-container.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ interface ViewContainerProps {
66

77
export function ViewContainer({ children }: ViewContainerProps) {
88
return (
9-
<div className="flex-1 flex flex-col bg-kumo-base overflow-hidden border-l">
9+
<div className="flex-1 flex flex-col min-h-0 min-w-0 bg-kumo-base overflow-hidden border-l">
1010
{children}
1111
</div>
1212
);

0 commit comments

Comments
 (0)