@@ -152,12 +152,17 @@ export class ProgramListComponent implements OnInit, OnDestroy, AfterViewInit {
152152 const scrollEvent$ = fromEvent ( target , "scroll" )
153153 . pipe (
154154 debounceTime ( this . listType === "rating" ? 200 : 500 ) ,
155- concatMap ( ( ) => this . onScroll ( ) ) ,
156- throttleTime ( this . listType === "rating" ? 2000 : 500 )
155+ switchMap ( ( ) => this . onScroll ( ) ) ,
156+ catchError ( err => {
157+ console . error ( "Scroll error:" , err ) ;
158+ return of ( { } ) ;
159+ } )
157160 )
158161 . subscribe ( noop ) ;
159162
160163 this . subscriptions$ . push ( scrollEvent$ ) ;
164+ } else {
165+ console . error ( ".office__body element not found" ) ;
161166 }
162167 }
163168
@@ -220,21 +225,17 @@ export class ProgramListComponent implements OnInit, OnDestroy, AfterViewInit {
220225
221226 const filtersObservable$ = this . route . queryParams
222227 . pipe (
228+ distinctUntilChanged ( ( prev , curr ) => JSON . stringify ( prev ) === JSON . stringify ( curr ) ) ,
223229 concatMap ( q => {
224230 const { filters, extraParams } = this . buildFilterQuery ( q ) ;
225231 const programId = this . route . parent ?. snapshot . params [ "programId" ] ;
226232
227- const filtersChanged =
228- JSON . stringify ( filters ) !== JSON . stringify ( this . previousReqQuery [ "filters" ] ) ;
229- const extraParamsChanged =
230- JSON . stringify ( extraParams ) !== JSON . stringify ( this . previousReqQuery [ "filters" ] ) ;
231-
232- this . previousReqQuery = { filters, extraParams } ;
233+ this . listPage = 0 ;
233234
234235 const params = new HttpParams ( {
235236 fromObject : {
236- offset : 0 ,
237- limit : this . itemsPerPage ,
237+ offset : "0" ,
238+ limit : this . itemsPerPage . toString ( ) ,
238239 ...extraParams ,
239240 } ,
240241 } ) ;
@@ -243,22 +244,24 @@ export class ProgramListComponent implements OnInit, OnDestroy, AfterViewInit {
243244 if ( Object . keys ( filters ) . length > 0 ) {
244245 return this . projectRatingService . postFilters ( programId , filters , params ) ;
245246 }
246-
247247 return this . projectRatingService . getAll ( programId , params ) ;
248248 }
249249
250250 if ( Object . keys ( filters ) . length > 0 ) {
251- return this . programService . createProgramFilters ( programId , filters ) ;
251+ return this . programService . createProgramFilters ( programId , filters , params ) ;
252252 }
253-
254253 return this . programService . getAllProjects ( programId , params ) ;
254+ } ) ,
255+ catchError ( err => {
256+ console . error ( "Error in setupFilters:" , err ) ;
257+ return of ( { count : 0 , results : [ ] } ) ;
255258 } )
256259 )
257260 . subscribe ( result => {
258261 if ( ! result ) return ;
259262
260- this . list = result . results ;
261- this . searchedList = result . results ;
263+ this . list = result . results || [ ] ;
264+ this . searchedList = result . results || [ ] ;
262265 this . listTotalCount = result . count ;
263266 this . listPage = 0 ;
264267 this . cdref . detectChanges ( ) ;
@@ -269,114 +272,205 @@ export class ProgramListComponent implements OnInit, OnDestroy, AfterViewInit {
269272
270273 // Универсальный метод скролла
271274 private onScroll ( ) {
272- if ( this . listTotalCount && this . list . length >= this . listTotalCount ) return of ( { } ) ;
275+ if ( this . listTotalCount && this . list . length >= this . listTotalCount ) {
276+ console . log ( "All items loaded" ) ;
277+ return of ( { } ) ;
278+ }
273279
274280 const target = document . querySelector ( ".office__body" ) ;
275- if ( ! target || ( this . listType !== "rating" && ! this . listRoot ) ) return of ( { } ) ;
281+ if ( ! target ) {
282+ console . log ( "Target not found" ) ;
283+ return of ( { } ) ;
284+ }
276285
277286 let shouldFetch = false ;
278287
279288 if ( this . listType === "rating" ) {
280- // Логика для rating
281289 const scrollBottom = target . scrollHeight - target . scrollTop - target . clientHeight ;
282- shouldFetch = scrollBottom <= 0 ;
290+ shouldFetch = scrollBottom <= 200 ;
291+ console . log ( "Rating scroll check:" , { scrollBottom, shouldFetch } ) ;
283292 } else {
284- // Логика для projects и members
293+ if ( ! this . listRoot ) return of ( { } ) ;
285294 const diff =
286295 target . scrollTop -
287- this . listRoot ! . nativeElement . getBoundingClientRect ( ) . height +
296+ this . listRoot . nativeElement . getBoundingClientRect ( ) . height +
288297 window . innerHeight ;
289298 const threshold = this . listType === "projects" ? - 200 : 0 ;
290299 shouldFetch = diff > threshold ;
300+ console . log ( "Projects/Members scroll check:" , { diff, threshold, shouldFetch } ) ;
291301 }
292302
293303 if ( shouldFetch ) {
304+ console . log ( "Fetching next page:" , this . listPage + 1 ) ;
294305 this . listPage ++ ;
295306 return this . onFetch ( ) ;
296307 }
297308
298309 return of ( { } ) ;
299310 }
300311
312+ // Универсальный метод загрузки данных
301313 // Универсальный метод загрузки данных
302314 private onFetch ( ) {
303315 const programId = this . route . parent ?. snapshot . params [ "programId" ] ;
304316 const offset = this . listPage * this . itemsPerPage ;
305317
318+ console . log ( "onFetch called:" , {
319+ listType : this . listType ,
320+ programId,
321+ offset,
322+ itemsPerPage : this . itemsPerPage ,
323+ currentPage : this . listPage ,
324+ currentListLength : this . list . length ,
325+ } ) ;
326+
327+ // Получаем текущие query параметры для фильтров
328+ const currentQuery = this . route . snapshot . queryParams ;
329+ const { filters, extraParams } = this . buildFilterQuery ( currentQuery ) ;
330+
331+ const params = new HttpParams ( {
332+ fromObject : {
333+ offset : offset . toString ( ) ,
334+ limit : this . itemsPerPage . toString ( ) ,
335+ ...extraParams ,
336+ } ,
337+ } ) ;
338+
339+ console . log ( "Request params:" , { filters, extraParams, paramsKeys : params . keys ( ) } ) ;
340+
306341 switch ( this . listType ) {
307- case "projects" :
308- return this . programService
309- . getAllProjects (
310- programId ,
311- new HttpParams ( { fromObject : { offset, limit : this . itemsPerPage } } )
312- )
313- . pipe (
314- tap ( ( projects : ApiPagination < Project > ) => {
315- this . listTotalCount = projects . count ;
316- if ( this . listPage === 0 ) {
317- this . list = projects . results ;
318- } else {
319- this . list = [ ...this . list , ...projects . results ] ;
320- }
321- this . searchedList = this . list ;
322- this . cdref . detectChanges ( ) ;
323- } )
324- ) ;
342+ case "rating" : {
343+ const ratingRequest$ =
344+ Object . keys ( filters ) . length > 0
345+ ? this . projectRatingService . postFilters ( programId , filters , params )
346+ : this . projectRatingService . getAll ( programId , params ) ;
347+
348+ return ratingRequest$ . pipe (
349+ tap ( ( { count, results } ) => {
350+ console . log ( "Rating response:" , {
351+ count,
352+ resultsLength : results . length ,
353+ currentListLength : this . list . length ,
354+ offset,
355+ expectedNewLength : this . list . length + results . length ,
356+ } ) ;
357+
358+ this . listTotalCount = count ;
325359
326- case "members" :
360+ if ( this . listPage === 0 ) {
361+ this . list = results ;
362+ } else {
363+ const newResults = results . filter (
364+ newItem => ! this . list . some ( existingItem => existingItem . id === newItem . id )
365+ ) ;
366+ console . log ( "New unique items to add:" , newResults . length ) ;
367+ this . list = [ ...this . list , ...newResults ] ;
368+ }
369+
370+ this . searchedList = this . list ;
371+ this . cdref . detectChanges ( ) ;
372+ } ) ,
373+ catchError ( err => {
374+ console . error ( "Error fetching ratings:" , err ) ;
375+ this . listPage -- ;
376+ return of ( { count : this . listTotalCount || 0 , results : [ ] } ) ;
377+ } )
378+ ) ;
379+ }
380+
381+ case "projects" : {
382+ const projectsRequest$ =
383+ Object . keys ( filters ) . length > 0
384+ ? this . programService . createProgramFilters ( programId , filters , params )
385+ : this . programService . getAllProjects ( programId , params ) ;
386+
387+ return projectsRequest$ . pipe (
388+ tap ( ( projects : ApiPagination < Project > ) => {
389+ console . log ( "Projects response:" , {
390+ count : projects . count ,
391+ resultsLength : projects . results . length ,
392+ currentListLength : this . list . length ,
393+ offset,
394+ } ) ;
395+
396+ this . listTotalCount = projects . count ;
397+
398+ if ( this . listPage === 0 ) {
399+ this . list = projects . results ;
400+ } else {
401+ const newResults = projects . results . filter (
402+ newItem => ! this . list . some ( existingItem => existingItem . id === newItem . id )
403+ ) ;
404+ console . log ( "New unique projects to add:" , newResults . length ) ;
405+ this . list = [ ...this . list , ...newResults ] ;
406+ }
407+
408+ this . searchedList = this . list ;
409+ this . cdref . detectChanges ( ) ;
410+ } ) ,
411+ catchError ( err => {
412+ console . error ( "Error fetching projects:" , err ) ;
413+ this . listPage -- ;
414+ return of ( { count : this . listTotalCount || 0 , results : [ ] } ) ;
415+ } )
416+ ) ;
417+ }
418+
419+ case "members" : {
327420 return this . programService . getAllMembers ( programId , offset , this . itemsPerPage ) . pipe (
328421 tap ( ( members : ApiPagination < User > ) => {
422+ console . log ( "Members response:" , {
423+ count : members . count ,
424+ resultsLength : members . results . length ,
425+ currentListLength : this . list . length ,
426+ offset,
427+ } ) ;
428+
329429 this . listTotalCount = members . count ;
430+
330431 if ( this . listPage === 0 ) {
331432 this . list = members . results ;
332433 } else {
333- this . list = [ ...this . list , ...members . results ] ;
434+ const newResults = members . results . filter (
435+ newItem => ! this . list . some ( existingItem => existingItem . id === newItem . id )
436+ ) ;
437+ console . log ( "New unique members to add:" , newResults . length ) ;
438+ this . list = [ ...this . list , ...newResults ] ;
334439 }
440+
335441 this . searchedList = this . list ;
336442 this . cdref . detectChanges ( ) ;
443+ } ) ,
444+ catchError ( err => {
445+ console . error ( "Error fetching members:" , err ) ;
446+ this . listPage -- ;
447+ return of ( { count : this . listTotalCount || 0 , results : [ ] } ) ;
337448 } )
338449 ) ;
339-
340- case "rating" :
341- return this . projectRatingService
342- . getAll ( programId , new HttpParams ( { fromObject : { offset, limit : this . itemsPerPage } } ) )
343- . pipe (
344- tap ( ( { count, results } ) => {
345- this . listTotalCount = count ;
346- if ( this . listPage === 0 ) {
347- this . list = results ;
348- } else {
349- this . list = [ ...this . list , ...results ] ;
350- }
351- this . searchedList = this . list ;
352- this . cdref . detectChanges ( ) ;
353- } )
354- ) ;
450+ }
355451
356452 default :
357- return of ( { } ) ;
453+ return of ( { count : 0 , results : [ ] } ) ;
358454 }
359455 }
360456
361457 // Построение запроса для фильтров (кроме участников)
362- private buildFilterQuery ( q : any ) : Record < string , any > {
363- if ( this . listType === "members" ) return { } ;
458+ private buildFilterQuery ( q : any ) : {
459+ filters : Record < string , any > ;
460+ extraParams : Record < string , any > ;
461+ } {
462+ if ( this . listType === "members" ) return { filters : { } , extraParams : { } } ;
364463
365- const filters : Record < string , any [ ] > = { } ;
464+ const filters : Record < string , any > = { } ;
366465 const extraParams : Record < string , any > = { } ;
367466
467+ console . log ( "buildFilterQuery input:" , q ) ;
468+
368469 Object . keys ( q ) . forEach ( key => {
369470 const value = q [ key ] ;
370- if ( value === undefined || value === "" ) return ;
371-
372- // ⭐ Для rating search → name__contains
373- if ( this . listType === "rating" && key === "search" ) {
374- extraParams [ "name__contains" ] = value ;
375- return ;
376- }
471+ if ( value === undefined || value === "" || value === null ) return ;
377472
378- // ⭐ Эти два ключа должны идти ТОЛЬКО как GET-параметры
379- if ( this . listType === "rating" && key === "name__contains" ) {
473+ if ( this . listType === "rating" && ( key === "search" || key === "name__contains" ) ) {
380474 extraParams [ "name__contains" ] = value ;
381475 return ;
382476 }
@@ -386,7 +480,6 @@ export class ProgramListComponent implements OnInit, OnDestroy, AfterViewInit {
386480 return ;
387481 }
388482
389- // ⭐ Для других ключей: обычные filters
390483 filters [ key ] = Array . isArray ( value ) ? value : [ value ] ;
391484 } ) ;
392485
@@ -460,7 +553,7 @@ export class ProgramListComponent implements OnInit, OnDestroy, AfterViewInit {
460553
461554 private get itemsPerPage ( ) : number {
462555 return this . listType === "rating"
463- ? 8
556+ ? 10
464557 : this . listType === "projects"
465558 ? this . perPage
466559 : this . listTake ;
0 commit comments