Skip to content
Snippets Groups Projects
datatable.component.ts 5.23 KiB
/**
 * This file is part of Anis Client.
 *
 * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';

import { Instance, Attribute, Dataset, DetailRendererConfig, DownloadRendererConfig, ImageRendererConfig, LinkRendererConfig, RendererConfig } from 'src/app/metamodel/models';
import { Pagination, PaginationOrder, SearchQueryParams } from 'src/app/instance/store/models';

@Component({
    selector: 'app-datatable',
    templateUrl: 'datatable.component.html',
    styleUrls: ['datatable.component.scss'],
})
/**
 * @class
 * @classdesc Datatable component.
 *
 * @implements OnInit
 */
export class DatatableComponent implements OnInit {
    @Input() dataset: Dataset;
    @Input() instance: Instance;
    @Input() attributeList: Attribute[];
    @Input() outputList: number[];
    @Input() queryParams: SearchQueryParams;
    @Input() dataLength: number;
    @Input() data: any[];
    @Input() dataIsLoading: boolean;
    @Input() dataIsLoaded: boolean;
    @Input() selectedData: any[] = [];
    @Output() retrieveData: EventEmitter<Pagination> = new EventEmitter();
    @Output() addSelectedData: EventEmitter<number | string> = new EventEmitter();
    @Output() deleteSelectedData: EventEmitter<number | string> = new EventEmitter();

    public page = 1;
    public nbItems = 10;
    public sortedCol: number = null;
    public sortedOrder: PaginationOrder = PaginationOrder.a;
    
    ngOnInit() {
        this.sortedCol = this.attributeList.find(a => a.order_by).id;
        Promise.resolve(null).then(() => this.retrieveData.emit({
            dname: this.dataset.name,
            page: this.page,
            nbItems: this.nbItems,
            sortedCol: this.sortedCol,
            order: this.sortedOrder
        }));
    }

    getRendererConfig(attribute: Attribute) {
        let config = null;
        switch(attribute.renderer) {
            case 'detail':
                config = attribute.renderer_config as DetailRendererConfig;
                break;
            case 'link':
                config = attribute.renderer_config as LinkRendererConfig;
                break;
            case 'download':
                config = attribute.renderer_config as DownloadRendererConfig;
                break;
            case 'image':
                config = attribute.renderer_config as ImageRendererConfig;
                break;
            case 'json':
                config = attribute.renderer_config as RendererConfig;
                break;
            default:
                config = null;
        }
        return config;
    }

    /**
     * Returns output list from attribute list.
     *
     * @return Attribute[]
     */
    getOutputList(): Attribute[] {
        return this.attributeList
            .filter(a => this.outputList.includes(a.id))
            .sort((a, b) => a.output_display - b.output_display);
    }

    /**
     * Emits events to select or unselect data.
     *
     * @param  {any} datum - The data to select or unselect.
     *
     * @fires EventEmitter<number | string>
     */
    toggleSelection(datum: any): void {
        const attribute = this.attributeList.find(a => a.search_flag === 'ID');
        const index = this.selectedData.indexOf(datum[attribute.label]);
        if (index > -1) {
            this.deleteSelectedData.emit(datum[attribute.label]);
        } else {
            this.addSelectedData.emit(datum[attribute.label]);
        }
    }

    /**
     * Checks if data is selected.
     *
     * @param  {any} datum - The data.
     *
     * @return boolean
     */
    isSelected(datum: any): boolean {
        const attribute = this.attributeList.find(a => a.search_flag === 'ID');

        if (this.selectedData.indexOf(datum[attribute.label]) > -1) {
            return true;
        }
        return false;
    }

    /**
     * Emits event to change datatable page.
     *
     * @param  {number} nb - The page number to access.
     *
     * @fires EventEmitter<Pagination>
     */
    changePage(nb: number): void {
        this.page = nb;
        const pagination: Pagination = {
            dname: this.dataset.name,
            page: this.page,
            nbItems: this.nbItems,
            sortedCol: this.sortedCol,
            order: this.sortedOrder
        };
        this.retrieveData.emit(pagination);
    }

    /**
     * Emits event to change datatable displayed items.
     *
     * @param  {number} nb - The number of items to display.
     *
     * @fires EventEmitter<Pagination>
     */
    changeNbItems(nb: number): void {
        this.nbItems = nb;
        this.changePage(1);
    }

    /**
     * Emits event to change the sorted order and the sorted column of the datatable.
     *
     * @param  {number} id - The id of the column to sort.
     *
     * @fires EventEmitter<Pagination>
     */
    sort(id: number): void {
        if (id === this.sortedCol) {
            this.sortedOrder = this.sortedOrder === PaginationOrder.a ? PaginationOrder.d : PaginationOrder.a;
        } else {
            this.sortedCol = id;
            this.sortedOrder = PaginationOrder.a;
        }
        this.changePage(1);
    }
}