import { Component, ContentChild, EventEmitter, Input, OnInit, Output, TemplateRef, OnChanges, SimpleChanges, ChangeDetectorRef } from '@angular/core'; import {ColumnOptions, SortableColumn, Table} from './table-settings.model'; @Component({ selector: 'onguard-table', templateUrl: './table.component.html', styleUrls: ['./table.component.scss'] }) export class TableComponent implements OnInit, OnChanges { @ContentChild('tableRow') rowTemplate: TemplateRef; @Input() model: Table; @Input() serverSide = false; @Input() loading: boolean; @Input() triggerFilter = false; @Output() sortChange: EventEmitter = new EventEmitter(); @Output() requestPage: EventEmitter = new EventEmitter(); public filteredData: T[]; public pageData: T[]; @Input() filterFunction: (item: T, index: number, array: T[]) => boolean = (item: T) => true; constructor() { } public track(index: number, item: T): string { return item[Object.keys(item)[0]]; } // Sorting public toggleSort(columnName: string): void { const sortCol = this.model.sorting.find(col => col.name === columnName); if (sortCol) { this.model.sorting .filter(col => col !== sortCol) .forEach(col => col.sort = false); if (sortCol.sort === 'asc') { sortCol.sort = 'desc'; } else { sortCol.sort = 'asc'; } this.sortChange.emit(sortCol); this.sort(); } } public getSortDirection(columnName: string): 'asc' | 'desc' | 'unsorted' { const cols = this.model.sorting.filter(s => s.name === columnName); if (cols.length === 1) { const col = cols[0]; return col.sort || 'unsorted'; } return 'desc'; } public sort(): void { const sortedCol = this.model.sorting.find(col => col.sort); if (!this.serverSide && sortedCol) { const colOptions = this.model.columnSettings[sortedCol.name] as ColumnOptions; this.filteredData = this.filteredData.sort((a, b) => { let sortOrder = colOptions.compareValues(a[sortedCol.name], b[sortedCol.name]); if (sortedCol.sort === 'asc') { sortOrder *= -1; } return sortOrder; }); this.calcPages(1); } } // Paging // public onPageChange(pageNumber: number): void { // Let paging be handled externally if serverside if (this.serverSide && this.model.paging) { this.requestPage.emit(pageNumber); return; } this.calcPages(pageNumber); } private calcPages(setToPage?: number): void { const paging = this.model.paging; paging.pageCount = Math.ceil(this.filteredData.length / paging.perPage); if (setToPage) { this.setPage(setToPage); } this.model.paging = paging; } public setPage(setToPage: number): void { const paging = this.model.paging; const start = (setToPage - 1) * paging.perPage; this.pageData = this.filteredData.slice(start, start + paging.perPage); paging.currentPage = setToPage; this.model.paging = paging; } // Lifecycle // public ngOnInit(): void { if (this.model && this.model.data) { this.filteredData = this.model.data.filter(this.filterFunction); this.setPage(1); } } public ngOnChanges(changes: SimpleChanges): void { // Handle filter Changes if ( this.model && this.model.data && (changes.filterFunction && changes.filterFunction.currentValue !== changes.filterFunction.previousValue ) || (changes.model && this.model ) ) { this.filteredData = this.model.data.filter(this.filterFunction); this.sort(); } } }