mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 12:25:22 +02:00
Enhance Excel-style filters with numeric operators and integrate into GRID metrics (Sell Out, Units)
This commit is contained in:
+70
-13
@@ -473,7 +473,7 @@ const DataGrid: React.FC<DataGridProps> = ({ data, filters, hasCustomerFilter, a
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Filter
|
||||
// 1. Filter (Legacy Row Filters)
|
||||
if (rowFilters.length > 0) {
|
||||
result = result.filter(row => {
|
||||
return rowFilters.every(filter => {
|
||||
@@ -512,6 +512,45 @@ const DataGrid: React.FC<DataGridProps> = ({ data, filters, hasCustomerFilter, a
|
||||
});
|
||||
}
|
||||
|
||||
// 1b. Filter (New Excel Column Filters for Metrics)
|
||||
(Object.entries(columnFilters) as [string, ColumnFilterCondition][]).forEach(([key, condition]) => {
|
||||
if (!condition) return;
|
||||
if (!key.startsWith('total_')) return; // Metric filters in this view start with 'total_'
|
||||
|
||||
const isSellOut = key.includes('_sellOut_');
|
||||
const year = key.split('_')[2];
|
||||
|
||||
if (condition.selectedValues && condition.selectedValues.length > 0) {
|
||||
result = result.filter(row => {
|
||||
const val = isSellOut ? row.totalsByYear[year]?.sellOut : row.totalsByYear[year]?.units;
|
||||
return condition.selectedValues?.includes(String(val || 0));
|
||||
});
|
||||
}
|
||||
|
||||
if (condition.textFilter) {
|
||||
const { operator, value } = condition.textFilter;
|
||||
const filterNum = parseFloat(value);
|
||||
if (isNaN(filterNum)) return;
|
||||
|
||||
result = result.filter(row => {
|
||||
const rowVal = (isSellOut ? row.totalsByYear[year]?.sellOut : row.totalsByYear[year]?.units) || 0;
|
||||
switch (operator) {
|
||||
case 'equals': return rowVal === filterNum;
|
||||
case 'notEquals': return rowVal !== filterNum;
|
||||
case 'gt': return rowVal > filterNum;
|
||||
case 'lt': return rowVal < filterNum;
|
||||
case 'gte': return rowVal >= filterNum;
|
||||
case 'lte': return rowVal <= filterNum;
|
||||
// Text-like operators on numeric values (convert to string)
|
||||
case 'contains': return String(rowVal).includes(value);
|
||||
case 'startsWith': return String(rowVal).startsWith(value);
|
||||
case 'endsWith': return String(rowVal).endsWith(value);
|
||||
default: return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 2. Sort
|
||||
if (sortConfig.key) {
|
||||
// Create a copy to avoid mutating the original array and ensure React detects the change
|
||||
@@ -1244,20 +1283,38 @@ const DataGrid: React.FC<DataGridProps> = ({ data, filters, hasCustomerFilter, a
|
||||
return (
|
||||
<React.Fragment key={year}>
|
||||
{/* Sell Out & Units */}
|
||||
<th
|
||||
className="px-4 py-3 border-b border-border text-right cursor-pointer hover:text-white bg-slate-950 min-w-[100px]"
|
||||
onClick={() => requestSort(`total_sellOut_${year}`)}
|
||||
>
|
||||
<div className="flex items-center justify-end">
|
||||
Sell Out {year} {getSortIcon(`total_sellOut_${year}`)}
|
||||
<th className="px-4 py-3 border-b border-border text-right bg-slate-950 min-w-[120px]">
|
||||
<div className="flex items-center justify-end gap-2">
|
||||
<div
|
||||
className="flex items-center cursor-pointer hover:text-white"
|
||||
onClick={() => requestSort(`total_sellOut_${year}`)}
|
||||
>
|
||||
Sell Out {year} {getSortIcon(`total_sellOut_${year}`)}
|
||||
</div>
|
||||
<ExcelFilter
|
||||
columnKey={`total_sellOut_${year}`}
|
||||
title={`Sell Out ${year}`}
|
||||
uniqueValues={Array.from(new Set(pivotRows.map(r => String(r.totalsByYear[year]?.sellOut || 0)))).sort((a, b) => parseFloat(a as string) - parseFloat(b as string))}
|
||||
currentFilter={columnFilters[`total_sellOut_${year}`]}
|
||||
onFilterChange={handleColumnFilterChange}
|
||||
/>
|
||||
</div>
|
||||
</th>
|
||||
<th
|
||||
className="px-4 py-3 border-b border-border text-right cursor-pointer hover:text-white bg-slate-950 min-w-[80px]"
|
||||
onClick={() => requestSort(`total_units_${year}`)}
|
||||
>
|
||||
<div className="flex items-center justify-end">
|
||||
Units {year} {getSortIcon(`total_units_${year}`)}
|
||||
<th className="px-4 py-3 border-b border-border text-right bg-slate-950 min-w-[100px]">
|
||||
<div className="flex items-center justify-end gap-2">
|
||||
<div
|
||||
className="flex items-center cursor-pointer hover:text-white"
|
||||
onClick={() => requestSort(`total_units_${year}`)}
|
||||
>
|
||||
Units {year} {getSortIcon(`total_units_${year}`)}
|
||||
</div>
|
||||
<ExcelFilter
|
||||
columnKey={`total_units_${year}`}
|
||||
title={`Units ${year}`}
|
||||
uniqueValues={Array.from(new Set(pivotRows.map(r => String(r.totalsByYear[year]?.units || 0)))).sort((a, b) => parseFloat(a as string) - parseFloat(b as string))}
|
||||
currentFilter={columnFilters[`total_units_${year}`]}
|
||||
onFilterChange={handleColumnFilterChange}
|
||||
/>
|
||||
</div>
|
||||
</th>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user