51 lines
1.7 KiB
TypeScript
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 });
|
|
}
|
|
}
|