2021-05-19 13:40:29 +02:00
|
|
|
import {
|
2023-03-08 23:26:06 +01:00
|
|
|
AfterViewInit,
|
|
|
|
ChangeDetectorRef,
|
|
|
|
Component,
|
|
|
|
Input,
|
|
|
|
OnChanges,
|
|
|
|
OnDestroy,
|
|
|
|
OnInit,
|
|
|
|
SimpleChanges
|
|
|
|
} from '@angular/core';
|
|
|
|
import {EnvProperties} from '../../../openaireLibrary/utils/properties/env-properties';
|
|
|
|
import {Constraint, Criteria, SelectionCriteria} from '../../../openaireLibrary/utils/entities/contentProvider';
|
2022-09-23 16:14:20 +02:00
|
|
|
import {AbstractControl, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators} from '@angular/forms';
|
2021-05-19 13:40:29 +02:00
|
|
|
import {properties} from "../../../../environments/environment";
|
|
|
|
import {MatSlideToggleChange} from "@angular/material/slide-toggle";
|
|
|
|
import {HelperFunctions} from "../../../openaireLibrary/utils/HelperFunctions.class";
|
|
|
|
import {CriteriaUtils} from "../criteria-utils";
|
2022-07-04 20:45:20 +02:00
|
|
|
import {NotificationHandler} from "../../../openaireLibrary/utils/notification-handler";
|
2022-09-21 09:29:11 +02:00
|
|
|
import {OpenaireEntities} from "../../../openaireLibrary/utils/properties/searchFields";
|
2023-03-08 23:26:06 +01:00
|
|
|
import {ISVocabulariesService} from "../../../openaireLibrary/utils/staticAutoComplete/ISVocabularies.service";
|
|
|
|
import {Subscription} from "rxjs";
|
2021-05-19 13:40:29 +02:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'criteria',
|
2022-07-04 20:45:20 +02:00
|
|
|
templateUrl: 'criteria.component.html',
|
|
|
|
styleUrls: ['criteria.component.less']
|
2021-05-19 13:40:29 +02:00
|
|
|
})
|
2023-03-08 23:26:06 +01:00
|
|
|
export class CriteriaComponent implements OnInit, OnChanges, AfterViewInit, OnDestroy {
|
|
|
|
@Input()
|
2023-03-10 16:15:26 +01:00
|
|
|
public entityType: string = 'filter';
|
|
|
|
@Input()
|
|
|
|
public entityTypePlural: string = 'filters';
|
2022-07-04 20:45:20 +02:00
|
|
|
@Input()
|
2023-03-08 23:26:06 +01:00
|
|
|
public selectionCriteria: SelectionCriteria;
|
|
|
|
@Input()
|
|
|
|
public height: number = 0;
|
2023-03-10 16:15:26 +01:00
|
|
|
public criteriaHeight: number = 0;
|
2023-03-08 23:26:06 +01:00
|
|
|
public selectionCriteriaForm: UntypedFormGroup;
|
2021-05-19 13:40:29 +02:00
|
|
|
public properties: EnvProperties = properties;
|
2023-03-10 16:15:26 +01:00
|
|
|
public criteriaUtils: CriteriaUtils = new CriteriaUtils();
|
2023-03-08 23:26:06 +01:00
|
|
|
public fos: string[] = [];
|
2023-03-10 16:15:26 +01:00
|
|
|
public sdg: string[] = [];
|
2021-05-19 13:40:29 +02:00
|
|
|
public loading = true;
|
2022-09-21 09:29:11 +02:00
|
|
|
public openaireEntities = OpenaireEntities;
|
2023-03-08 23:26:06 +01:00
|
|
|
private subscriptions: any[] = [];
|
2021-05-19 13:40:29 +02:00
|
|
|
|
2023-03-08 23:26:06 +01:00
|
|
|
constructor(private cdr: ChangeDetectorRef, private vocabulariesService: ISVocabulariesService,
|
2022-09-23 16:14:20 +02:00
|
|
|
private fb: UntypedFormBuilder) {
|
2021-05-19 13:40:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ngOnInit() {
|
2022-07-04 20:45:20 +02:00
|
|
|
this.loading = false;
|
2023-03-08 23:26:06 +01:00
|
|
|
this.subscriptions.push(this.vocabulariesService.getVocabularyByType('fos', null, properties).subscribe((fos: any[]) => {
|
|
|
|
this.fos = fos.map(element => element.id);
|
|
|
|
}));
|
2023-03-10 16:15:26 +01:00
|
|
|
this.subscriptions.push(this.vocabulariesService.getVocabularyByType('sdg', null, properties).subscribe((sdg: any[]) => {
|
|
|
|
this.sdg = sdg.map(element => element.id);
|
|
|
|
}));
|
2023-03-08 23:26:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
ngOnChanges(changes: SimpleChanges) {
|
2023-06-08 12:24:46 +02:00
|
|
|
if(changes.selectionCriteria){
|
|
|
|
this.reset();
|
|
|
|
}
|
2023-03-08 23:26:06 +01:00
|
|
|
this.calculateMaxHeight();
|
|
|
|
}
|
|
|
|
|
|
|
|
ngAfterViewInit() {
|
|
|
|
this.calculateMaxHeight();
|
|
|
|
}
|
|
|
|
|
|
|
|
ngOnDestroy() {
|
|
|
|
this.subscriptions.forEach(subscription => {
|
|
|
|
if (subscription instanceof Subscription) {
|
|
|
|
subscription.unsubscribe();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
calculateMaxHeight() {
|
|
|
|
if(this.height) {
|
|
|
|
if(this.height > 0) {
|
2023-03-10 16:15:26 +01:00
|
|
|
/* Element height - margins(20 + 20) - button height(42) */
|
|
|
|
this.criteriaHeight = this.height - 40 - 42;
|
2023-03-08 23:26:06 +01:00
|
|
|
this.cdr.detectChanges();
|
|
|
|
}
|
|
|
|
}
|
2021-05-19 13:40:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
reset() {
|
2023-06-08 12:24:46 +02:00
|
|
|
this.selectionCriteriaForm = this.fb.group({
|
|
|
|
criteria: this.fb.array([])
|
|
|
|
});
|
2023-03-08 23:26:06 +01:00
|
|
|
if (this.selectionCriteria?.criteria) {
|
2023-06-08 12:24:46 +02:00
|
|
|
|
2023-03-08 23:26:06 +01:00
|
|
|
this.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))
|
2021-05-19 13:40:29 +02:00
|
|
|
}));
|
|
|
|
});
|
2023-03-08 23:26:06 +01:00
|
|
|
this.criteria.push(this.fb.group({
|
|
|
|
constraint: constraintArray
|
|
|
|
}));
|
|
|
|
});
|
2021-05-19 13:40:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-04 20:45:20 +02:00
|
|
|
get disabled() {
|
2023-03-08 23:26:06 +01:00
|
|
|
return this.loading || !this.dirty || this.selectionCriteriaForm.invalid;
|
2021-05-19 13:40:29 +02:00
|
|
|
}
|
|
|
|
|
2022-09-23 16:14:20 +02:00
|
|
|
public get criteria(): UntypedFormArray {
|
2023-03-08 23:26:06 +01:00
|
|
|
return this.selectionCriteriaForm.get('criteria') as UntypedFormArray;
|
2021-05-19 13:40:29 +02:00
|
|
|
}
|
|
|
|
|
2022-09-23 16:14:20 +02:00
|
|
|
public getConstraint(i: number): UntypedFormArray {
|
|
|
|
return this.criteria.at(i).get('constraint') as UntypedFormArray;
|
2021-05-19 13:40:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public addCriteria() {
|
2022-09-23 16:14:20 +02:00
|
|
|
let constraintArray: UntypedFormArray = this.fb.array([
|
2021-05-19 13:40:29 +02:00
|
|
|
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')
|
|
|
|
})
|
|
|
|
]);
|
2023-03-08 23:26:06 +01:00
|
|
|
this.criteria.push(this.fb.group({constraint: constraintArray}));
|
2021-05-19 13:40:29 +02:00
|
|
|
this.cdr.detectChanges();
|
2023-03-08 23:26:06 +01:00
|
|
|
document.getElementById('criterion-' + (this.criteria.length - 1).toString()).scrollIntoView({behavior: 'smooth'});
|
2021-05-19 13:40:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public addConstraint(i: number) {
|
2022-09-23 16:14:20 +02:00
|
|
|
let constraintArray: UntypedFormArray = this.criteria.at(i).get('constraint') as UntypedFormArray;
|
2021-05-19 13:40:29 +02:00
|
|
|
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) {
|
2022-09-23 16:14:20 +02:00
|
|
|
let constraintArray: UntypedFormArray = this.criteria.at(i).get('constraint') as UntypedFormArray;
|
2021-05-19 13:40:29 +02:00
|
|
|
constraintArray.removeAt(j);
|
|
|
|
if (constraintArray.length === 0) {
|
|
|
|
this.criteria.removeAt(i);
|
|
|
|
}
|
|
|
|
this.cdr.detectChanges();
|
|
|
|
}
|
|
|
|
|
2023-03-08 23:26:06 +01:00
|
|
|
get criteriaArray(): Criteria[] {
|
|
|
|
return (this.selectionCriteria?.criteria) ? this.selectionCriteria?.criteria : [];
|
2021-05-19 13:40:29 +02:00
|
|
|
}
|
2023-03-08 23:26:06 +01:00
|
|
|
|
2021-05-19 13:40:29 +02:00
|
|
|
get dirty() {
|
2023-08-29 10:22:27 +02:00
|
|
|
if (!this.selectionCriteria && !this.criteria) {
|
2021-05-19 13:40:29 +02:00
|
|
|
return false;
|
2023-03-08 23:26:06 +01:00
|
|
|
} else if (this.criteria.length !== this.criteriaArray.length) {
|
2021-05-19 13:40:29 +02:00
|
|
|
return true;
|
|
|
|
} else {
|
2023-03-08 23:26:06 +01:00
|
|
|
return this.criteriaArray.filter((criterion, i) => {
|
|
|
|
if (criterion.constraint.length !== this.getConstraint(i).length) {
|
2021-05-19 13:40:29 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-08 23:26:06 +01:00
|
|
|
save(callback: (selectionCriteria) => void = null) {
|
|
|
|
if (this.selectionCriteriaForm.valid) {
|
2021-05-19 13:40:29 +02:00
|
|
|
this.loading = true;
|
2023-03-08 23:26:06 +01:00
|
|
|
callback(this.parseForm(this.selectionCriteriaForm.value));
|
2021-05-19 13:40:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-04 20:45:20 +02:00
|
|
|
handeError(message, error = null) {
|
|
|
|
console.error(error);
|
|
|
|
NotificationHandler.rise(message, 'danger');
|
|
|
|
}
|
|
|
|
|
2021-05-19 13:40:29 +02:00
|
|
|
caseSensitive(event: MatSlideToggleChange, constraint: AbstractControl) {
|
2023-03-08 23:26:06 +01:00
|
|
|
if (event.checked) {
|
2021-05-19 13:40:29 +02:00
|
|
|
constraint.get('verb_suffix').setValue('');
|
|
|
|
} else {
|
|
|
|
constraint.get('verb_suffix').setValue('_caseinsensitive');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
removeSuffix(verb: string) {
|
|
|
|
return verb.replace('_caseinsensitive', '');
|
|
|
|
}
|
|
|
|
|
|
|
|
getSuffix(verb: string) {
|
2023-03-08 23:26:06 +01:00
|
|
|
if (verb.includes('_caseinsensitive')) {
|
2021-05-19 13:40:29 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|