import { Injectable } from '@angular/core'; import { orderBy } from 'lodash'; import { BehaviorSubject } from 'rxjs'; import { SortingOption } from './models/sorting-option.model'; import { SortingOrder, SortingOrders } from './models/sorting-order.type'; import { KeysOf } from '../utils'; import { IListable } from '../listing'; import { distinctUntilChanged, shareReplay } from 'rxjs/operators'; @Injectable() export class SortingService { private readonly _sortingOption$ = new BehaviorSubject>({ column: 'searchKey', order: SortingOrders.asc, }); readonly sortingOption$ = this._sortingOption$.asObservable().pipe(distinctUntilChanged(), shareReplay()); get sortingOption(): SortingOption | undefined { return this._sortingOption$.getValue(); } static sort(values: T[], order?: SortingOrder, column?: KeysOf): T[] { if (!values || values.length <= 1 || !order) { return values; } if (!column) { /** sort 1D array */ const result = [...values].sort(); return order === SortingOrders.asc ? result : result.reverse(); } return orderBy(values, [column], [order]); } setSortingOption(value: SortingOption): void { this._sortingOption$.next(value); } defaultSort(values: T[]): T[] { return SortingService.sort(values, this.sortingOption?.order, this.sortingOption?.column); } toggleSort(column: KeysOf): void { const sameColumn = this.sortingOption?.column === column; const order = sameColumn ? SortingOrders.inverseOf(this.sortingOption?.order) : SortingOrders.asc; this._sortingOption$.next({ column, order }); } }