common-ui/src/lib/sorting/sorting.service.ts
2021-10-11 13:13:27 +03:00

51 lines
1.7 KiB
TypeScript

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<T extends IListable> {
private readonly _sortingOption$ = new BehaviorSubject<SortingOption<T>>({
column: 'searchKey',
order: SortingOrders.asc,
});
readonly sortingOption$ = this._sortingOption$.asObservable().pipe(distinctUntilChanged(), shareReplay());
get sortingOption(): SortingOption<T> | undefined {
return this._sortingOption$.getValue();
}
static sort<T>(values: T[], order?: SortingOrder, column?: KeysOf<T>): 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<T>): void {
this._sortingOption$.next(value);
}
defaultSort(values: T[]): T[] {
return SortingService.sort(values, this.sortingOption?.order, this.sortingOption?.column);
}
toggleSort(column: KeysOf<T>): void {
const sameColumn = this.sortingOption?.column === column;
const order = sameColumn ? SortingOrders.inverseOf(this.sortingOption?.order) : SortingOrders.asc;
this._sortingOption$.next({ column, order });
}
}