diff --git a/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.spec.ts b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.spec.ts index 9197875ea4..c9349c5916 100644 --- a/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.spec.ts +++ b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.spec.ts @@ -21,6 +21,7 @@ import { VocabularyEntry } from '../../../core/submission/vocabularies/models/vo import { VocabularyEntryDetail } from '../../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; import { VocabularyOptions } from '../../../core/submission/vocabularies/models/vocabulary-options.model'; import { VocabularyService } from '../../../core/submission/vocabularies/vocabulary.service'; +import { createSuccessfulRemoteDataObject$ } from '../../remote-data.utils'; import { createTestComponent } from '../../testing/utils.test'; import { FormFieldMetadataValueObject } from '../builder/models/form-field-metadata-value.model'; import { VocabularyTreeviewComponent } from './vocabulary-treeview.component'; @@ -63,6 +64,7 @@ describe('VocabularyTreeviewComponent test suite', () => { searchTopEntries: jasmine.createSpy('searchTopEntries'), getEntryDetailChildren: jasmine.createSpy('getEntryDetailChildren'), clearSearchTopRequests: jasmine.createSpy('clearSearchTopRequests'), + findVocabularyById: createSuccessfulRemoteDataObject$({ preloadLevel: 2 }), }); beforeEach(waitForAsync(() => { diff --git a/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.ts b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.ts index 89d908ec7f..18ff87ce53 100644 --- a/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.ts +++ b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.ts @@ -25,8 +25,17 @@ import { Observable, Subscription, } from 'rxjs'; +import { + map, + switchMap, + tap, +} from 'rxjs/operators'; +import { VocabularyService } from 'src/app/core/submission/vocabularies/vocabulary.service'; +import { RemoteData } from '../../../core/data/remote-data'; +import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; import { PageInfo } from '../../../core/shared/page-info.model'; +import { Vocabulary } from '../../../core/submission/vocabularies/models/vocabulary.model'; import { VocabularyEntry } from '../../../core/submission/vocabularies/models/vocabulary-entry.model'; import { VocabularyEntryDetail } from '../../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; import { VocabularyOptions } from '../../../core/submission/vocabularies/models/vocabulary-options.model'; @@ -168,6 +177,7 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges */ constructor( private vocabularyTreeviewService: VocabularyTreeviewService, + protected vocabularyService: VocabularyService, ) { this.treeFlattener = new VocabularyTreeFlattener(this.transformer, this.getLevel, this.isExpandable, this.getChildren); @@ -209,12 +219,20 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges ); this.nodeMap.set(entryId, newNode); - if ((((level + 1) < this.preloadLevel) && newNode.childrenLoaded) + if ((((level + 1) < this.preloadLevel)) || (newNode.isSearchNode && newNode.childrenLoaded) || newNode.isInInitValueHierarchy) { - if (!newNode.isSearchNode) { + + if (newNode.item.id === LOAD_MORE || newNode.item.id === LOAD_MORE_ROOT) { + // When a 'LOAD_MORE' node is encountered, the parent already has a lot of expanded children + // so this is a good point to stop expanding. + return newNode; + } + + if (!newNode.childrenLoaded) { this.loadChildren(newNode); } + this.treeControl.expand(newNode); } return newNode; @@ -255,15 +273,31 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges */ ngOnInit(): void { this.subs.push( - this.vocabularyTreeviewService.getData().subscribe((data) => { + this.vocabularyService.findVocabularyById(this.vocabularyOptions.name).pipe( + // Retrieve the configured preloadLevel from REST + getFirstCompletedRemoteData(), + map((vocabularyRD: RemoteData) => { + if (vocabularyRD.hasSucceeded && + hasValue(vocabularyRD.payload.preloadLevel) && + vocabularyRD.payload.preloadLevel > 1) { + return vocabularyRD.payload.preloadLevel; + } else { + // Set preload level to 1 in case request fails + return 1; + } + }), + tap(preloadLevel => this.preloadLevel = preloadLevel), + tap(() => { + const entryId: string = (this.selectedItems?.length > 0) ? this.getEntryId(this.selectedItems[0]) : null; + this.vocabularyTreeviewService.initialize(this.vocabularyOptions, new PageInfo(), this.getSelectedEntryIds(), entryId); + }), + switchMap(() => this.vocabularyTreeviewService.getData()), + ).subscribe((data) => { this.dataSource.data = data; }), ); this.loading = this.vocabularyTreeviewService.isLoading(); - - const entryId: string = (this.selectedItems?.length > 0) ? this.getEntryId(this.selectedItems[0]) : null; - this.vocabularyTreeviewService.initialize(this.vocabularyOptions, new PageInfo(), this.getSelectedEntryIds(), entryId); } /**