@@ -2,12 +2,13 @@ import { FilteringLogic, type IFilteringExpression } from './filtering-expressio
22import { FilteringExpressionsTree , type IFilteringExpressionsTree } from './filtering-expressions-tree' ;
33import { resolveNestedPath , parseDate , formatDate , formatCurrency , columnFieldPath } from '../core/utils' ;
44import type { ColumnType , EntityType , GridType } from '../grids/common/grid.interface' ;
5- import { GridColumnDataType } from './data-util' ;
5+ import { DataUtil , GridColumnDataType } from './data-util' ;
66import { SortingDirection } from './sorting-strategy' ;
77import { formatNumber , formatPercent , getLocaleCurrencyCode } from '@angular/common' ;
88import type { IFilteringState } from './filtering-state.interface' ;
99import { isTree } from './expressions-tree-util' ;
1010import type { IgxHierarchicalGridComponent } from '../grids/hierarchical-grid/hierarchical-grid.component' ;
11+ import { IgxSorting } from '../grids/common/strategy' ;
1112
1213const DateType = 'date' ;
1314const DateTimeType = 'dateTime' ;
@@ -132,27 +133,35 @@ export abstract class BaseFilteringStrategy implements IFilteringStrategy {
132133 public getFilterItems ( column : ColumnType , tree : IFilteringExpressionsTree ) : Promise < IgxFilterItem [ ] > {
133134 const applyFormatter = column . formatter && this . shouldFormatFilterValues ( column ) ;
134135
135- let data = column . grid . gridAPI . filterDataByExpressions ( tree ) ;
136- data = column . grid . gridAPI . sortDataByExpressions ( data ,
137- [ { fieldName : column . field , dir : SortingDirection . Asc , ignoreCase : column . sortingIgnoreCase } ] ) ;
138-
136+ const data = this . getFilteredData ( column , tree ) ;
139137
140138 const pathParts = columnFieldPath ( column . field )
141- let filterItems : IgxFilterItem [ ] = data . map ( record => {
142- const value = applyFormatter ?
143- column . formatter ( resolveNestedPath ( record , pathParts ) , record ) :
144- resolveNestedPath ( record , pathParts ) ;
145-
146- return {
147- value,
148- label : this . getFilterItemLabel ( column , value , ! applyFormatter , record )
149- } ;
150- } ) ;
151- filterItems = this . getUniqueFilterItems ( column , filterItems ) ;
139+ const seenFormattedFilterItems = new Map < any , IgxFilterItem > ( )
140+
141+ for ( let i = 0 ; i < data . length ; ++ i ) {
142+ const record = data [ i ]
143+ const rawValue = resolveNestedPath ( record , pathParts ) ;
144+ const formattedValue = applyFormatter ? column . formatter ( rawValue , record ) : rawValue ;
145+ const { key, finalValue } = this . getFilterItemKeyValue ( formattedValue , column ) ;
146+ // Deduplicate by normalized key
147+ if ( ! seenFormattedFilterItems . has ( key ) ) {
148+ const label = this . getFilterItemLabel ( column , finalValue , ! applyFormatter , record ) ;
149+ seenFormattedFilterItems . set ( key , { value : finalValue , label } ) ;
150+ }
151+ }
152+
153+ let filterItems : IgxFilterItem [ ] = Array . from ( seenFormattedFilterItems . values ( ) ) ;
154+
155+ filterItems = DataUtil . sort ( filterItems ,
156+ [ { fieldName : 'value' , dir : SortingDirection . Asc , ignoreCase : column . sortingIgnoreCase } ] , new IgxSorting ( ) )
152157
153158 return Promise . resolve ( filterItems ) ;
154159 }
155160
161+ protected getFilteredData ( column : ColumnType , tree : IFilteringExpressionsTree ) {
162+ return column . grid . gridAPI . filterDataByExpressions ( tree ) ;
163+ }
164+
156165 protected getFilterItemLabel ( column : ColumnType , value : any , applyFormatter : boolean , data : any ) {
157166 if ( column . formatter ) {
158167 if ( applyFormatter ) {
@@ -180,30 +189,33 @@ export abstract class BaseFilteringStrategy implements IFilteringStrategy {
180189 }
181190 }
182191
183- protected getUniqueFilterItems ( column : ColumnType , filterItems : IgxFilterItem [ ] ) {
184- const filteredUniqueValues = filterItems . reduce ( ( map , item ) => {
185- let key = item . value ;
186-
187- if ( column . dataType === GridColumnDataType . String && column . filteringIgnoreCase ) {
188- key = key ?. toString ( ) . toLowerCase ( ) ;
189- } else if ( column . dataType === GridColumnDataType . DateTime ) {
190- key = item . value ?. toString ( ) ;
191- item . value = key ? new Date ( key ) : key ;
192- } else if ( column . dataType === GridColumnDataType . Time ) {
193- const date = key ? new Date ( key ) : key ;
194- key = date ? new Date ( ) . setHours ( date . getHours ( ) , date . getMinutes ( ) , date . getSeconds ( ) , date . getMilliseconds ( ) ) : key ;
195- item . value = key ? new Date ( key ) : key ;
196- } else if ( column . dataType === GridColumnDataType . Date ) {
197- const date = key ? new Date ( key ) : key ;
198- key = date ? new Date ( date . getFullYear ( ) , date . getMonth ( ) , date . getDate ( ) ) . toISOString ( ) : key ;
199- item . value = date ;
200- }
201-
202- return map . has ( key ) ? map : map . set ( key , item )
203- } , new Map ( ) ) ;
204- const uniqueValues = Array . from ( filteredUniqueValues . values ( ) ) ;
205-
206- return uniqueValues ;
192+ protected getFilterItemKeyValue ( value : any , column : ColumnType ) {
193+ let key : any = value ;
194+ let finalValue = value ;
195+ if ( column . dataType === GridColumnDataType . String && column . filteringIgnoreCase ) {
196+ key = key ?. toString ( ) . toLowerCase ( ) ;
197+ } else if ( column . dataType === GridColumnDataType . DateTime ) {
198+ key = value ?. toString ( ) ;
199+ finalValue = key ? new Date ( key ) : key ;
200+ } else if ( column . dataType === GridColumnDataType . Time ) {
201+ const date = key ? new Date ( key ) : key ;
202+ key = date
203+ ? new Date ( ) . setHours (
204+ date . getHours ( ) ,
205+ date . getMinutes ( ) ,
206+ date . getSeconds ( ) ,
207+ date . getMilliseconds ( )
208+ )
209+ : date ;
210+ finalValue = key ? new Date ( key ) : key ;
211+ } else if ( column . dataType === GridColumnDataType . Date ) {
212+ const date = key ? new Date ( key ) : key ;
213+ key = date
214+ ? new Date ( date . getFullYear ( ) , date . getMonth ( ) , date . getDate ( ) ) . toISOString ( )
215+ : date ;
216+ finalValue = date ;
217+ }
218+ return { key, finalValue } ;
207219 }
208220
209221 protected shouldFormatFilterValues ( _column : ColumnType ) : boolean {
0 commit comments