diff --git a/components/DataGrid.tsx b/components/DataGrid.tsx index 114a41f..a7c2dc3 100644 --- a/components/DataGrid.tsx +++ b/components/DataGrid.tsx @@ -473,7 +473,7 @@ const DataGrid: React.FC = ({ 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 = ({ 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 = ({ data, filters, hasCustomerFilter, a return ( {/* Sell Out & Units */} - requestSort(`total_sellOut_${year}`)} - > -
- Sell Out {year} {getSortIcon(`total_sellOut_${year}`)} + +
+
requestSort(`total_sellOut_${year}`)} + > + Sell Out {year} {getSortIcon(`total_sellOut_${year}`)} +
+ String(r.totalsByYear[year]?.sellOut || 0)))).sort((a, b) => parseFloat(a as string) - parseFloat(b as string))} + currentFilter={columnFilters[`total_sellOut_${year}`]} + onFilterChange={handleColumnFilterChange} + />
- requestSort(`total_units_${year}`)} - > -
- Units {year} {getSortIcon(`total_units_${year}`)} + +
+
requestSort(`total_units_${year}`)} + > + Units {year} {getSortIcon(`total_units_${year}`)} +
+ String(r.totalsByYear[year]?.units || 0)))).sort((a, b) => parseFloat(a as string) - parseFloat(b as string))} + currentFilter={columnFilters[`total_units_${year}`]} + onFilterChange={handleColumnFilterChange} + />
diff --git a/components/ExcelFilter.tsx b/components/ExcelFilter.tsx index 766a7e4..381dd32 100644 --- a/components/ExcelFilter.tsx +++ b/components/ExcelFilter.tsx @@ -21,6 +21,10 @@ const OPERATORS = [ { label: 'No comienza por', value: 'notStartsWith' }, { label: 'Termina con', value: 'endsWith' }, { label: 'No termina con', value: 'notEndsWith' }, + { label: 'Mayor que', value: 'gt' }, + { label: 'Menor que', value: 'lt' }, + { label: 'Mayor o igual que', value: 'gte' }, + { label: 'Menor o igual que', value: 'lte' }, ] as const; export const ExcelFilter: React.FC = ({ diff --git a/types.ts b/types.ts index 4769d0d..21e986d 100644 --- a/types.ts +++ b/types.ts @@ -32,7 +32,7 @@ export interface FilterState { export interface ColumnFilterCondition { textFilter?: { - operator: 'equals' | 'notEquals' | 'contains' | 'notContains' | 'startsWith' | 'notStartsWith' | 'endsWith' | 'notEndsWith'; + operator: 'equals' | 'notEquals' | 'contains' | 'notContains' | 'startsWith' | 'notStartsWith' | 'endsWith' | 'notEndsWith' | 'gt' | 'lt' | 'gte' | 'lte'; value: string; }; selectedValues?: string[];