feat: DataTable scrollable layout with 200+ mock exchanges
All checks were successful
Build & Publish / publish (push) Successful in 1m55s
SonarQube Analysis / sonarqube (push) Successful in 1m52s

Make Dashboard table fill viewport height with sticky header/footer
and internal scrolling. Expand mock exchange data from 15 to 200
records and Inventory showcase from 5 to 500 records.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-29 10:43:03 +02:00
parent 8070fdea7c
commit 0bb49b83e5
4 changed files with 102 additions and 8 deletions

View File

@@ -4,7 +4,10 @@
overflow-y: auto;
padding: 20px 24px 40px;
min-width: 0;
min-height: 0;
background: var(--bg-body);
display: flex;
flex-direction: column;
}
/* Filter bar spacing */
@@ -19,6 +22,10 @@
border-radius: var(--radius-lg);
box-shadow: var(--shadow-card);
overflow: hidden;
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
.tableHeader {

View File

@@ -425,6 +425,7 @@ export function Dashboard() {
selectedId={selectedId}
sortable
flush
fillHeight
rowAccent={handleRowAccent}
expandedContent={(row) =>
row.errorMessage ? (

View File

@@ -135,13 +135,27 @@ interface TableRow {
exchanges: number
}
const TABLE_DATA: TableRow[] = [
{ id: '1', name: 'order-ingest', method: 'POST', status: 'live', exchanges: 1243 },
{ id: '2', name: 'payment-validate', method: 'POST', status: 'live', exchanges: 987 },
{ id: '3', name: 'inventory-check', method: 'GET', status: 'stale', exchanges: 432 },
{ id: '4', name: 'notify-customer', method: 'POST', status: 'live', exchanges: 876 },
{ id: '5', name: 'archive-order', method: 'PUT', status: 'dead', exchanges: 54 },
const ROUTE_PREFIXES = [
'order', 'payment', 'inventory', 'customer', 'shipment', 'user', 'cart',
'refund', 'stock', 'email', 'webhook', 'cache', 'log', 'rate', 'health',
'session', 'config', 'metrics', 'batch', 'audit', 'invoice', 'product',
'catalog', 'search', 'report', 'export', 'import', 'sync', 'alert', 'ticket',
]
const ROUTE_SUFFIXES = [
'ingest', 'validate', 'check', 'notify', 'archive', 'track', 'auth',
'update', 'process', 'sync', 'dispatch', 'relay', 'invalidate', 'aggregate',
'limit', 'refresh', 'reload', 'export', 'import', 'purge',
]
const METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH']
const STATUSES = ['live', 'live', 'live', 'live', 'stale', 'stale', 'dead']
const TABLE_DATA: TableRow[] = Array.from({ length: 500 }, (_, i) => ({
id: String(i + 1),
name: `${ROUTE_PREFIXES[i % ROUTE_PREFIXES.length]}-${ROUTE_SUFFIXES[(i * 7) % ROUTE_SUFFIXES.length]}`,
method: METHODS[i % METHODS.length],
status: STATUSES[i % STATUSES.length],
exchanges: ((i * 1337 + 421) % 9990) + 10,
}))
const NOW = new Date()
const minsAgo = (n: number) => new Date(NOW.getTime() - n * 60 * 1000)
@@ -468,12 +482,13 @@ export function CompositesSection() {
title="DataTable"
description="Sortable, paginated table with row click, accent rows, and page size selector."
>
<div style={{ width: '100%' }}>
<div style={{ width: '100%', height: 500, display: 'flex', flexDirection: 'column' }}>
<DataTable
columns={tableColumns}
data={TABLE_DATA}
sortable
pageSize={5}
pageSize={25}
fillHeight
/>
</div>
</DemoCard>