UI: Add resizable columns to Matrix View. Users can now adjust column widths by dragging, improving data visibility in the All Data view.

This commit is contained in:
Christian Vidal Wolf
2026-04-22 17:09:46 +02:00
parent f01b720c05
commit bf98e4e4ba
+33 -4
View File
@@ -66,6 +66,8 @@ export function MatrixView({ data, headers, rowStatuses }: MatrixViewProps) {
return filteredData.slice(start, start + pageSize); return filteredData.slice(start, start + pageSize);
}, [filteredData, page, pageSize]); }, [filteredData, page, pageSize]);
const [columnWidths, setColumnWidths] = useState<Record<number, number>>({});
const handleSort = (col: number) => { const handleSort = (col: number) => {
if (sortCol === col) { if (sortCol === col) {
setSortDesc(!sortDesc); setSortDesc(!sortDesc);
@@ -75,6 +77,25 @@ export function MatrixView({ data, headers, rowStatuses }: MatrixViewProps) {
} }
}; };
const handleResize = (colIndex: number, e: React.MouseEvent) => {
e.preventDefault();
const startX = e.pageX;
const startWidth = columnWidths[colIndex] || 150;
const onMouseMove = (moveEvent: MouseEvent) => {
const newWidth = Math.max(60, startWidth + (moveEvent.pageX - startX));
setColumnWidths(prev => ({ ...prev, [colIndex]: newWidth }));
};
const onMouseUp = () => {
window.removeEventListener('mousemove', onMouseMove);
window.removeEventListener('mouseup', onMouseUp);
};
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('mouseup', onMouseUp);
};
const getUniqueValues = (col: number) => { const getUniqueValues = (col: number) => {
const values = data.map(r => String(r[col] || '')); const values = data.map(r => String(r[col] || ''));
return Array.from(new Set(values)).sort(); return Array.from(new Set(values)).sort();
@@ -197,17 +218,18 @@ export function MatrixView({ data, headers, rowStatuses }: MatrixViewProps) {
</div> </div>
<div className="overflow-auto flex-1"> <div className="overflow-auto flex-1">
<table className="w-full text-left text-sm whitespace-nowrap"> <table className="w-full text-left text-sm whitespace-nowrap" style={{ tableLayout: 'fixed' }}>
<thead className="bg-slate-900/50 text-slate-400 sticky top-0 z-10"> <thead className="bg-slate-900/50 text-slate-400 sticky top-0 z-10">
<tr> <tr>
{headers.map((header, index) => ( {headers.map((header, index) => (
<th <th
key={index} key={index}
className="px-4 py-3 font-medium border-b border-slate-700 transition-colors select-none group relative" className="px-4 py-3 font-medium border-b border-slate-700 transition-colors select-none group relative border-r border-slate-700/30"
style={{ width: columnWidths[index] || 150, minWidth: columnWidths[index] || 150 }}
> >
<div className="flex items-center overflow-hidden"> <div className="flex items-center overflow-hidden">
<span <span
className="flex items-center gap-1 cursor-pointer hover:text-white" className="flex items-center gap-1 cursor-pointer hover:text-white truncate"
onClick={() => handleSort(index)} onClick={() => handleSort(index)}
> >
{header} {header}
@@ -229,6 +251,12 @@ export function MatrixView({ data, headers, rowStatuses }: MatrixViewProps) {
</button> </button>
</div> </div>
{/* Resizer handle */}
<div
onMouseDown={(e) => handleResize(index, e)}
className="absolute right-0 top-0 bottom-0 w-1 cursor-col-resize hover:bg-blue-500/50 group-hover:bg-slate-700/50 transition-colors z-20"
/>
{openFilterCol === index && ( {openFilterCol === index && (
<ColumnFilterPopover <ColumnFilterPopover
uniqueValues={getUniqueValues(index)} uniqueValues={getUniqueValues(index)}
@@ -259,7 +287,8 @@ export function MatrixView({ data, headers, rowStatuses }: MatrixViewProps) {
return ( return (
<td <td
key={colIndex} key={colIndex}
className="px-4 py-3 text-slate-300 max-w-[200px] truncate" className="px-4 py-3 text-slate-300 truncate border-r border-slate-700/30"
style={{ width: columnWidths[colIndex] || 150, minWidth: columnWidths[colIndex] || 150 }}
title={String(row[colIndex] || '')} title={String(row[colIndex] || '')}
> >
{formattedValue} {formattedValue}