File
cd_nom
|
cd_nom: number
|
Type : number
|
cd_ref
|
cd_ref: number
|
Type : number
|
cd_sup
|
cd_sup: number
|
Type : number
|
cd_taxsup
|
cd_taxsup: number
|
Type : number
|
classe
|
classe: string
|
Type : string
|
famille
|
famille: string
|
Type : string
|
group1_inpn
|
group1_inpn: string
|
Type : string
|
group2_inpn
|
group2_inpn: string
|
Type : string
|
id_rang
|
id_rang: string
|
Type : string
|
lb_nom
|
lb_nom: string
|
Type : string
|
nom_complet
|
nom_complet: string
|
Type : string
|
nom_habitat
|
nom_habitat: string
|
Type : string
|
nom_rang
|
nom_rang: string
|
Type : string
|
nom_statut
|
nom_statut: string
|
Type : string
|
nom_valide
|
nom_valide: string
|
Type : string
|
nom_vern
|
nom_vern: string
|
Type : string
|
ordre
|
ordre: string
|
Type : string
|
phylum
|
phylum: string
|
Type : string
|
regne
|
regne: string
|
Type : string
|
search_name
|
search_name: string
|
Type : string
|
statuts_protection
|
statuts_protection: any[]
|
Type : any[]
|
synonymes
|
synonymes: any[]
|
Type : any[]
|
import {
Component,
EventEmitter,
Input,
OnChanges,
OnInit,
Output,
ViewEncapsulation,
} from '@angular/core';
import { UntypedFormControl } from '@angular/forms';
import { NgbTypeaheadSelectItemEvent } from '@ng-bootstrap/ng-bootstrap';
import { Observable, of } from 'rxjs';
import { debounceTime, distinctUntilChanged, filter, map, switchMap, tap } from 'rxjs/operators';
import { DataFormService } from '../data-form.service';
import { ConfigService } from '@geonature/services/config.service';
export interface Taxon {
search_name?: string;
nom_valide?: string;
group2_inpn?: string;
regne?: string;
lb_nom?: string;
cd_nom?: number;
cd_ref?: number;
cd_sup?: number;
cd_taxsup?: number;
classe?: string;
famille?: string;
group1_inpn?: string;
id_rang?: string;
nom_complet?: string;
nom_habitat?: string;
nom_rang?: string;
nom_statut?: string;
nom_vern?: string;
ordre?: string;
phylum?: string;
statuts_protection?: any[];
synonymes?: any[];
}
/**
* Ce composant permet de créer un "input" de type "typeahead" pour rechercher des taxons à partir d'une liste définit dans schéma taxonomie. Table ``taxonomie.bib_listes`` et ``taxonomie.cor_nom_listes``.
*
* @example
* <pnx-taxonomy #taxon
* label="{{ 'Taxon.Taxon' | translate }}
* [parentFormControl]="occurrenceForm.controls.cd_nom"
* [idList]="occtaxConfig.id_taxon_list"
* [charNumber]="3"
* [listLength]="occtaxConfig.taxon_result_number"
* (onChange)="fs.onTaxonChanged($event);"
* [displayAdvancedFilters]=true>
* </pnx-taxonomy>
*
* */
@Component({
selector: 'pnx-taxonomy',
templateUrl: './taxonomy.component.html',
styleUrls: ['./taxonomy.component.scss'],
encapsulation: ViewEncapsulation.None,
})
export class TaxonomyComponent implements OnInit, OnChanges {
/**
* Reactive form
*/
@Input() parentFormControl: UntypedFormControl;
@Input() label: string;
// api endpoint for the automplete ressource
@Input() apiEndPoint: string;
/*** Id de la liste de taxon */
@Input() idList: string;
/** Nombre de charactere avant que la recherche AJAX soit lançé (obligatoire) */
@Input() charNumber: number;
// **ombre de résultat affiché */
@Input() listLength = 20;
// ** Pour changer la valeur affichée */
@Input() displayedLabel = 'nom_valide';
/** Afficher ou non les filtres par regne et groupe INPN qui controle l'autocomplétion */
@Input() displayAdvancedFilters = false;
searchString: any;
filteredTaxons: any;
regnes = new Array();
regneControl = new UntypedFormControl(null);
groupControl = new UntypedFormControl(null);
regnesAndGroup: any;
noResult: boolean;
isLoading = false;
@Output() onChange = new EventEmitter<NgbTypeaheadSelectItemEvent>(); // renvoie l'evenement, le taxon est récupérable grâce à e.item
@Output() onDelete = new EventEmitter<Taxon>();
public isCollapseTaxonomy = true;
constructor(
private _dfService: DataFormService,
public config: ConfigService
) {}
ngOnInit() {
if (!this.apiEndPoint) {
this.setApiEndPoint(this.idList);
}
this.parentFormControl.valueChanges
.pipe(filter((value) => value !== null && value.length === 0))
.subscribe((value) => {
this.onDelete.emit();
});
if (this.displayAdvancedFilters) {
// get regne and group2
this._dfService.getRegneAndGroup2Inpn().subscribe((data) => {
this.regnesAndGroup = data;
for (const regne in data) {
this.regnes.push(regne);
}
});
}
// put group to null if regne = null
this.regneControl.valueChanges.subscribe((value) => {
if (value === '') {
this.groupControl.patchValue(null);
}
});
}
ngOnChanges(changes) {
if (changes && changes.idList) {
this.setApiEndPoint(changes.idList.currentValue);
}
}
setApiEndPoint(idList) {
if (idList) {
this.apiEndPoint = `${this.config.API_TAXHUB}/taxref/allnamebylist/${idList}`;
} else {
this.apiEndPoint = `${this.config.API_TAXHUB}/taxref/allnamebylist`;
}
}
taxonSelected(e: NgbTypeaheadSelectItemEvent) {
this.onChange.emit(e);
}
formatter = (taxon: any) => {
return taxon[this.displayedLabel].replace(/<[^>]*>/g, ''); // supprime les balises HTML
};
searchTaxon = (text$: Observable<string>) =>
text$.pipe(
distinctUntilChanged(),
debounceTime(400),
tap(() => (this.isLoading = true)),
switchMap((search_name_) => {
const search_name = search_name_.toString();
if (search_name.length >= this.charNumber) {
return this._dfService
.autocompleteTaxon(this.apiEndPoint, search_name, {
regne: this.regneControl.value,
group2_inpn: this.groupControl.value,
limit: this.listLength.toString(),
})
.catch(() => {
return of([]);
});
} else {
this.isLoading = false;
return [[]];
}
}),
map((response) => {
this.noResult = response.length === 0;
this.isLoading = false;
return response;
})
);
refreshAllInput() {
this.parentFormControl.reset();
this.regneControl.reset();
this.groupControl.reset();
}
}