mirror of
https://github.com/christianvidalwolf-prog/Craze-Data-check.git
synced 2026-08-03 15:55:24 +02:00
feat: add filter to Issues column in Pricing view
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
db25ea793d
commit
e7f88c67e6
@@ -82,6 +82,7 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit,
|
||||
const [outerLFilter, setOuterLFilter] = useState<string[]>([]);
|
||||
const [outerHFilter, setOuterHFilter] = useState<string[]>([]);
|
||||
const [dynamicColFilters, setDynamicColFilters] = useState<Record<number, string[]>>({});
|
||||
const [weightIssueFilter, setWeightIssueFilter] = useState<'all' | 'with' | 'without'>('all');
|
||||
const [editingType, setEditingType] = useState<{ rowIndex: number; value: string } | null>(null);
|
||||
const [typeSuggestions, setTypeSuggestions] = useState<string[]>([]);
|
||||
const typeInputRef = useRef<HTMLInputElement>(null);
|
||||
@@ -345,8 +346,15 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit,
|
||||
}
|
||||
});
|
||||
|
||||
// Weight issue filter
|
||||
if (weightIssueFilter === 'with') {
|
||||
result = result.filter(r => r.unitErrors.some(e => e.startsWith('NW')));
|
||||
} else if (weightIssueFilter === 'without') {
|
||||
result = result.filter(r => !r.unitErrors.some(e => e.startsWith('NW')));
|
||||
}
|
||||
|
||||
return result;
|
||||
}, [analyzedRows, filterMode, search, nameColFilter, lineMultiFilter, classificationFilter, unitsOuterFilter, outerWFilter, outerLFilter, outerHFilter, dynamicColFilters]);
|
||||
}, [analyzedRows, filterMode, search, nameColFilter, lineMultiFilter, classificationFilter, unitsOuterFilter, outerWFilter, outerLFilter, outerHFilter, dynamicColFilters, weightIssueFilter]);
|
||||
|
||||
// ── Sorted rows ──────────────────────────────────────────────────────────
|
||||
const sortedRows = useMemo(() => {
|
||||
@@ -1057,8 +1065,35 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit,
|
||||
);
|
||||
})}
|
||||
|
||||
<th style={{ width: 180 }} className="text-left px-3 py-3 text-xs font-semibold text-red-400 uppercase tracking-wider border-b border-slate-700 whitespace-nowrap relative">
|
||||
Issues
|
||||
<th style={{ width: 180 }} className="text-left px-3 py-3 text-xs font-semibold text-red-400 uppercase tracking-wider border-b border-slate-700 whitespace-nowrap group relative">
|
||||
<div className="flex items-center gap-1">
|
||||
<span>Issues</span>
|
||||
<button
|
||||
onClick={() => setOpenFilter(openFilter === 'weightIssue' ? null : 'weightIssue')}
|
||||
className={cn(
|
||||
'p-0.5 rounded hover:bg-slate-700 transition-colors shrink-0',
|
||||
weightIssueFilter !== 'all' ? 'text-red-400 bg-red-400/10' : 'text-slate-500 opacity-0 group-hover:opacity-100'
|
||||
)}
|
||||
>
|
||||
<Filter className="w-3 h-3" />
|
||||
</button>
|
||||
</div>
|
||||
{openFilter === 'weightIssue' && (
|
||||
<div className="absolute top-full left-0 mt-1 w-44 bg-slate-800 border border-slate-700 rounded-lg shadow-2xl z-50 p-1 flex flex-col gap-0.5 animate-in fade-in zoom-in-95 duration-100">
|
||||
{(['all', 'with', 'without'] as const).map(opt => (
|
||||
<button
|
||||
key={opt}
|
||||
onClick={() => { setWeightIssueFilter(opt); setOpenFilter(null); }}
|
||||
className={cn(
|
||||
'w-full text-left px-3 py-1.5 rounded text-xs transition-colors',
|
||||
weightIssueFilter === opt ? 'bg-red-500/20 text-red-400' : 'text-slate-300 hover:bg-slate-700'
|
||||
)}
|
||||
>
|
||||
{opt === 'all' ? 'All' : opt === 'with' ? 'With weight issue' : 'No weight issue'}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</th>
|
||||
|
||||
<th style={{ width: columnWidths.check }} className="text-left px-3 py-3 text-xs font-semibold text-blue-400 uppercase tracking-wider group cursor-pointer hover:bg-slate-800/50 transition-colors relative" onClick={() => handleSort(COLUMNS.VALIDATED_CHECK)}>
|
||||
|
||||
Reference in New Issue
Block a user