import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { distinctUntilKeyChanged, skip, takeUntil } from 'rxjs/operators';
import { combineLatest, Subject } from 'rxjs';
import { Field, Filter, Operator } from './filtering.interface';
import { FieldsService } from './fields.service';
@Component({
selector: 'app-filter',
template: `
`,
styles: [`
:host {
display: inline-flex;
align-items: center;
height: 30px;
background: #ffffff;
border: solid 1px #dddfe2;
border-radius: 4px;
margin: 4px;
max-width: 100%;
padding: 2px 4px;
-webkit-user-select: none;
vertical-align: middle;
box-sizing: border-box;
white-space: nowrap;
}
.filter-item {
position: relative;
display: inline-flex;
align-items: center;
border: 1px solid #d6d6d6;
border-radius: 3px;
margin-right: 4px;
padding: 0 4px;
height: 20px;
font-size: 1.1rem;
cursor: pointer;
}
.filter-item:last-child {
margin: 0;
}
.remove {
position: relative;
top: 0;
right: 0;
}
`],
changeDetection: ChangeDetectionStrategy.Default
})
export class FilterComponent implements OnDestroy, OnInit {
destroy$ = new Subject();
filter$ = new Subject();
field$ = new Subject();
operator$ = new Subject();
value$ = new Subject();
fields = this.fieldsService.get();
field: Field;
operator: Operator;
value: string | string[];
@Input() filter: Filter;
@Input() hideRemove: Boolean = false;
@Output() remove = new EventEmitter();
onRemove () {
this.remove.emit();
}
ngOnDestroy () {
this.destroy$.next();
}
ngOnInit () {
this.fieldsService.fields.pipe(
takeUntil(this.destroy$)
)
.subscribe((fields) => {
this.fields = fields;
});
this.filter$
.pipe(
takeUntil(this.destroy$),
distinctUntilKeyChanged('field')
)
.subscribe((filter) => {
const newField = this.fields.find((_: Field) => _.id === filter.field) || this.fields[0];
this.field$.next(newField);
});
this.field$
.pipe(
takeUntil(this.destroy$),
skip(1)
)
.subscribe(({operator}) => {
this.operator$.next(Object.keys(operator)[0]);
this.value$.next();
});
combineLatest(this.field$, this.operator$, this.value$)
.subscribe(([field, operator, value]) => {
this.field = field;
this.operator = operator;
this.value = value;
this.filter.field = field.id;
this.filter.operator = operator;
this.filter.value = value;
});
this.filter$.next(this.filter);
this.operator$.next(this.filter.operator);
this.value$.next(this.filter.value);
}
constructor (private fieldsService: FieldsService) {}
}