UNPKG

igniteui-angular-sovn

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

129 lines (109 loc) 4.01 kB
import type { KeyOfOrString } from '../core/types'; import { IBaseEventArgs } from '../core/utils'; import { GridType } from '../grids/common/grid.interface'; export enum SortingDirection { None = 0, Asc = 1, Desc = 2 } export interface ISortingExpression<T = any> extends IBaseEventArgs { fieldName: KeyOfOrString<T> & string; dir: SortingDirection; ignoreCase?: boolean; strategy?: ISortingStrategy; } export interface ISortingStrategy { sort: ( data: any[], fieldName: string, dir: SortingDirection, ignoreCase: boolean, valueResolver: (obj: any, key: string, isDate?: boolean) => any, isDate?: boolean, isTime?: boolean, grid?: GridType ) => any[]; } export class DefaultSortingStrategy implements ISortingStrategy { protected static _instance: DefaultSortingStrategy = null; protected constructor() { } public static instance(): DefaultSortingStrategy { return this._instance || (this._instance = new this()); } public sort( data: any[], fieldName: string, dir: SortingDirection, ignoreCase: boolean, valueResolver: (obj: any, key: string, isDate?: boolean) => any, isDate?: boolean, isTime?: boolean ) { const key = fieldName; const reverse = (dir === SortingDirection.Desc ? -1 : 1); const cmpFunc = (obj1: any, obj2: any) => this.compareObjects(obj1, obj2, key, reverse, ignoreCase, valueResolver, isDate, isTime); return this.arraySort(data, cmpFunc); } public compareValues(a: any, b: any): number { const an = (a === null || a === undefined); const bn = (b === null || b === undefined); if (an) { if (bn) { return 0; } return -1; } else if (bn) { return 1; } return a > b ? 1 : a < b ? -1 : 0; } protected compareObjects( obj1: any, obj2: any, key: string, reverse: number, ignoreCase: boolean, valueResolver: (obj: any, key: string, isDate?: boolean, isTime?: boolean) => any, isDate: boolean, isTime: boolean ) { let a = valueResolver.call(this, obj1, key, isDate, isTime); let b = valueResolver.call(this, obj2, key, isDate, isTime); if (ignoreCase) { a = a && a.toLowerCase ? a.toLowerCase() : a; b = b && b.toLowerCase ? b.toLowerCase() : b; } return reverse * this.compareValues(a, b); } protected arraySort(data: any[], compareFn?: (arg0: any, arg1: any) => number): any[] { return data.sort(compareFn); } } export class GroupMemberCountSortingStrategy implements ISortingStrategy { protected static _instance: GroupMemberCountSortingStrategy = null; protected constructor() { } public static instance(): GroupMemberCountSortingStrategy { return this._instance || (this._instance = new this()); } public sort(data: any[], fieldName: string, dir: SortingDirection) { const groupedArray = this.groupBy(data, fieldName); const reverse = (dir === SortingDirection.Desc ? -1 : 1); const cmpFunc = (a, b) => { return this.compareObjects(a, b, groupedArray, fieldName, reverse); }; return data .sort((a, b) => a[fieldName].localeCompare(b[fieldName])) .sort(cmpFunc); } public groupBy(data, key) { return data.reduce((acc, curr) => { (acc[curr[key]] = acc[curr[key]] || []).push(curr); return acc; }, {}) } protected compareObjects(obj1: any, obj2: any, data: any[], fieldName: string, reverse: number) { const firstItemValuesLength = data[obj1[fieldName]].length; const secondItemValuesLength = data[obj2[fieldName]].length; return reverse * (firstItemValuesLength - secondItemValuesLength); } }