all files / common/core/sorting/ sorting.service.ts

100% Statements 30/30
92.86% Branches 13/14
100% Functions 9/9
100% Lines 28/28
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70                                30×               30× 29× 29× 29× 42× 42× 42× 15×       30×                 14× 14× 14× 14×   55× 43×   12×   12× 12×     55×      
/*
 *  @license
 *  Copyright Hôpitaux Universitaires de Genève. All Rights Reserved.
 *
 *  Use of this source code is governed by an Apache-2.0 license that can be
 *  found in the LICENSE file at https://github.com/DSI-HUG/dejajs-components/blob/master/LICENSE
 */
 
import * as _ from 'lodash';
import { Observable, of as observableOf } from 'rxjs';
import { map, reduce, switchMap } from 'rxjs/operators';
import { ISortInfos } from './sort-infos.model';
import { SortOrder } from './sort-order.model';
 
/** Classe de tri d'une liste plate ou hierarchique */
export class SortingService {
    /** Trie les éléments de la liste plate spécifiée en fonction du modèle de tri spécifié. Peut être surchargé pour implémenter un tri asynchrone
     * @param list Liste à trier.
     * @param sortInfos Modèle de tri à appliquer.
     * @return Observable résolu par la fonction.
     */
    public sort$(list: any[], sortInfos: ISortInfos | ISortInfos[]) {
        return observableOf(this.sort(list, sortInfos));
    }
 
    /** Trie les éléments de la liste plate spécifiée en fonction du modèle de tri spécifié
     * @param list Liste à trier.
     * @param sortInfos Modèle de tri à appliquer.
     * @return Liste triée.
     */
    public sort(list: any[], sortInfos: ISortInfos | ISortInfos[]) {
        if (list && list.length) {
            const sis = sortInfos instanceof Array ? sortInfos : [sortInfos];
            let i = sis.length;
            while (--i >= 0) {
                const si = sis[i];
                list = _.sortBy(list, si.name);
                if (si.order === SortOrder.descending) {
                    list = list.reverse();
                }
            }
        }
        return list;
    }
 
    /** Trie les éléments de la liste hierarchique spécifiée en fonction du modèle de tri spécifié.  Peut être surchargé pour implémenter un tri asynchrone
     * @param tree Liste à trier.
     * @param sortInfos Modèle de tri à appliquer.
     * @param childrenField Champ à utiliser pour la recherche dans les enfants d'un parent.
     * @return Observable résolue par la fonction.
     */
    public sortTree$(tree: any[], sortInfos: ISortInfos | ISortInfos[], childrenField?: string): Observable<any[]> {
        childrenField = childrenField || 'items';
        return this.sort$(tree, sortInfos).pipe(
            switchMap((child) => child),
            switchMap((child) => {
                if (!child || !child[childrenField]) {
                    return observableOf(child);
                }
                return this.sortTree$(child[childrenField], sortInfos, childrenField).pipe(
                    map((sortedList) => {
                        child[childrenField] = sortedList;
                        return child;
                    }));
            }),
            reduce((acc: any[], cur: any) => [...acc, cur], []));
    }
}