11import { RemoteData } from 'src/app/core/data/remote-data' ;
22import { Injectable } from '@angular/core' ;
33
4- import { BehaviorSubject , combineLatest , Observable , of as observableOf } from 'rxjs' ;
5- import { map , merge , mergeMap , scan } from 'rxjs/operators' ;
4+ import { BehaviorSubject , combineLatest , EMPTY , Observable , of as observableOf } from 'rxjs' ;
5+ import { expand , map , merge , mergeMap , scan } from 'rxjs/operators' ;
66import findIndex from 'lodash/findIndex' ;
77
88import { LOAD_MORE_NODE , LOAD_MORE_ROOT_NODE , TreeviewFlatNode , TreeviewNode } from './vocabulary-treeview-node.model' ;
@@ -104,8 +104,9 @@ export class VocabularyTreeviewService {
104104 * @param initValueId The entry id of the node to mark as selected, if any
105105 * @param publicModeOnly Whether the tree is used in a public view
106106 * @param isRelationComponent Whether the tree is used as relation component
107+ * @param loadAll
107108 */
108- initialize ( options : VocabularyOptions , pageInfo : PageInfo , selectedItems : string [ ] , initValueId ?: string , publicModeOnly = false , isRelationComponent = false ) : void {
109+ initialize ( options : VocabularyOptions , pageInfo : PageInfo , selectedItems : string [ ] , initValueId ?: string , publicModeOnly = false , isRelationComponent = false , loadAll = false ) : void {
109110 this . loading . next ( true ) ;
110111 this . vocabularyOptions = options ;
111112 this . vocabularyName = options . name ;
@@ -116,8 +117,8 @@ export class VocabularyTreeviewService {
116117 if ( hasValue ( hierarchy ) && hierarchy . length > 0 ) {
117118 this . initValueHierarchy = hierarchy ;
118119 isRelationComponent ?
119- this . retrieveNodesTreeByTopParentEntry ( hierarchy [ 0 ] , pageInfo , selectedItems ) :
120- this . retrieveTopNodes ( pageInfo , [ ] , selectedItems , publicModeOnly ? hierarchy : null ) ;
120+ this . retrieveNodesTreeByTopParentEntry ( hierarchy [ 0 ] , pageInfo , selectedItems , loadAll ) :
121+ this . retrieveTopNodes ( pageInfo , [ ] , selectedItems , publicModeOnly ? hierarchy : null , loadAll ) ;
121122 } else {
122123 this . loading . next ( false ) ;
123124 }
@@ -150,22 +151,25 @@ export class VocabularyTreeviewService {
150151 * @param item
151152 * @param selectedItems
152153 * @param onlyFirstTime
154+ * @param loadAll
153155 */
154- loadMore ( item : VocabularyEntryDetail , selectedItems : string [ ] , onlyFirstTime = false ) {
156+ loadMore ( item : VocabularyEntryDetail , selectedItems : string [ ] , onlyFirstTime = false , loadAll = false ) {
155157 if ( ! this . nodeMap . has ( item . otherInformation . id ) ) {
156158 return ;
157159 }
158160 const parent : TreeviewNode = this . nodeMap . get ( item . otherInformation . id ) ! ;
159161 const children = this . nodeMap . get ( item . otherInformation . id ) ! . children || [ ] ;
160- this . getChildrenNodesByParent ( item . otherInformation . id , parent . pageInfo ) . subscribe ( ( list : PaginatedList < VocabularyEntryDetail > ) => {
161-
162- if ( onlyFirstTime && parent . children ! . length > 0 ) {
162+ this . getChildrenNodesByParent ( item . otherInformation . id , parent . pageInfo , ( loadAll && selectedItems . length > 0 ) ) . subscribe ( ( list : PaginatedList < VocabularyEntryDetail > ) => {
163+ if ( onlyFirstTime && parent . children ! . length > 0 && ! loadAll ) {
163164 return ;
164165 }
165166
166167 const newNodes : TreeviewNode [ ] = list . page . map ( ( entry ) => this . _generateNode ( entry , selectedItems ) ) ;
167168 if ( newNodes . length > 0 ) {
168- children . pop ( ) ;
169+ if ( ! loadAll ) {
170+ //remove load more button
171+ children . pop ( ) ;
172+ }
169173 children . push ( ...newNodes ) ;
170174 }
171175
@@ -175,11 +179,15 @@ export class VocabularyTreeviewService {
175179 currentPage : list . pageInfo . currentPage + 1
176180 } ) ;
177181 parent . updatePageInfo ( newPageInfo ) ;
182+ parent . childrenChange . next ( children ) ;
178183
179- // Need a new load more node
180- children . push ( new TreeviewNode ( LOAD_MORE_NODE , false , newPageInfo , item ) ) ;
184+ if ( ! ( loadAll && selectedItems . length > 0 ) ) {
185+ // if not all loaded add a load more button
186+ children . push ( new TreeviewNode ( LOAD_MORE_NODE , false , newPageInfo , item ) ) ;
187+ }
188+ } else {
189+ parent . childrenChange . next ( children ) ;
181190 }
182- parent . childrenChange . next ( children ) ;
183191 this . dataChange . next ( this . dataChange . value ) ;
184192 } ) ;
185193
@@ -289,14 +297,35 @@ export class VocabularyTreeviewService {
289297 * Return the vocabulary entry's children
290298 * @param parentId The node id
291299 * @param pageInfo The {@link PageInfo} object
300+ * @param loadAll
301+ * @param selectedItem
292302 * @return Observable<PaginatedList<VocabularyEntryDetail>>
293303 */
294- private getChildrenNodesByParent ( parentId : string , pageInfo : PageInfo ) : Observable < PaginatedList < VocabularyEntryDetail > > {
304+ private getChildrenNodesByParent ( parentId : string , pageInfo : PageInfo , loadAll = false ) : Observable < PaginatedList < VocabularyEntryDetail > > {
295305 return this . vocabularyService . getEntryDetailChildren ( parentId , this . vocabularyName , pageInfo ) . pipe (
296- getFirstSucceededRemoteDataPayload ( )
306+ getFirstSucceededRemoteDataPayload ( ) ,
307+ ) . pipe (
308+ expand ( res => this . getPaginatedChildren ( res , parentId , loadAll ) )
297309 ) ;
298310 }
299311
312+ /**
313+ * Get children recursively in expand to load all children
314+ * @param res
315+ * @param parentId
316+ * @param loadAll
317+ * @private
318+ */
319+ private getPaginatedChildren ( res : PaginatedList < VocabularyEntryDetail > , parentId : string , loadAll : boolean ) : Observable < PaginatedList < VocabularyEntryDetail > > {
320+ if ( res . pageInfo . currentPage + 1 <= res . pageInfo . totalPages && loadAll ) {
321+ const newPageInfo = Object . assign ( { } , res . pageInfo , { currentPage : res . pageInfo . currentPage + 1 } ) ;
322+ return this . vocabularyService . getEntryDetailChildren ( parentId , this . vocabularyName , newPageInfo ) . pipe (
323+ getFirstSucceededRemoteDataPayload ( )
324+ ) ;
325+ }
326+ return EMPTY ;
327+ }
328+
300329 /**
301330 * Return the vocabulary entry's parent
302331 * @param entryId The entry id
@@ -331,8 +360,9 @@ export class VocabularyTreeviewService {
331360 * @param nodes The top level nodes already loaded, if any
332361 * @param selectedItems The currently selected items
333362 * @param hierarchyToLimit If given the top nodes included will be only the one related to the hierarchy
363+ * @param loadAll
334364 */
335- private retrieveTopNodes ( pageInfo : PageInfo , nodes : TreeviewNode [ ] , selectedItems : string [ ] , hierarchyToLimit ?: string [ ] ) : void {
365+ private retrieveTopNodes ( pageInfo : PageInfo , nodes : TreeviewNode [ ] , selectedItems : string [ ] , hierarchyToLimit ?: string [ ] , loadAll = false ) : void {
336366 this . vocabularyService . searchTopEntries ( this . vocabularyName , pageInfo ) . pipe (
337367 getFirstSucceededRemoteDataPayload ( )
338368 ) . subscribe ( ( list : PaginatedList < VocabularyEntryDetail > ) => {
@@ -344,15 +374,20 @@ export class VocabularyTreeviewService {
344374 nodes . push ( ...newNodes ) ;
345375 }
346376
347-
348377 if ( ( list . pageInfo . currentPage + 1 ) <= list . pageInfo . totalPages ) {
349- // Need a new load more node
350378 const newPageInfo : PageInfo = Object . assign ( new PageInfo ( ) , list . pageInfo , {
351379 currentPage : list . pageInfo . currentPage + 1
352380 } ) ;
353- const loadMoreNode = new TreeviewNode ( LOAD_MORE_ROOT_NODE , false , newPageInfo ) ;
354- loadMoreNode . updatePageInfo ( newPageInfo ) ;
355- nodes . push ( loadMoreNode ) ;
381+
382+ if ( loadAll ) {
383+ // loop over pages until we load all of them
384+ this . retrieveTopNodes ( newPageInfo , nodes , selectedItems , hierarchyToLimit ) ;
385+ return ;
386+ } else {
387+ const loadMoreNode = new TreeviewNode ( LOAD_MORE_ROOT_NODE , false , newPageInfo ) ;
388+ loadMoreNode . updatePageInfo ( newPageInfo ) ;
389+ nodes . push ( loadMoreNode ) ;
390+ }
356391 }
357392 this . loading . next ( false ) ;
358393 // Notify the change.
@@ -365,23 +400,23 @@ export class VocabularyTreeviewService {
365400 * @param entry The root node to use to start building the tree
366401 * @param pageInfo The {@link PageInfo} object
367402 * @param selectedItems The currently selected items
403+ * @param loadAll
368404 */
369- private retrieveNodesTreeByTopParentEntry ( entry : string , pageInfo : PageInfo , selectedItems : string [ ] ) : void {
370- const nodes = [ ] ;
405+ private retrieveNodesTreeByTopParentEntry ( entry : string , pageInfo : PageInfo , selectedItems : string [ ] , loadAll = false ) : void {
371406 const rootNode$ = this . getById ( entry ) ;
372407 let tempList ;
373408
374409 combineLatest ( [
375410 rootNode$ ,
376- this . getChildrenNodesByParent ( entry , pageInfo )
411+ this . getChildrenNodesByParent ( entry , pageInfo , loadAll )
377412 ] ) . pipe (
378413 mergeMap ( ( [ rootNode , list ] ) => {
379414 tempList = list ;
380415 let newPageInfo : PageInfo ;
381416
382417 const childNodes : TreeviewNode [ ] = list . page . map ( ( entryDetail : VocabularyEntryDetail ) => this . _generateNode ( entryDetail , selectedItems ) ) ;
383418
384- if ( ( tempList . pageInfo . currentPage + 1 ) <= tempList . pageInfo . totalPages ) {
419+ if ( ( tempList . pageInfo . currentPage + 1 ) <= tempList . pageInfo . totalPages && ! loadAll ) {
385420 // Need a new load more node
386421 newPageInfo = Object . assign ( new PageInfo ( ) , tempList . pageInfo , {
387422 currentPage : tempList . pageInfo . currentPage + 1
@@ -398,11 +433,13 @@ export class VocabularyTreeviewService {
398433 ) ;
399434 } )
400435 ) . subscribe ( hierarchy => {
401- nodes . push ( hierarchy ) ;
402-
403- this . loading . next ( false ) ;
436+ // Loading stops if we reach the end of the list or if we are done with the first loading and don't need to load all.
437+ // Major or equal because rest seems bugged and return total pages 0 if there is only 1 element
438+ if ( ( tempList . pageInfo . currentPage >= tempList . pageInfo . totalPages && loadAll ) || ! loadAll ) {
439+ this . loading . next ( false ) ;
440+ }
404441 // Notify the change.
405- this . dataChange . next ( nodes ) ;
442+ this . dataChange . next ( [ hierarchy ] ) ;
406443
407444 } ) ;
408445
0 commit comments