1- import { ChangeDetectorRef , Component , EventEmitter , Input , OnInit , Output } from '@angular/core' ;
1+ import { ChangeDetectorRef , Component , EventEmitter , Input , OnDestroy , OnInit , Output } from '@angular/core' ;
22import { UntypedFormGroup , ValidatorFn , ValidationErrors , AbstractControl } from '@angular/forms' ;
33import {
44 DynamicCheckboxModel ,
@@ -17,7 +17,7 @@ import { getFirstSucceededRemoteDataPayload } from '../../../../../../core/share
1717import { PaginatedList } from '../../../../../../core/data/paginated-list.model' ;
1818import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry.model' ;
1919import { PageInfo } from '../../../../../../core/shared/page-info.model' ;
20- import { BehaviorSubject , EMPTY , expand , map , reduce , tap } from "rxjs" ;
20+ import { BehaviorSubject , EMPTY , expand , map , reduce , Subscription , tap } from "rxjs" ;
2121
2222export interface ListItem {
2323 id : string ;
@@ -34,7 +34,7 @@ export interface ListItem {
3434 styleUrls : [ './dynamic-list.component.scss' ] ,
3535 templateUrl : './dynamic-list.component.html'
3636} )
37- export class DsDynamicListComponent extends DynamicFormControlComponent implements OnInit {
37+ export class DsDynamicListComponent extends DynamicFormControlComponent implements OnInit , OnDestroy {
3838
3939 @Input ( ) group : UntypedFormGroup ;
4040 @Input ( ) model : any ;
@@ -44,9 +44,10 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
4444 @Output ( ) focus : EventEmitter < any > = new EventEmitter < any > ( ) ;
4545
4646 public items : ListItem [ ] [ ] = [ ] ;
47- public showLoadMore $ : BehaviorSubject < boolean > = new BehaviorSubject < boolean > ( false ) ;
47+ public isLoading $ : BehaviorSubject < boolean > = new BehaviorSubject < boolean > ( true ) ;
4848 protected optionsList : VocabularyEntry [ ] = [ ] ;
4949 private nextPageInfo : PageInfo ;
50+ private subs : Subscription [ ] = [ ] ;
5051
5152 constructor ( private vocabularyService : VocabularyService ,
5253 private cdr : ChangeDetectorRef ,
@@ -66,6 +67,12 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
6667 }
6768 }
6869
70+ ngOnDestroy ( ) {
71+ if ( this . subs . length > 0 ) {
72+ this . subs . forEach ( sub => sub . unsubscribe ( ) ) ;
73+ }
74+ }
75+
6976 /**
7077 * Emits a blur event containing a given value.
7178 * @param event The value to emit.
@@ -140,9 +147,9 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
140147 setPaginationInfo ( response : PaginatedList < VocabularyEntry > ) {
141148 if ( response . pageInfo . currentPage < response . pageInfo . totalPages ) {
142149 this . nextPageInfo = Object . assign ( new PageInfo ( ) , response . pageInfo , { currentPage : response . currentPage + 1 } ) ;
143- this . showLoadMore $. next ( true ) ;
150+ this . isLoading $. next ( true ) ;
144151 } else {
145- this . showLoadMore $. next ( false ) ;
152+ this . isLoading $. next ( false ) ;
146153 }
147154 }
148155
@@ -156,47 +163,53 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
156163 listGroup = this . group . controls [ this . model . id ] as UntypedFormGroup ;
157164 }
158165
159- this . vocabularyService . getVocabularyEntries ( this . model . vocabularyOptions , this . nextPageInfo ) . pipe (
160- getFirstSucceededRemoteDataPayload ( ) ,
161- tap ( ( response ) => this . setPaginationInfo ( response ) ) ,
162- map ( entries => entries . page ) ,
163- ) . subscribe ( ( allEntries : VocabularyEntry [ ] ) => {
164- this . optionsList = [ ...this . optionsList , ...allEntries ] ;
165- let groupCounter = ( this . items . length > 0 ) ? ( this . items . length - 1 ) : 0 ;
166- let itemsPerGroup = 0 ;
167- let tempList : ListItem [ ] = [ ] ;
168-
169- // Make a list of available options (checkbox/radio) and split in groups of 'model.groupLength'
170- allEntries . forEach ( ( option : VocabularyEntry , key : number ) => {
171- const value = option . authority || option . value ;
172- const checked : boolean = isNotEmpty ( findKey (
173- this . model . value ,
174- ( v ) => v ?. value === option . value ) ) ;
175-
176- const item : ListItem = {
177- id : `${ this . model . id } _${ value } ` ,
178- label : option . display ,
179- value : checked ,
180- index : key ,
181- } ;
182- if ( this . model . repeatable ) {
183- this . formBuilderService . addFormGroupControl ( listGroup , ( this . model as DynamicListCheckboxGroupModel ) , new DynamicCheckboxModel ( item ) ) ;
184- } else {
185- ( this . model as DynamicListRadioGroupModel ) . options . push ( {
186- label : item . label ,
187- value : option ,
188- } ) ;
189- }
190- tempList . push ( item ) ;
191- itemsPerGroup ++ ;
192- this . items [ groupCounter ] = tempList ;
193- if ( itemsPerGroup === this . model . groupLength ) {
194- groupCounter ++ ;
195- itemsPerGroup = 0 ;
196- tempList = [ ] ;
166+ this . subs . push (
167+ this . vocabularyService . getVocabularyEntries ( this . model . vocabularyOptions , this . nextPageInfo ) . pipe (
168+ getFirstSucceededRemoteDataPayload ( ) ,
169+ tap ( ( response ) => this . setPaginationInfo ( response ) ) ,
170+ map ( entries => entries . page ) ,
171+ ) . subscribe ( ( allEntries : VocabularyEntry [ ] ) => {
172+ this . optionsList = [ ...this . optionsList , ...allEntries ] ;
173+ let groupCounter = this . items . length ;
174+ let itemsPerGroup = 0 ;
175+ let tempList : ListItem [ ] = [ ] ;
176+
177+ // Make a list of available options (checkbox/radio) and split in groups of 'model.groupLength'
178+ allEntries . forEach ( ( option : VocabularyEntry ) => {
179+ const value = option . authority || option . value ;
180+ const checked : boolean = isNotEmpty ( findKey (
181+ this . model . value ,
182+ ( v ) => v ?. value === option . value ) ) ;
183+
184+ const item : ListItem = {
185+ id : `${ this . model . id } _${ value } ` ,
186+ label : option . display ,
187+ value : checked ,
188+ index : this . optionsList . indexOf ( option ) ,
189+ } ;
190+ if ( this . model . repeatable ) {
191+ this . formBuilderService . addFormGroupControl ( listGroup , ( this . model as DynamicListCheckboxGroupModel ) , new DynamicCheckboxModel ( item ) ) ;
192+ } else {
193+ ( this . model as DynamicListRadioGroupModel ) . options . push ( {
194+ label : item . label ,
195+ value : option ,
196+ } ) ;
197+ }
198+ tempList . push ( item ) ;
199+ itemsPerGroup ++ ;
200+ this . items [ groupCounter ] = tempList ;
201+ if ( itemsPerGroup === this . model . groupLength ) {
202+ groupCounter ++ ;
203+ itemsPerGroup = 0 ;
204+ tempList = [ ] ;
205+ }
206+ } ) ;
207+ this . cdr . markForCheck ( ) ;
208+ // If the paginated request did not reach the end keep loading the entries in the background
209+ if ( this . isLoading$ . value ) {
210+ this . loadEntries ( ) ;
197211 }
198- } ) ;
199- this . cdr . markForCheck ( ) ;
200- } ) ;
212+ } ) ,
213+ ) ;
201214 }
202215}
0 commit comments