mirror of
https://github.com/christianvidalwolf-prog/Craze-Data-check.git
synced 2026-08-03 17:35:23 +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 [outerLFilter, setOuterLFilter] = useState<string[]>([]);
|
||||||
const [outerHFilter, setOuterHFilter] = useState<string[]>([]);
|
const [outerHFilter, setOuterHFilter] = useState<string[]>([]);
|
||||||
const [dynamicColFilters, setDynamicColFilters] = useState<Record<number, 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 [editingType, setEditingType] = useState<{ rowIndex: number; value: string } | null>(null);
|
||||||
const [typeSuggestions, setTypeSuggestions] = useState<string[]>([]);
|
const [typeSuggestions, setTypeSuggestions] = useState<string[]>([]);
|
||||||
const typeInputRef = useRef<HTMLInputElement>(null);
|
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;
|
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 ──────────────────────────────────────────────────────────
|
// ── Sorted rows ──────────────────────────────────────────────────────────
|
||||||
const sortedRows = useMemo(() => {
|
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">
|
<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">
|
||||||
Issues
|
<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>
|
||||||
|
|
||||||
<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)}>
|
<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