@@ -109,6 +109,32 @@ export class IdentitiesCrudController extends AbstractController {
109109 } ) ;
110110 }
111111
112+ /**
113+ * Construit le filtre Mongo commun aux listes d'identités (recherche plein texte + filtres `filters[...]`).
114+ * Le type `FilterSchema` est récursif (valeurs attendues) alors qu'on injecte ici des opérateurs Mongo,
115+ * d'où les casts `any` volontaires.
116+ */
117+ protected buildIdentitiesSearchFilter (
118+ search : string ,
119+ searchFilterSchema : FilterSchema ,
120+ searchFields : string | string [ ] ,
121+ ) : any {
122+ const searchFilters : any [ ] = [ ] ;
123+
124+ if ( search && search . trim ( ) . length > 0 ) {
125+ const effectiveSearchFields = mergeIdentitySearchFields ( searchFields ) ;
126+ searchFilters . push ( {
127+ $or : Object . keys ( effectiveSearchFields ) . map ( ( key ) => ( {
128+ [ key ] : { $regex : `^${ search } ` , $options : 'i' } ,
129+ } ) ) ,
130+ } ) ;
131+ }
132+
133+ searchFilters . push ( searchFilterSchema ) ;
134+
135+ return searchFilters . length === 1 ? searchFilters [ 0 ] : { $and : searchFilters } ;
136+ }
137+
112138 @Get ( 'getdeleted' )
113139 @UseRoles ( {
114140 resource : '/management/identities' ,
@@ -119,7 +145,9 @@ export class IdentitiesCrudController extends AbstractController {
119145 public async getdeleted (
120146 @Res ( ) res : Response ,
121147 @Query ( 'search' ) search : string ,
148+ @SearchFilterSchema ( ) searchFilterSchema : FilterSchema ,
122149 @SearchFilterOptions ( ) searchFilterOptions : FilterOptions ,
150+ @Query ( 'searchFields' ) searchFields : string | string [ ] ,
123151 ) : Promise <
124152 Response <
125153 {
@@ -132,7 +160,12 @@ export class IdentitiesCrudController extends AbstractController {
132160 any
133161 >
134162 > {
135- const [ data , total ] = await this . _service . trashAndCount ( IdentitiesCrudController . projection , searchFilterOptions ) ;
163+ const searchFilter = this . buildIdentitiesSearchFilter ( search , searchFilterSchema , searchFields ) ;
164+ const [ data , total ] = await this . _service . trashAndCount (
165+ searchFilter ,
166+ IdentitiesCrudController . projection ,
167+ searchFilterOptions ,
168+ ) ;
136169 return res . status ( HttpStatus . OK ) . json ( {
137170 statusCode : HttpStatus . OK ,
138171 total,
@@ -163,7 +196,6 @@ export class IdentitiesCrudController extends AbstractController {
163196 validations ?: MixedValue ;
164197 } >
165198 > {
166- const searchFilters = [ ] ;
167199 // Par défaut, on cache les identités "ne pas synchroniser" dans la recherche.
168200 // Si le client fournit déjà un filtre `state`, on ne l'écrase pas.
169201 // Le type `FilterSchema` est récursif (valeurs attendues), alors que pour Mongo on injecte parfois
@@ -173,19 +205,7 @@ export class IdentitiesCrudController extends AbstractController {
173205 effectiveSearchFilterSchema . state = { $ne : IdentityState . DONT_SYNC } ;
174206 }
175207
176- if ( search && search . trim ( ) . length > 0 ) {
177- const effectiveSearchFields = mergeIdentitySearchFields ( searchFields ) ;
178- const searchRequest = { } ;
179- searchRequest [ '$or' ] = Object . keys ( effectiveSearchFields )
180- . map ( ( key ) => {
181- return { [ key ] : { $regex : `^${ search } ` , $options : 'i' } } ;
182- } )
183- . filter ( ( item ) => item !== undefined ) ;
184- searchFilters . push ( searchRequest ) ;
185- searchFilters . push ( effectiveSearchFilterSchema ) ;
186- } else {
187- searchFilters . push ( effectiveSearchFilterSchema ) ;
188- }
208+ const searchFilters : any [ ] = [ this . buildIdentitiesSearchFilter ( search , effectiveSearchFilterSchema , searchFields ) ] ;
189209
190210 const expiredQuery = parseInitInvitationExpiredQuery ( initInvitationExpired ) ;
191211 if ( expiredQuery !== null ) {
0 commit comments