import { DataSource } from '@angular/cdk/collections'; import { EventEmitter } from '@angular/core'; import { MatPaginator, PageEvent } from '@angular/material/paginator'; import { merge, Observable, of as observableOf } from 'rxjs'; import { map, tap } from 'rxjs/operators'; import { Case } from '../../core/case'; export class CaseListDataSource extends DataSource { private dataValues: Case[] = []; private searchValues = ''; private data: Observable; private search: Observable; constructor( public d: Observable, public s: Observable, private paginator?: MatPaginator, ) { super(); this.data = d.pipe(tap((x) => (this.dataValues = x))); this.search = s.pipe(tap((x) => (this.searchValues = x))); } connect(): Observable { const dataMutations: (Observable | Observable | EventEmitter)[] = [ this.data, this.search, ]; if (this.paginator) { dataMutations.push((this.paginator as MatPaginator).page); } return merge(...dataMutations) .pipe( map(() => this.getFilteredData([...this.dataValues])), tap((x: Case[]) => { if (this.paginator) { this.paginator.length = x.length; } }), ) .pipe(map((x: Case[]) => this.getPagedData(x))); } disconnect() {} private getFilteredData(data: Case[]): Case[] { return this.searchValues.split(' ').reduce( (p: Case[], c: string) => p.filter((x) => { const accountString = `${x.caseSource.prefix}-${x.officeFileNumber} ${x.courtCaseNumber} ${x.year} ${x.title} ${x.docketNumber} ${x.remarks}`.toLowerCase(); return accountString.indexOf(c) !== -1; }), Object.assign([], data), ); } private getPagedData(data: Case[]) { if (this.paginator === undefined) { return data; } const startIndex = this.paginator.pageIndex * this.paginator.pageSize; return data.slice(startIndex, startIndex + this.paginator.pageSize); } }