fix: resolve white screen crash in PricingView filters by adding comprehensive safety checks

This commit is contained in:
Christian Vidal Wolf
2026-04-24 20:19:01 +02:00
parent 127363a308
commit dcbaaea055
2 changed files with 39 additions and 35 deletions
+13 -10
View File
@@ -21,6 +21,7 @@ interface ColumnFilterPopoverProps {
title?: string;
className?: string;
zIndex?: number;
triggerId?: string;
}
export function ColumnFilterPopover({
@@ -73,8 +74,10 @@ export function ColumnFilterPopover({
const isDraggingRef = React.useRef(false);
const dragStartRef = React.useRef<number | null>(null);
const safeUniqueValues = uniqueValues || [];
const safeSelectedValues = selectedValues || [];
const hoveredIndexRef = React.useRef<number | null>(null);
const selectedValuesRef = React.useRef<string[]>(selectedValues);
const selectedValuesRef = React.useRef<string[]>(safeSelectedValues);
const onSelectAllRef = React.useRef(onSelectAll);
const filteredValuesRef = React.useRef<string[]>([]);
const didDragRef = React.useRef(false);
@@ -85,16 +88,16 @@ export function ColumnFilterPopover({
const listRef = React.useRef<HTMLDivElement>(null);
const filteredValues = useMemo(() => {
return uniqueValues.filter(v =>
return safeUniqueValues.filter(v =>
String(v || '').toLowerCase().includes(search.toLowerCase())
);
}, [uniqueValues, search]);
}, [safeUniqueValues, search]);
filteredValuesRef.current = filteredValues;
selectedValuesRef.current = selectedValues;
selectedValuesRef.current = safeSelectedValues;
onSelectAllRef.current = onSelectAll;
const isAllSelected = selectedValues.length === uniqueValues.length && uniqueValues.length > 0;
const isAllSelected = safeSelectedValues.length === safeUniqueValues.length && safeUniqueValues.length > 0;
const applyCondition = () => {
const results: string[] = [];
@@ -221,7 +224,7 @@ export function ColumnFilterPopover({
activeTab === 'values' ? "bg-blue-600 text-white" : "text-slate-400 hover:text-white"
)}
>
Values ({selectedValues.length})
Values ({safeSelectedValues.length})
</button>
<button
onClick={() => setActiveTab('condition')}
@@ -277,7 +280,7 @@ export function ColumnFilterPopover({
<div
key={val}
role="checkbox"
aria-checked={selectedValues.includes(val)}
aria-checked={safeSelectedValues.includes(val)}
tabIndex={0}
onMouseDown={(e) => { e.preventDefault(); handleMouseDown(idx); }}
onMouseEnter={() => handleMouseEnter(idx)}
@@ -287,7 +290,7 @@ export function ColumnFilterPopover({
const start = Math.min(lastClickedIndex, idx);
const end = Math.max(lastClickedIndex, idx);
const itemsToSelect = filteredValues.slice(start, end + 1);
const newSelected = new Set([...selectedValues, ...itemsToSelect]);
const newSelected = new Set([...safeSelectedValues, ...itemsToSelect]);
onSelectAll(Array.from(newSelected));
} else {
onToggle(val);
@@ -304,7 +307,7 @@ export function ColumnFilterPopover({
"w-4 h-4 rounded border flex items-center justify-center shrink-0 transition-colors",
selectedValues.includes(val) ? "bg-blue-600 border-blue-600" : "border-slate-600 bg-slate-900 group-hover:border-slate-500"
)}>
{selectedValues.includes(val) && <Check className="w-3 h-3 text-white" />}
{safeSelectedValues.includes(val) && <Check className="w-3 h-3 text-white" />}
</div>
<span className="text-xs text-slate-300 truncate" title={val}>{val || '(Empty)'}</span>
</div>
@@ -322,7 +325,7 @@ export function ColumnFilterPopover({
if (isAllSelected) {
onSelectAll([]);
} else {
onSelectAll(uniqueValues);
onSelectAll(safeUniqueValues);
}
}}
className="text-[10px] font-black text-indigo-400 hover:text-indigo-300 transition-colors uppercase tracking-tight"