From af2ed8a037977f6188c9c13561a385b68f6e0c2e Mon Sep 17 00:00:00 2001 From: Christian Vidal Wolf Date: Mon, 20 Apr 2026 17:01:47 +0200 Subject: [PATCH] Add dynamic column filters to all pricing columns Add filter dropdowns to SRP, UVP, and container columns in Pricing tab --- src/components/PricingView.tsx | 99 +++++++++++++++++++++++++++++----- 1 file changed, 86 insertions(+), 13 deletions(-) diff --git a/src/components/PricingView.tsx b/src/components/PricingView.tsx index 043c4a6..8fdb247 100644 --- a/src/components/PricingView.tsx +++ b/src/components/PricingView.tsx @@ -55,15 +55,12 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, const [lineMultiFilter, setLineMultiFilter] = useState([]); const [classificationFilter, setClassificationFilter] = useState([]); const [nameColFilter, setNameColFilter] = useState(''); - const [openFilter, setOpenFilter] = useState<'name' | 'line' | 'classification' | 'unitsOuter' | 'outerW' | 'outerL' | 'outerH' | 'srp' | 'container' | null>(null); + const [openFilter, setOpenFilter] = useState(null); const [unitsOuterFilter, setUnitsOuterFilter] = useState([]); const [outerWFilter, setOuterWFilter] = useState([]); const [outerLFilter, setOuterLFilter] = useState([]); const [outerHFilter, setOuterHFilter] = useState([]); - const [srpFilter, setSrpFilter] = useState([]); - const [containerFilter, setContainerFilter] = useState([]); - const [srpColFilter, setSrpColFilter] = useState([]); - const [containerColFilter, setContainerColFilter] = useState([]); + const [dynamicColFilters, setDynamicColFilters] = useState>({}); // ── Dynamic column detection ────────────────────────────────────────────── const { uvpIdx, srpCols, containerCols } = useMemo(() => { @@ -214,8 +211,17 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, result = result.filter(r => outerHFilter.includes(String(r.row[COLUMNS.OUTER_H] || ''))); } + // Dynamic column filters (SRP, container) + (Object.keys(dynamicColFilters) as string[]).forEach(colIdx => { + const filterVals = dynamicColFilters[Number(colIdx)]; + if (filterVals && filterVals.length > 0) { + const col = Number(colIdx); + result = result.filter(r => filterVals.includes(String(r.row[col] || ''))); + } + }); + return result; - }, [analyzedRows, filterMode, search, nameColFilter, lineMultiFilter, classificationFilter, unitsOuterFilter, outerWFilter, outerLFilter, outerHFilter]); + }, [analyzedRows, filterMode, search, nameColFilter, lineMultiFilter, classificationFilter, unitsOuterFilter, outerWFilter, outerLFilter, outerHFilter, dynamicColFilters]); // ── Inline edit helpers ─────────────────────────────────────────────────── const startEdit = (rowIndex: number, colIndex: number, currentValue: string) => { @@ -249,6 +255,18 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, ...srpCols, ]; + // ═ Unique values for dynamic pricing columns ═════════════════════════════ + const dynamicColUniqueValues = useMemo(() => { + const result: Record = {}; + pricingEditableCols.forEach(col => { + result[col.index] = Array.from(new Set(data.map(r => String(r[col.index] || '')))).filter(v => v).sort(); + }); + containerCols.forEach(col => { + result[col.index] = Array.from(new Set(data.map(r => String(r[col.index] || '')))).filter(v => v).sort(); + }); + return result; + }, [data, uvpIdx, srpCols, containerCols, headers]); + const formatPrice = (val: any) => { if (val === undefined || val === null || val === '') return ''; const n = parseFloat(String(val).replace(',', '.')); @@ -468,11 +486,37 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, {/* Editable pricing columns */} {pricingEditableCols.map(col => ( - - - - {col.name} - + +
+ {col.name} + +
+ {openFilter === `prc_${col.index}` && ( + setDynamicColFilters(prev => { + const current = prev[col.index] || []; + return current.includes(val) + ? { ...prev, [col.index]: current.filter(v => v !== val) } + : { ...prev, [col.index]: [...current, val] }; + })} + onSelectAll={vals => setDynamicColFilters(prev => ({ ...prev, [col.index]: vals }))} + onClear={() => { setDynamicColFilters(prev => { const next = { ...prev }; delete next[col.index]; return next; }); setOpenFilter(null); }} + onClose={() => setOpenFilter(null)} + /> + )} ))} @@ -582,8 +626,37 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, {/* Container columns */} {containerCols.map(col => ( - - {col.name} + +
+ {col.name} + +
+ {openFilter === `con_${col.index}` && ( + setDynamicColFilters(prev => { + const current = prev[col.index] || []; + return current.includes(val) + ? { ...prev, [col.index]: current.filter(v => v !== val) } + : { ...prev, [col.index]: [...current, val] }; + })} + onSelectAll={vals => setDynamicColFilters(prev => ({ ...prev, [col.index]: vals }))} + onClear={() => { setDynamicColFilters(prev => { const next = { ...prev }; delete next[col.index]; return next; }); setOpenFilter(null); }} + onClose={() => setOpenFilter(null)} + /> + )} ))}