mirror of
https://github.com/christianvidalwolf-prog/Craze-Data-check.git
synced 2026-08-03 13:45:24 +02:00
Fix column resizing in Pricing table
Improve resize logic with proper mouse delta calculation
This commit is contained in:
@@ -51,8 +51,15 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit,
|
|||||||
const [filterMode, setFilterMode] = useState<FilterMode>('all_errors');
|
const [filterMode, setFilterMode] = useState<FilterMode>('all_errors');
|
||||||
const [search, setSearch] = useState('');
|
const [search, setSearch] = useState('');
|
||||||
const [searchMode, setSearchMode] = useState<'all' | 'selected'>('all');
|
const [searchMode, setSearchMode] = useState<'all' | 'selected'>('all');
|
||||||
const [columnWidths, setColumnWidths] = useState<Record<string, number>>({});
|
const [columnWidths, setColumnWidths] = useState<Record<string, number>>({
|
||||||
|
articleNo: 100,
|
||||||
|
articleName: 220,
|
||||||
|
line: 100,
|
||||||
|
classification: 130,
|
||||||
|
});
|
||||||
const [resizingColumn, setResizingColumn] = useState<string | null>(null);
|
const [resizingColumn, setResizingColumn] = useState<string | null>(null);
|
||||||
|
const [resizeStartX, setResizeStartX] = useState<number | null>(null);
|
||||||
|
const [resizeStartWidth, setResizeStartWidth] = useState<number | null>(null);
|
||||||
const tableRef = useRef<HTMLTableElement>(null);
|
const tableRef = useRef<HTMLTableElement>(null);
|
||||||
const [editingCell, setEditingCell] = useState<EditingCell | null>(null);
|
const [editingCell, setEditingCell] = useState<EditingCell | null>(null);
|
||||||
const [savingCell, setSavingCell] = useState<{ rowIndex: number; colIndex: number } | null>(null);
|
const [savingCell, setSavingCell] = useState<{ rowIndex: number; colIndex: number } | null>(null);
|
||||||
@@ -114,36 +121,36 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit,
|
|||||||
setSearchMode('all');
|
setSearchMode('all');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleResizeStart = (e: React.MouseEvent, colKey: string) => {
|
const handleResizeStart = (e: React.MouseEvent, colKey: string, currentWidth: number) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
setResizingColumn(colKey);
|
setResizingColumn(colKey);
|
||||||
|
setResizeStartX(e.clientX);
|
||||||
|
setResizeStartWidth(currentWidth);
|
||||||
};
|
};
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
if (!resizingColumn || resizeStartX === null || resizeStartWidth === null) return;
|
||||||
|
|
||||||
const handleMouseMove = (e: MouseEvent) => {
|
const handleMouseMove = (e: MouseEvent) => {
|
||||||
if (!resizingColumn || !tableRef.current) return;
|
const delta = e.clientX - resizeStartX;
|
||||||
const th = tableRef.current.querySelector(`th[data-col-key="${resizingColumn}"]`) as HTMLElement;
|
const newWidth = Math.max(50, Math.min(400, resizeStartWidth + delta));
|
||||||
if (!th) return;
|
|
||||||
const rect = th.getBoundingClientRect();
|
|
||||||
const newWidth = e.clientX - rect.left;
|
|
||||||
if (newWidth >= 50 && newWidth <= 400) {
|
|
||||||
setColumnWidths(prev => ({ ...prev, [resizingColumn]: newWidth }));
|
setColumnWidths(prev => ({ ...prev, [resizingColumn]: newWidth }));
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMouseUp = () => {
|
const handleMouseUp = () => {
|
||||||
setResizingColumn(null);
|
setResizingColumn(null);
|
||||||
|
setResizeStartX(null);
|
||||||
|
setResizeStartWidth(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (resizingColumn) {
|
document.addEventListener('mousemove', handleMouseMove);
|
||||||
document.addEventListener('mousemove', handleMouseMove as any);
|
|
||||||
document.addEventListener('mouseup', handleMouseUp);
|
document.addEventListener('mouseup', handleMouseUp);
|
||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener('mousemove', handleMouseMove as any);
|
document.removeEventListener('mousemove', handleMouseMove);
|
||||||
document.removeEventListener('mouseup', handleMouseUp);
|
document.removeEventListener('mouseup', handleMouseUp);
|
||||||
};
|
};
|
||||||
}
|
}, [resizingColumn, resizeStartX, resizeStartWidth]);
|
||||||
}, [resizingColumn]);
|
|
||||||
|
|
||||||
// ── Dynamic column detection ──────────────────────────────────────────────
|
// ── Dynamic column detection ──────────────────────────────────────────────
|
||||||
const { uvpIdx, srpCols, containerCols } = useMemo(() => {
|
const { uvpIdx, srpCols, containerCols } = useMemo(() => {
|
||||||
@@ -656,7 +663,7 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit,
|
|||||||
<tr>
|
<tr>
|
||||||
<th data-col-key="articleNo" style={{ width: columnWidths.articleNo || 100 }} className="text-left px-3 py-3 text-xs font-semibold text-slate-400 uppercase tracking-wider border-b border-slate-700 whitespace-nowrap relative">
|
<th data-col-key="articleNo" style={{ width: columnWidths.articleNo || 100 }} className="text-left px-3 py-3 text-xs font-semibold text-slate-400 uppercase tracking-wider border-b border-slate-700 whitespace-nowrap relative">
|
||||||
Art. No.
|
Art. No.
|
||||||
<div onMouseDown={(e) => handleResizeStart(e, 'articleNo')} className="absolute right-0 top-0 bottom-0 w-2 cursor-col-resize hover:bg-blue-500/30" />
|
<div onMouseDown={(e) => handleResizeStart(e, 'articleNo', columnWidths.articleNo || 100)} className="absolute right-0 top-0 bottom-0 w-2 cursor-col-resize hover:bg-blue-500/30" />
|
||||||
</th>
|
</th>
|
||||||
<th data-col-key="articleName" style={{ width: columnWidths.articleName || 220 }} className="text-left px-3 py-3 text-xs font-semibold text-slate-400 uppercase tracking-wider border-b border-slate-700 group relative">
|
<th data-col-key="articleName" style={{ width: columnWidths.articleName || 220 }} className="text-left px-3 py-3 text-xs font-semibold text-slate-400 uppercase tracking-wider border-b border-slate-700 group relative">
|
||||||
<div className="flex items-center gap-1"><span>Article Name</span>
|
<div className="flex items-center gap-1"><span>Article Name</span>
|
||||||
@@ -923,9 +930,9 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit,
|
|||||||
<tr
|
<tr
|
||||||
key={dataIndex}
|
key={dataIndex}
|
||||||
className={cn(
|
className={cn(
|
||||||
'border-b border-slate-700/50 transition-colors hover:bg-slate-700/20',
|
'border-b border-slate-700/50 transition-colors',
|
||||||
isValidated
|
isValidated
|
||||||
? 'bg-emerald-500/10'
|
? 'bg-green-400/30 border-l-4 border-l-green-400' // Vibrant high-visibility green
|
||||||
: saveStatus === 'error'
|
: saveStatus === 'error'
|
||||||
? 'bg-red-400/20 border-l-4 border-l-red-500'
|
? 'bg-red-400/20 border-l-4 border-l-red-500'
|
||||||
: saveStatus === 'pending'
|
: saveStatus === 'pending'
|
||||||
@@ -1068,7 +1075,7 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit,
|
|||||||
|
|
||||||
<td className={cn(
|
<td className={cn(
|
||||||
"px-2 py-2.5 sticky right-0 shadow-[-4px_0_8px_rgba(0,0,0,0.1)] transition-colors",
|
"px-2 py-2.5 sticky right-0 shadow-[-4px_0_8px_rgba(0,0,0,0.1)] transition-colors",
|
||||||
isValidated ? "bg-[#1e2a25]" : "bg-slate-800",
|
isValidated ? "bg-[#1b4d24]" : "bg-slate-800",
|
||||||
"group-hover:bg-slate-700/40"
|
"group-hover:bg-slate-700/40"
|
||||||
)}>
|
)}>
|
||||||
<button
|
<button
|
||||||
|
|||||||
Reference in New Issue
Block a user