Skip to content

Commit bd28ba1

Browse files
authored
Table sizing improvements (#31)
* Fix table sizing Make the table width to 100% and limit the resizing of columns * Update FeatureCoverage.tsx
1 parent 158d574 commit bd28ba1

File tree

6 files changed

+351
-147
lines changed

6 files changed

+351
-147
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ pnpm-debug.log*
1919

2020
# macOS-specific files
2121
.DS_Store
22+
.kiro
23+
.vscode
Lines changed: 105 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React from 'react';
22
const jsonData = import.meta.glob('/src/data/coverage/*.json');
33
import {
44
Table,
@@ -7,60 +7,67 @@ import {
77
TableRow,
88
TableHead,
99
TableCell,
10-
} from "@/components/ui/table";
10+
} from '@/components/ui/table';
1111
import {
1212
useReactTable,
1313
getCoreRowModel,
1414
getSortedRowModel,
1515
flexRender,
1616
getFilteredRowModel,
1717
getPaginationRowModel,
18-
} from "@tanstack/react-table";
19-
import type { SortingState, ColumnDef, ColumnFiltersState } from "@tanstack/react-table";
18+
} from '@tanstack/react-table';
19+
import type {
20+
SortingState,
21+
ColumnDef,
22+
ColumnFiltersState,
23+
} from '@tanstack/react-table';
24+
2025

2126
const columns: ColumnDef<any>[] = [
2227
{
23-
id: "operation",
24-
accessorFn: (row) => (
25-
Object.keys(row)[0]
26-
),
27-
header: () => "Operation",
28+
id: 'operation',
29+
accessorFn: (row) => Object.keys(row)[0],
30+
header: () => 'Operation',
2831
enableColumnFilter: true,
29-
filterFn: (row, columnId, filterValue) => {
32+
filterFn: (row, _, filterValue) => {
3033
let operation = Object.keys(row.original)[0];
3134
return operation
3235
.toLowerCase()
33-
.includes((filterValue ?? "").toLowerCase());
36+
.includes((filterValue ?? '').toLowerCase());
3437
},
35-
meta: { className: "w-1/3" },
38+
enableResizing: false,
3639
},
3740
{
38-
id: "implemented",
39-
accessorFn: row => row[Object.keys(row)[0]].implemented,
40-
header: () => "Implemented",
41-
cell: ({ getValue }) => (getValue() ? "✔️" : ""),
42-
meta: { className: "w-1/6" },
41+
id: 'implemented',
42+
accessorFn: (row) => row[Object.keys(row)[0]].implemented,
43+
header: () => 'Implemented',
44+
cell: ({ getValue }) => (getValue() ? '✔️' : ''),
4345
enableSorting: true,
46+
enableResizing: false,
4447
},
4548
{
46-
id: "image",
47-
accessorFn: row => row[Object.keys(row)[0]].availability,
48-
header: () => "Image",
49-
meta: { className: "w-1/6" },
49+
id: 'image',
50+
accessorFn: (row) => row[Object.keys(row)[0]].availability,
51+
header: () => 'Image',
5052
enableSorting: false,
53+
enableResizing: false,
5154
},
5255
];
5356

54-
export default function PersistenceCoverage({service}: {service: string}) {
57+
export default function PersistenceCoverage({ service }: { service: string }) {
5558
const [coverage, setCoverage] = React.useState<any[]>([]);
5659
const [sorting, setSorting] = React.useState<SortingState>([
57-
{ id: "operation", desc: false },
60+
{ id: 'operation', desc: false },
5861
]);
59-
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([]);
62+
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
63+
[]
64+
);
6065

6166
React.useEffect(() => {
6267
const loadData = async () => {
63-
const moduleData = await jsonData[`/src/data/coverage/${service}.json`]() as { default: Record<string, any> };
68+
const moduleData = (await jsonData[
69+
`/src/data/coverage/${service}.json`
70+
]()) as { default: Record<string, any> };
6471
setCoverage(moduleData.default.operations);
6572
};
6673
loadData();
@@ -69,7 +76,10 @@ export default function PersistenceCoverage({service}: {service: string}) {
6976
const table = useReactTable({
7077
data: coverage,
7178
columns,
72-
state: { sorting, columnFilters },
79+
state: {
80+
sorting,
81+
columnFilters,
82+
},
7383
onSortingChange: setSorting,
7484
onColumnFiltersChange: setColumnFilters,
7585
getCoreRowModel: getCoreRowModel(),
@@ -87,39 +97,65 @@ export default function PersistenceCoverage({service}: {service: string}) {
8797
type="text"
8898
placeholder="Filter by operation name..."
8999
value={
90-
table.getColumn("operation")?.getFilterValue() as string || ""
100+
(table.getColumn('operation')?.getFilterValue() as string) || ''
91101
}
92-
onChange={e =>
93-
table.getColumn("operation")?.setFilterValue(e.target.value)
102+
onChange={(e) =>
103+
table.getColumn('operation')?.setFilterValue(e.target.value)
94104
}
95105
className="border rounded px-2 py-1 w-full max-w-xs"
96106
/>
97107
</div>
98-
<div className="rounded-md border">
99-
<Table>
108+
<div className="rounded-md border w-full overflow-hidden">
109+
<Table
110+
className="w-full"
111+
style={{
112+
width: '100%',
113+
tableLayout: 'fixed',
114+
}}
115+
>
100116
<TableHeader>
101117
{table.getHeaderGroups().map((headerGroup) => (
102118
<TableRow key={headerGroup.id}>
103119
{headerGroup.headers.map((header) => {
104120
const canSort = header.column.getCanSort();
105-
const meta = header.column.columnDef.meta as { className?: string } | undefined;
121+
// Calculate percentage-based widths: Operation 60%, others 20% each
122+
const getColumnWidth = (columnId: string) => {
123+
switch (columnId) {
124+
case 'operation':
125+
return '75%';
126+
case 'implemented':
127+
case 'image':
128+
return '15%';
129+
default:
130+
return 'auto';
131+
}
132+
};
133+
106134
return (
107135
<TableHead
108136
key={header.id}
109-
onClick={canSort ? header.column.getToggleSortingHandler() : undefined}
110-
className={
111-
(meta?.className || "") +
112-
(canSort ? " cursor-pointer select-none" : "")
137+
onClick={
138+
canSort
139+
? header.column.getToggleSortingHandler()
140+
: undefined
113141
}
142+
className={canSort ? 'cursor-pointer select-none' : ''}
143+
style={{
144+
width: getColumnWidth(header.id),
145+
textAlign: header.id === 'operation' ? 'left' : 'center',
146+
}}
114147
>
115-
{flexRender(header.column.columnDef.header, header.getContext())}
148+
{flexRender(
149+
header.column.columnDef.header,
150+
header.getContext()
151+
)}
116152
{canSort && (
117153
<span>
118-
{header.column.getIsSorted() === "asc"
119-
? " ▲"
120-
: header.column.getIsSorted() === "desc"
121-
? " ▼"
122-
: ""}
154+
{header.column.getIsSorted() === 'asc'
155+
? ' ▲'
156+
: header.column.getIsSorted() === 'desc'
157+
? ' ▼'
158+
: ''}
123159
</span>
124160
)}
125161
</TableHead>
@@ -132,13 +168,34 @@ export default function PersistenceCoverage({service}: {service: string}) {
132168
{table.getRowModel().rows.map((row) => (
133169
<TableRow key={row.id}>
134170
{row.getVisibleCells().map((cell) => {
135-
const meta = cell.column.columnDef.meta as { className?: string } | undefined;
171+
// Same width calculation for cells
172+
const getColumnWidth = (columnId: string) => {
173+
switch (columnId) {
174+
case 'operation':
175+
return '60%';
176+
case 'implemented':
177+
case 'image':
178+
return '20%';
179+
default:
180+
return 'auto';
181+
}
182+
};
183+
136184
return (
137185
<TableCell
138186
key={cell.id}
139-
className={meta?.className || undefined}
187+
style={{
188+
width: getColumnWidth(cell.column.id),
189+
textAlign: cell.column.id === 'operation' ? 'left' : 'center',
190+
overflow: 'hidden',
191+
textOverflow: 'ellipsis',
192+
whiteSpace: cell.column.id === 'operation' ? 'normal' : 'nowrap',
193+
}}
140194
>
141-
{flexRender(cell.column.columnDef.cell, cell.getContext())}
195+
{flexRender(
196+
cell.column.columnDef.cell,
197+
cell.getContext()
198+
)}
142199
</TableCell>
143200
);
144201
})}
@@ -156,7 +213,8 @@ export default function PersistenceCoverage({service}: {service: string}) {
156213
Previous
157214
</button>
158215
<span>
159-
Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount()}
216+
Page {table.getState().pagination.pageIndex + 1} of{' '}
217+
{table.getPageCount()}
160218
</span>
161219
<button
162220
className="px-3 py-1 border rounded disabled:opacity-50"
@@ -168,4 +226,4 @@ export default function PersistenceCoverage({service}: {service: string}) {
168226
</div>
169227
</div>
170228
);
171-
}
229+
}

0 commit comments

Comments
 (0)