import{Component, OnInit}from'@angular/core';import{concat,of, Subject, Observable, BehaviorSubject}from'rxjs';import{catchError, distinctUntilChanged, switchMap, tap}from'rxjs/operators';import{FilterLabel, isFilterLabel, LabelStoreService}from'../../data/label/label-store.service';import{StateService}from'../../state.service';/**
* This component is responsible for the display of the search bar above the graph.
* It allows for filtering issues by multiple labels and text fragments.
*/@Component({
selector:'app-label-search',
templateUrl:'./label-search.component.html',
styleUrls:['./label-search.component.scss']})exportclassLabelSearchComponentimplementsOnInit{public filterSelection$ =newBehaviorSubject<FilterSelection>({
labels:[],
texts:[]});
labels$: Observable<FilterLabel[]>;
labelsLoading =false;
labelsInput$ =newSubject<string>();
selectedLabels: FilterElement[]=[];constructor(private labelStore: LabelStoreService,private ss: StateService){}ngOnInit(){this.loadLabels();}trackByFn(item: FilterLabel):string{return item.id;}/**
* Emit value representing label and text fragments in the search bar via this.filterSelection$
*/emitSelectedLabels():void{const selection: FilterSelection ={texts:[], labels:[]};// find out which elements in search bar correspond to an existing label on the backend and which to a text fragment
selection.texts =this.selectedLabels.filter((item)=>!isFilterLabel(item)).map((item)=> item.name);
selection.labels =this.selectedLabels.filter((label)=>isFilterLabel(label))as FilterLabel[];this.filterSelection$.next(selection);}/**
* Load all labels from backend that match the currently typed in ng-select element
*/privateloadLabels(){this.labels$ =concat(of([]),// default itemsthis.labelsInput$.pipe(distinctUntilChanged(),tap(()=>(this.labelsLoading =true)),switchMap((term)=>this.labelStore.getMatchingLabels(this.ss.state.project.node.id, term).pipe(catchError(()=>of([])),// empty list on errortap(()=>(this.labelsLoading =false))))));}}/**
* The bar can contain elements standing for labels and elements for text fragments.
*/typeFilterElement= TextFragment | FilterLabel;interfaceTextFragment{
name:string;}exportinterfaceFilterSelection{
texts:string[];
labels: FilterLabel[];}