mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
Merge pull request #2738 from 4Science/main-restore-hierarchical-tree-original-behaviour
Restore hierarchical tree original behaviour
This commit is contained in:
@@ -7,8 +7,10 @@
|
||||
} }}
|
||||
</h1>
|
||||
<div class="mb-3">
|
||||
<ds-vocabulary-treeview [vocabularyOptions]=vocabularyOptions
|
||||
<ds-vocabulary-treeview [description]="description"
|
||||
[vocabularyOptions]=vocabularyOptions
|
||||
[multiSelect]="true"
|
||||
[showAdd]="false"
|
||||
(select)="onSelect($event)"
|
||||
(deselect)="onDeselect($event)">
|
||||
</ds-vocabulary-treeview>
|
||||
|
@@ -14,7 +14,10 @@ import {
|
||||
Params,
|
||||
RouterLink,
|
||||
} from '@angular/router';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import {
|
||||
TranslateModule,
|
||||
TranslateService,
|
||||
} from '@ngx-translate/core';
|
||||
import {
|
||||
BehaviorSubject,
|
||||
Observable,
|
||||
@@ -124,6 +127,11 @@ export class BrowseByTaxonomyComponent implements OnInit, OnChanges, OnDestroy {
|
||||
*/
|
||||
browseDefinition$: Observable<BrowseDefinition>;
|
||||
|
||||
/**
|
||||
* Browse description
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* Subscriptions to track
|
||||
*/
|
||||
@@ -131,6 +139,7 @@ export class BrowseByTaxonomyComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
public constructor(
|
||||
protected route: ActivatedRoute,
|
||||
protected translate: TranslateService,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -141,9 +150,11 @@ export class BrowseByTaxonomyComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}),
|
||||
);
|
||||
this.subs.push(this.browseDefinition$.subscribe((browseDefinition: HierarchicalBrowseDefinition) => {
|
||||
this.selectedItems = [];
|
||||
this.facetType = browseDefinition.facetType;
|
||||
this.vocabularyName = browseDefinition.vocabulary;
|
||||
this.vocabularyOptions = { name: this.vocabularyName, closed: true };
|
||||
this.description = this.translate.instant(`browse.metadata.${this.vocabularyName}.tree.descrption`);
|
||||
}));
|
||||
this.subs.push(this.scope$.subscribe(() => {
|
||||
this.updateQueryParams();
|
||||
|
@@ -293,7 +293,7 @@ export class DsDynamicOneboxComponent extends DsDynamicVocabularyComponent imple
|
||||
const modalRef: NgbModalRef = this.modalService.open(VocabularyTreeviewModalComponent, { size: 'lg', windowClass: 'treeview' });
|
||||
modalRef.componentInstance.vocabularyOptions = this.model.vocabularyOptions;
|
||||
modalRef.componentInstance.preloadLevel = preloadLevel;
|
||||
modalRef.componentInstance.selectedItems = this.currentValue ? [this.currentValue.value] : [];
|
||||
modalRef.componentInstance.selectedItems = this.currentValue ? [this.currentValue] : [];
|
||||
modalRef.result.then((result: VocabularyEntryDetail) => {
|
||||
if (result) {
|
||||
this.currentValue = result;
|
||||
|
@@ -7,9 +7,11 @@
|
||||
<div class="modal-body">
|
||||
<div class="p-3">
|
||||
<ds-vocabulary-treeview [vocabularyOptions]="vocabularyOptions"
|
||||
[description]="description"
|
||||
[preloadLevel]="preloadLevel"
|
||||
[selectedItems]="selectedItems"
|
||||
[multiSelect]="multiSelect"
|
||||
[showAdd]="showAdd"
|
||||
(select)="onSelect($event)">
|
||||
</ds-vocabulary-treeview>
|
||||
</div>
|
||||
|
@@ -5,6 +5,7 @@ import {
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { VocabularyOptions } from '../../../core/submission/vocabularies/models/vocabulary-options.model';
|
||||
import { VocabularyTreeviewComponent } from '../vocabulary-treeview/vocabulary-treeview.component';
|
||||
import { VocabularyTreeviewModalComponent } from './vocabulary-treeview-modal.component';
|
||||
|
||||
@@ -13,6 +14,7 @@ describe('VocabularyTreeviewModalComponent', () => {
|
||||
let fixture: ComponentFixture<VocabularyTreeviewModalComponent>;
|
||||
|
||||
const modalStub = jasmine.createSpyObj('modalStub', ['close']);
|
||||
const vocabularyOptions = new VocabularyOptions('vocabularyTest', false);
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
@@ -32,10 +34,16 @@ describe('VocabularyTreeviewModalComponent', () => {
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(VocabularyTreeviewModalComponent);
|
||||
component = fixture.componentInstance;
|
||||
component.vocabularyOptions = vocabularyOptions;
|
||||
spyOn(component as any, 'setDescription').and.callThrough();
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should init descrption message', () => {
|
||||
expect((component as any).setDescription).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@@ -2,10 +2,14 @@ import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnInit,
|
||||
Output,
|
||||
} from '@angular/core';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import {
|
||||
TranslateModule,
|
||||
TranslateService,
|
||||
} from '@ngx-translate/core';
|
||||
|
||||
import { VocabularyEntryDetail } from '../../../core/submission/vocabularies/models/vocabulary-entry-detail.model';
|
||||
import { VocabularyOptions } from '../../../core/submission/vocabularies/models/vocabulary-options.model';
|
||||
@@ -24,7 +28,7 @@ import { VocabularyTreeviewComponent } from '../vocabulary-treeview/vocabulary-t
|
||||
/**
|
||||
* Component that contains a modal to display a VocabularyTreeviewComponent
|
||||
*/
|
||||
export class VocabularyTreeviewModalComponent {
|
||||
export class VocabularyTreeviewModalComponent implements OnInit {
|
||||
|
||||
/**
|
||||
* The {@link VocabularyOptions} object
|
||||
@@ -39,13 +43,23 @@ export class VocabularyTreeviewModalComponent {
|
||||
/**
|
||||
* The vocabulary entries already selected, if any
|
||||
*/
|
||||
@Input() selectedItems: string[] = [];
|
||||
@Input() selectedItems: VocabularyEntryDetail[] = [];
|
||||
|
||||
/**
|
||||
* Whether to allow selecting multiple values with checkboxes
|
||||
*/
|
||||
@Input() multiSelect = false;
|
||||
|
||||
/**
|
||||
* A boolean representing if to show the add button or not
|
||||
*/
|
||||
@Input() showAdd = true;
|
||||
|
||||
/**
|
||||
* Contain a descriptive message for this vocabulary retrieved from i18n files
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* An event fired when a vocabulary entry is selected.
|
||||
* Event's payload equals to {@link VocabularyEntryDetail} selected.
|
||||
@@ -56,11 +70,17 @@ export class VocabularyTreeviewModalComponent {
|
||||
* Initialize instance variables
|
||||
*
|
||||
* @param {NgbActiveModal} activeModal
|
||||
* @param {TranslateService} translate
|
||||
*/
|
||||
constructor(
|
||||
public activeModal: NgbActiveModal,
|
||||
protected translate: TranslateService,
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.setDescription();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called on entry select
|
||||
*/
|
||||
@@ -68,4 +88,13 @@ export class VocabularyTreeviewModalComponent {
|
||||
this.select.emit(item);
|
||||
this.activeModal.close(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the description message related to the given vocabulary
|
||||
*/
|
||||
private setDescription() {
|
||||
const descriptionLabel = 'vocabulary-treeview.tree.description.' + this.vocabularyOptions.name;
|
||||
this.description = this.translate.instant(descriptionLabel);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<ds-alert [content]="'vocabulary-treeview.info' | translate" [type]="AlertType.Info"></ds-alert>
|
||||
<ds-alert *ngIf="description" [content]="description" [type]="AlertType.Info"></ds-alert>
|
||||
<div class="treeview-header row mb-1">
|
||||
<div class="col-12">
|
||||
<div class="input-group">
|
||||
@@ -11,7 +11,7 @@
|
||||
<button class="btn btn-outline-secondary" type="button" (click)="reset()">
|
||||
{{'vocabulary-treeview.search.form.reset' | translate}}
|
||||
</button>
|
||||
<button class="btn btn-outline-primary" type="button" (click)="add()" [disabled]="this.vocabularyOptions.closed">
|
||||
<button *ngIf="showAdd && this.vocabularyOptions.closed" class="btn btn-outline-primary" type="button" (click)="add()">
|
||||
{{'vocabulary-treeview.search.form.add' | translate}}
|
||||
</button>
|
||||
<button class="btn btn-outline-primary" type="button" (click)="add()" [disabled]="this.vocabularyOptions.closed">
|
||||
|
@@ -13,14 +13,9 @@ import {
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { StoreModule } from '@ngrx/store';
|
||||
import { provideMockStore } from '@ngrx/store/testing';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
|
||||
import { storeModuleConfig } from '../../../app.reducer';
|
||||
import { authReducer } from '../../../core/auth/auth.reducer';
|
||||
import { AuthTokenInfo } from '../../../core/auth/models/auth-token-info.model';
|
||||
import { PageInfo } from '../../../core/shared/page-info.model';
|
||||
import { VocabularyEntry } from '../../../core/submission/vocabularies/models/vocabulary-entry.model';
|
||||
import { VocabularyEntryDetail } from '../../../core/submission/vocabularies/models/vocabulary-entry-detail.model';
|
||||
@@ -40,7 +35,6 @@ describe('VocabularyTreeviewComponent test suite', () => {
|
||||
let comp: VocabularyTreeviewComponent;
|
||||
let compAsAny: any;
|
||||
let fixture: ComponentFixture<VocabularyTreeviewComponent>;
|
||||
let initialState;
|
||||
let de;
|
||||
|
||||
const item = new VocabularyEntryDetail();
|
||||
@@ -71,25 +65,10 @@ describe('VocabularyTreeviewComponent test suite', () => {
|
||||
clearSearchTopRequests: jasmine.createSpy('clearSearchTopRequests'),
|
||||
});
|
||||
|
||||
initialState = {
|
||||
core: {
|
||||
auth: {
|
||||
authenticated: true,
|
||||
loaded: true,
|
||||
blocking: false,
|
||||
loading: false,
|
||||
authToken: new AuthTokenInfo('test_token'),
|
||||
userId: 'testid',
|
||||
authMethods: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
CdkTreeModule,
|
||||
StoreModule.forRoot({ auth: authReducer }, storeModuleConfig),
|
||||
TranslateModule.forRoot(),
|
||||
VocabularyTreeviewComponent,
|
||||
TestComponent,
|
||||
@@ -99,7 +78,6 @@ describe('VocabularyTreeviewComponent test suite', () => {
|
||||
{ provide: VocabularyTreeviewService, useValue: vocabularyTreeviewServiceStub },
|
||||
{ provide: VocabularyService, useValue: vocabularyServiceStub },
|
||||
{ provide: NgbActiveModal, useValue: modalStub },
|
||||
provideMockStore({ initialState }),
|
||||
ChangeDetectorRef,
|
||||
VocabularyTreeviewComponent,
|
||||
],
|
||||
@@ -155,10 +133,10 @@ describe('VocabularyTreeviewComponent test suite', () => {
|
||||
currentValue.otherInformation = {
|
||||
id: 'entryID',
|
||||
};
|
||||
comp.selectedItems = [currentValue.value];
|
||||
comp.selectedItems = [currentValue];
|
||||
fixture.detectChanges();
|
||||
expect(comp.dataSource.data).toEqual([]);
|
||||
expect(vocabularyTreeviewServiceStub.initialize).toHaveBeenCalledWith(comp.vocabularyOptions, new PageInfo(), ['testValue'], null);
|
||||
expect(vocabularyTreeviewServiceStub.initialize).toHaveBeenCalledWith(comp.vocabularyOptions, new PageInfo(), ['entryID'], 'entryID');
|
||||
});
|
||||
|
||||
it('should should init component properly with init value as VocabularyEntry', () => {
|
||||
@@ -167,10 +145,20 @@ describe('VocabularyTreeviewComponent test suite', () => {
|
||||
currentValue.otherInformation = {
|
||||
id: 'entryID',
|
||||
};
|
||||
comp.selectedItems = [currentValue.value];
|
||||
comp.selectedItems = [currentValue];
|
||||
fixture.detectChanges();
|
||||
expect(comp.dataSource.data).toEqual([]);
|
||||
expect(vocabularyTreeviewServiceStub.initialize).toHaveBeenCalledWith(comp.vocabularyOptions, new PageInfo(), ['testValue'], null);
|
||||
expect(vocabularyTreeviewServiceStub.initialize).toHaveBeenCalledWith(comp.vocabularyOptions, new PageInfo(), ['entryID'], 'entryID');
|
||||
});
|
||||
|
||||
it('should should init component properly with init value as VocabularyEntryDetail', () => {
|
||||
const currentValue = new VocabularyEntryDetail();
|
||||
currentValue.value = 'testValue';
|
||||
currentValue.id = 'entryID';
|
||||
comp.selectedItems = [currentValue];
|
||||
fixture.detectChanges();
|
||||
expect(comp.dataSource.data).toEqual([]);
|
||||
expect(vocabularyTreeviewServiceStub.initialize).toHaveBeenCalledWith(comp.vocabularyOptions, new PageInfo(), ['entryID'], 'entryID');
|
||||
});
|
||||
|
||||
it('should call loadMore function', () => {
|
||||
|
@@ -18,23 +18,16 @@ import {
|
||||
} from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { Store } from '@ngrx/store';
|
||||
import {
|
||||
TranslateModule,
|
||||
TranslateService,
|
||||
} from '@ngx-translate/core';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import {
|
||||
Observable,
|
||||
Subscription,
|
||||
} from 'rxjs';
|
||||
|
||||
import { CoreState } from '../../../core/core-state.model';
|
||||
import { getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators';
|
||||
import { PageInfo } from '../../../core/shared/page-info.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';
|
||||
import { VocabularyService } from '../../../core/submission/vocabularies/vocabulary.service';
|
||||
import { AlertComponent } from '../../alert/alert.component';
|
||||
import { AlertType } from '../../alert/alert-type';
|
||||
import {
|
||||
@@ -43,6 +36,7 @@ import {
|
||||
isNotEmpty,
|
||||
} from '../../empty.util';
|
||||
import { ThemedLoadingComponent } from '../../loading/themed-loading.component';
|
||||
import { FormFieldMetadataValueObject } from '../builder/models/form-field-metadata-value.model';
|
||||
import { VocabularyTreeFlatDataSource } from './vocabulary-tree-flat-data-source';
|
||||
import { VocabularyTreeFlattener } from './vocabulary-tree-flattener';
|
||||
import { VocabularyTreeviewService } from './vocabulary-treeview.service';
|
||||
@@ -53,6 +47,8 @@ import {
|
||||
TreeviewNode,
|
||||
} from './vocabulary-treeview-node.model';
|
||||
|
||||
export type VocabularyTreeItemType = FormFieldMetadataValueObject | VocabularyEntry | VocabularyEntryDetail;
|
||||
|
||||
/**
|
||||
* Component that shows a hierarchical vocabulary in a tree view
|
||||
*/
|
||||
@@ -85,15 +81,25 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges
|
||||
@Input() preloadLevel = 2;
|
||||
|
||||
/**
|
||||
* The vocabulary entries already selected, if any
|
||||
* Contain a descriptive message for the tree
|
||||
*/
|
||||
@Input() selectedItems: string[] = [];
|
||||
@Input() description = '';
|
||||
|
||||
/**
|
||||
* Whether to allow selecting multiple values with checkboxes
|
||||
*/
|
||||
@Input() multiSelect = false;
|
||||
|
||||
/**
|
||||
* A boolean representing if to show the add button or not
|
||||
*/
|
||||
@Input() showAdd = true;
|
||||
|
||||
/**
|
||||
* The vocabulary entries already selected, if any
|
||||
*/
|
||||
@Input() selectedItems: VocabularyTreeItemType[] = [];
|
||||
|
||||
/**
|
||||
* A map containing the current node showed by the tree
|
||||
*/
|
||||
@@ -131,20 +137,15 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges
|
||||
|
||||
/**
|
||||
* An event fired when a vocabulary entry is selected.
|
||||
* Event's payload equals to {@link VocabularyEntryDetail} selected.
|
||||
* Event's payload equals to {@link VocabularyTreeItemType} selected.
|
||||
*/
|
||||
@Output() select: EventEmitter<VocabularyEntryDetail> = new EventEmitter<VocabularyEntryDetail>(null);
|
||||
@Output() select: EventEmitter<VocabularyTreeItemType> = new EventEmitter<VocabularyTreeItemType>(null);
|
||||
|
||||
/**
|
||||
* An event fired when a vocabulary entry is deselected.
|
||||
* Event's payload equals to {@link VocabularyEntryDetail} deselected.
|
||||
* Event's payload equals to {@link VocabularyTreeItemType} deselected.
|
||||
*/
|
||||
@Output() deselect: EventEmitter<VocabularyEntryDetail> = new EventEmitter<VocabularyEntryDetail>(null);
|
||||
|
||||
/**
|
||||
* A boolean representing if user is authenticated
|
||||
*/
|
||||
private isAuthenticated: Observable<boolean>;
|
||||
@Output() deselect: EventEmitter<VocabularyTreeItemType> = new EventEmitter<VocabularyTreeItemType>(null);
|
||||
|
||||
/**
|
||||
* Array to track all subscriptions and unsubscribe them onDestroy
|
||||
@@ -157,15 +158,9 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges
|
||||
* Initialize instance variables
|
||||
*
|
||||
* @param {VocabularyTreeviewService} vocabularyTreeviewService
|
||||
* @param {vocabularyService} vocabularyService
|
||||
* @param {Store<CoreState>} store
|
||||
* @param {TranslateService} translate
|
||||
*/
|
||||
constructor(
|
||||
private vocabularyTreeviewService: VocabularyTreeviewService,
|
||||
private vocabularyService: VocabularyService,
|
||||
private store: Store<CoreState>,
|
||||
private translate: TranslateService,
|
||||
) {
|
||||
this.treeFlattener = new VocabularyTreeFlattener(this.transformer, this.getLevel,
|
||||
this.isExpandable, this.getChildren);
|
||||
@@ -187,7 +182,8 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges
|
||||
* @param level The node level information
|
||||
*/
|
||||
transformer = (node: TreeviewNode, level: number) => {
|
||||
const existingNode = this.nodeMap.get(node.item.id);
|
||||
const entryId = this.getEntryId(node.item);
|
||||
const existingNode = this.nodeMap.get(entryId);
|
||||
|
||||
if (existingNode && existingNode.item.id !== LOAD_MORE && existingNode.item.id !== LOAD_MORE_ROOT) {
|
||||
return existingNode;
|
||||
@@ -204,7 +200,7 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges
|
||||
node.isInInitValueHierarchy,
|
||||
node.isSelected,
|
||||
);
|
||||
this.nodeMap.set(node.item.id, newNode);
|
||||
this.nodeMap.set(entryId, newNode);
|
||||
|
||||
if ((((level + 1) < this.preloadLevel) && newNode.childrenLoaded)
|
||||
|| (newNode.isSearchNode && newNode.childrenLoaded)
|
||||
@@ -259,7 +255,8 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges
|
||||
|
||||
this.loading = this.vocabularyTreeviewService.isLoading();
|
||||
|
||||
this.vocabularyTreeviewService.initialize(this.vocabularyOptions, new PageInfo(), this.selectedItems, null);
|
||||
const entryId: string = (this.selectedItems?.length > 0) ? this.getEntryId(this.selectedItems[0]) : null;
|
||||
this.vocabularyTreeviewService.initialize(this.vocabularyOptions, new PageInfo(), this.getSelectedEntryIds(), entryId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -267,7 +264,7 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges
|
||||
* @param item The VocabularyEntryDetail for which to load more nodes
|
||||
*/
|
||||
loadMore(item: VocabularyEntryDetail) {
|
||||
this.vocabularyTreeviewService.loadMore(item, this.selectedItems);
|
||||
this.vocabularyTreeviewService.loadMore(item, this.getSelectedEntryIds());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,7 +272,7 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges
|
||||
* @param node The TreeviewFlatNode for which to load more nodes
|
||||
*/
|
||||
loadMoreRoot(node: TreeviewFlatNode) {
|
||||
this.vocabularyTreeviewService.loadMoreRoot(node, this.selectedItems);
|
||||
this.vocabularyTreeviewService.loadMoreRoot(node, this.getSelectedEntryIds());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -283,18 +280,18 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges
|
||||
* @param node The TreeviewFlatNode for which to load children nodes
|
||||
*/
|
||||
loadChildren(node: TreeviewFlatNode) {
|
||||
this.vocabularyTreeviewService.loadMore(node.item, this.selectedItems, true);
|
||||
this.vocabularyTreeviewService.loadMore(node.item, this.getSelectedEntryIds(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called on entry select/deselect
|
||||
*/
|
||||
onSelect(item: VocabularyEntryDetail) {
|
||||
if (!this.selectedItems.includes(item.id)) {
|
||||
this.selectedItems.push(item.id);
|
||||
if (!this.getSelectedEntryIds().includes(this.getEntryId(item))) {
|
||||
this.selectedItems.push(item);
|
||||
this.select.emit(item);
|
||||
} else {
|
||||
this.selectedItems = this.selectedItems.filter((detail: string) => { return detail !== item.id; });
|
||||
this.selectedItems = this.selectedItems.filter((detail: VocabularyTreeItemType) => this.getEntryId(detail) !== this.getEntryId(item));
|
||||
this.deselect.emit(item);
|
||||
}
|
||||
}
|
||||
@@ -308,7 +305,7 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges
|
||||
this.storedNodeMap = this.nodeMap;
|
||||
}
|
||||
this.nodeMap = new Map<string, TreeviewFlatNode>();
|
||||
this.vocabularyTreeviewService.searchByQuery(this.searchText, this.selectedItems);
|
||||
this.vocabularyTreeviewService.searchByQuery(this.searchText, this.getSelectedEntryIds());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,12 +322,8 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges
|
||||
reset() {
|
||||
this.searchText = '';
|
||||
for (const item of this.selectedItems) {
|
||||
this.subs.push(this.vocabularyService.findEntryDetailById(item, this.vocabularyOptions.name, true, true, false).pipe(
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
).subscribe((detail: VocabularyEntryDetail) => {
|
||||
this.deselect.emit(detail);
|
||||
}));
|
||||
this.nodeMap.get(item).isSelected = false;
|
||||
this.deselect.emit(item);
|
||||
this.nodeMap.get(this.getEntryId(item)).isSelected = false;
|
||||
}
|
||||
this.selectedItems = [];
|
||||
|
||||
@@ -361,14 +354,27 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an id for a given {@link VocabularyEntry}
|
||||
* Return an id for a given {@link VocabularyTreeItemType}
|
||||
*/
|
||||
private getEntryId(entry: VocabularyEntry): string {
|
||||
return entry.authority || entry.otherInformation.id || undefined;
|
||||
private getEntryId(entry: VocabularyTreeItemType): string {
|
||||
return entry?.authority || entry?.otherInformation?.id || (entry as any)?.id || undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an ids for all selected entries
|
||||
*/
|
||||
private getSelectedEntryIds(): string[] {
|
||||
return this.selectedItems
|
||||
.map((entry: VocabularyTreeItemType) => this.getEntryId(entry))
|
||||
.filter((value) => isNotEmpty(value));
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
this.reset();
|
||||
this.vocabularyTreeviewService.initialize(this.vocabularyOptions, new PageInfo(), this.selectedItems, null);
|
||||
if (!changes.vocabularyOptions.isFirstChange() && changes.vocabularyOptions.currentValue !== changes.vocabularyOptions.previousValue) {
|
||||
this.selectedItems = [];
|
||||
this.searchText = '';
|
||||
this.vocabularyTreeviewService.cleanTree();
|
||||
this.vocabularyTreeviewService.initialize(this.vocabularyOptions, new PageInfo(), this.getSelectedEntryIds(), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -260,7 +260,7 @@ export class VocabularyTreeviewService {
|
||||
const hasChildren = entry.hasOtherInformation() && (entry.otherInformation as any)!.hasChildren === 'true';
|
||||
const pageInfo: PageInfo = this.pageInfo;
|
||||
const isInInitValueHierarchy = this.initValueHierarchy.includes(entryId);
|
||||
const isSelected: boolean = selectedItems.some(() => selectedItems.includes(entry.id));
|
||||
const isSelected: boolean = selectedItems.some(() => selectedItems.includes(entryId));
|
||||
const result = new TreeviewNode(
|
||||
entry,
|
||||
hasChildren,
|
||||
|
@@ -126,6 +126,7 @@ export class SearchHierarchyFilterComponent extends SearchFacetFilterComponent i
|
||||
name: this.getVocabularyEntry(),
|
||||
closed: true,
|
||||
};
|
||||
modalRef.componentInstance.showAdd = false;
|
||||
this.subs.push(from(modalRef.result).pipe(
|
||||
switchMap((detail: VocabularyEntryDetail) => this.searchConfigService.selectNewAppliedFilterParams(this.filterConfig.name, detail.value, 'equals')),
|
||||
take(1),
|
||||
|
@@ -1034,8 +1034,12 @@
|
||||
|
||||
"browse.metadata.srsc.breadcrumbs": "Browse by Subject Category",
|
||||
|
||||
"browse.metadata.srsc.tree.descrption": "Select a subject to add as search filter",
|
||||
|
||||
"browse.metadata.nsi.breadcrumbs": "Browse by Norwegian Science Index",
|
||||
|
||||
"browse.metadata.nsi.tree.descrption": "Select an index to add as search filter",
|
||||
|
||||
"browse.metadata.title.breadcrumbs": "Browse by Title",
|
||||
|
||||
"pagination.next.button": "Next",
|
||||
|
Reference in New Issue
Block a user