import {ChangeDetectorRef, Component, OnDestroy, OnInit} from '@angular/core'; import {ActivatedRoute, Router} from '@angular/router'; import {SearchCommunityDataprovidersService} from '../../../openaireLibrary/connect/contentProviders/searchDataproviders.service'; import {EnvProperties} from '../../../openaireLibrary/utils/properties/env-properties'; import { Constraint, ContentProvider, Criteria, SelectionCriteria } from '../../../openaireLibrary/utils/entities/contentProvider'; import {AbstractControl, FormArray, FormBuilder, FormGroup, Validators} from '@angular/forms'; import {ManageCommunityContentProvidersService} from '../../../services/manageContentProviders.service'; import {Title} from '@angular/platform-browser'; import {properties} from "../../../../environments/environment"; import {Subscription} from "rxjs"; import {Option} from "../../../openaireLibrary/sharedComponents/input/input.component"; import {MatSlideToggleChange} from "@angular/material/slide-toggle"; import {HelperFunctions} from "../../../openaireLibrary/utils/HelperFunctions.class"; import {CriteriaUtils} from "../criteria-utils"; declare var UIkit; @Component({ selector: 'criteria', templateUrl: './criteria.component.html', styleUrls: ['criteria.component.css'], }) export class CriteriaComponent implements OnInit, OnDestroy { public community: string = ''; public openaireId: string = ''; public dataProvider: ContentProvider = null; public selectionCriteria: FormGroup; public properties: EnvProperties = properties; public fields: Option[] = CriteriaUtils.fields; public verbs: Option[] = CriteriaUtils.verbs; public loading = true; /** Paging */ public page: number = 1; public pageSize: number = 5; private subs: any[] = []; constructor(private route: ActivatedRoute, private router: Router, private title: Title, private searchCommunityDataprovidersService: SearchCommunityDataprovidersService, private manageCommunityContentProvidersService: ManageCommunityContentProvidersService, private cdr: ChangeDetectorRef, private fb: FormBuilder) { } ngOnInit() { this.subs.push(this.route.params.subscribe(params => { this.community = params['community']; this.route.params.subscribe(params => { if (params['provider']) { this.openaireId = params['provider']; } this.searchCommunityDataprovidersService.searchDataproviders(this.properties, this.community).subscribe(dataProviders => { dataProviders.forEach(dataProvider => { if (dataProvider.openaireId == this.openaireId) { this.dataProvider = dataProvider; this.title.setTitle(this.community.toUpperCase() + ' | Criteria for ' + this.dataProvider.officialname); } }); if (!this.dataProvider) { this.navigateToError(); } else { this.reset(); this.loading = false; } }); }); })); } public ngOnDestroy() { this.subs.forEach(subscription => { if (subscription instanceof Subscription) { subscription.unsubscribe(); } }) } private navigateToError() { this.router.navigate(['/error'], {queryParams: {'page': this.properties.baseLink + this.router.url}}); } reset() { this.page = 1; if (this.dataProvider) { this.selectionCriteria = this.fb.group({ criteria: this.fb.array([]) }); let selectionCriteria = this.dataProvider.selectioncriteria; if (selectionCriteria) { selectionCriteria.criteria.forEach(criterion => { let constraintArray: FormArray = this.fb.array([]); criterion.constraint.forEach(constraint => { constraintArray.push(this.fb.group({ field: this.fb.control(constraint.field, Validators.required), verb: this.fb.control(this.removeSuffix(constraint.verb), Validators.required), value: this.fb.control(constraint.value, Validators.required), verb_suffix: this.fb.control(this.getSuffix(constraint.verb)) })); }); this.criteria.push(this.fb.group({ constraint: constraintArray })); }); } } } get currentPage(): AbstractControl[] { if (this.criteria) { return this.criteria.controls.slice((this.page - 1) * this.pageSize, this.page * this.pageSize); } else { return []; } } getIndex(index: number): number { return (this.page - 1)*this.pageSize + index; } public get criteria(): FormArray { return this.selectionCriteria.get('criteria') as FormArray; } public getConstraint(i: number): FormArray { return this.criteria.at(i).get('constraint') as FormArray; } public addCriteria() { let constraintArray: FormArray = this.fb.array([ this.fb.group({ field: this.fb.control('', Validators.required), verb: this.fb.control('contains', Validators.required), value: this.fb.control('', Validators.required), verb_suffix: this.fb.control('_caseinsensitive') }) ]); this.criteria.push(this.fb.group({ constraint: constraintArray })); this.page = Math.ceil(this.criteria.length/this.pageSize); this.cdr.detectChanges(); } public addConstraint(i: number) { let constraintArray: FormArray = this.criteria.at(i).get('constraint') as FormArray; constraintArray.push(this.fb.group({ field: this.fb.control('', Validators.required), verb: this.fb.control('contains', Validators.required), value: this.fb.control('', Validators.required), verb_suffix: this.fb.control('_caseinsensitive') })); this.cdr.detectChanges(); } public removeConstraint(i: number, j: number) { let constraintArray: FormArray = this.criteria.at(i).get('constraint') as FormArray; constraintArray.removeAt(j); if (constraintArray.length === 0) { this.criteria.removeAt(i); if (this.currentPage.length === 0) { this.page = 1; } } this.cdr.detectChanges(); } get dataProviderCriteria(): Criteria[] { return (this.dataProvider && this.dataProvider.selectioncriteria && this.dataProvider.selectioncriteria.criteria)?this.dataProvider.selectioncriteria.criteria:[]; } get dirty() { if(!this.dataProvider || !this.criteria) { return false; } else if(this.criteria.length !== this.dataProviderCriteria.length) { return true; } else { return this.dataProviderCriteria.filter((criterion, i) => { if(criterion.constraint.length !== this.getConstraint(i).length) { return true; } else { let temp = this.getConstraint(i).value; return criterion.constraint.filter((constraint, j) => { return constraint.field !== temp[j].field || constraint.verb !== (temp[j].verb + temp[j].verb_suffix) || constraint.value !== temp[j].value; }).length > 0; } }).length > 0; } } save() { if (this.selectionCriteria.valid) { this.loading = true; this.dataProvider.selectioncriteria = this.parseForm(this.selectionCriteria.value); this.manageCommunityContentProvidersService.saveContentProvider(this.properties, this.dataProvider).subscribe(() => { this.reset(); this.loading = false; UIkit.notification('Filters has been successfully updated', { status: 'success', timeout: 6000, pos: 'bottom-right' }); }, error => { UIkit.notification('An error has been occurred. Try again later!', { status: 'danger', timeout: 6000, pos: 'bottom-right' }); }); } else { UIkit.notification('An error has been occurred. Try again later!', { status: 'danger', timeout: 6000, pos: 'bottom-right' }); } } caseSensitive(event: MatSlideToggleChange, constraint: AbstractControl) { if(event.checked) { constraint.get('verb_suffix').setValue(''); } else { constraint.get('verb_suffix').setValue('_caseinsensitive'); } } removeSuffix(verb: string) { return verb.replace('_caseinsensitive', ''); } getSuffix(verb: string) { if(verb.includes('_caseinsensitive')) { return '_caseinsensitive'; } else { return ''; } } parseForm(formValue): SelectionCriteria { let value = HelperFunctions.copy(formValue); let selectionCriteria: SelectionCriteria = new SelectionCriteria(); selectionCriteria.criteria = []; value.criteria.forEach(criterion => { let criteria = new Criteria(); criteria.constraint = []; criterion.constraint.forEach(constraint => { criteria.constraint.push(new Constraint(constraint.verb + constraint.verb_suffix, constraint.field, constraint.value)); }); selectionCriteria.criteria.push(criteria); }) return selectionCriteria; } }