import {ChangeDetectorRef, Component, Input, OnInit} from '@angular/core'; import {EnvProperties} from '../../../openaireLibrary/utils/properties/env-properties'; import { Constraint, ContentProvider, Criteria, SelectionCriteria } from '../../../openaireLibrary/utils/entities/contentProvider'; import {AbstractControl, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators} from '@angular/forms'; import {ManageCommunityContentProvidersService} from '../../../services/manageContentProviders.service'; import {properties} from "../../../../environments/environment"; 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"; import {NotificationHandler} from "../../../openaireLibrary/utils/notification-handler"; import {OpenaireEntities} from "../../../openaireLibrary/utils/properties/searchFields"; @Component({ selector: 'criteria', templateUrl: 'criteria.component.html', styleUrls: ['criteria.component.less'] }) export class CriteriaComponent implements OnInit { @Input() public dataProvider: ContentProvider; public selectionCriteria: UntypedFormGroup; 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; public openaireEntities = OpenaireEntities; constructor(private manageCommunityContentProvidersService: ManageCommunityContentProvidersService, private cdr: ChangeDetectorRef, private fb: UntypedFormBuilder) { } ngOnInit() { this.reset(); this.loading = false; } 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: UntypedFormArray = 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 disabled() { return this.loading || !this.dirty || this.selectionCriteria.invalid; } 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(): UntypedFormArray { return this.selectionCriteria.get('criteria') as UntypedFormArray; } public getConstraint(i: number): UntypedFormArray { return this.criteria.at(i).get('constraint') as UntypedFormArray; } public addCriteria() { let constraintArray: UntypedFormArray = 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.insert(0, this.fb.group({ constraint: constraintArray })); this.page = 1; this.cdr.detectChanges(); } public addConstraint(i: number) { let constraintArray: UntypedFormArray = this.criteria.at(i).get('constraint') as UntypedFormArray; 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: UntypedFormArray = this.criteria.at(i).get('constraint') as UntypedFormArray; constraintArray.removeAt(j); if (constraintArray.length === 0) { this.criteria.removeAt(i); while(this.currentPage.length === 0 && this.page > 0) { this.page--; } } 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(callback: Function = null) { 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(); if(callback) { callback(); } this.loading = false; NotificationHandler.rise('Filters have been successfully updated'); }, error => { this.loading = false; this.handeError('An error has been occurred. Try again later!', error); }); } else { this.handeError('An error has been occurred. Try again later!'); } } handeError(message, error = null) { console.error(error); NotificationHandler.rise(message, 'danger'); } 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; } public updatePage(event) { this.page = event.value; HelperFunctions.scroll(); } }