import { Component, Input, EventEmitter, Output, HostBinding, HostListener, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; import { SortDirection, SortType, SelectionType, TableColumn } from '../../types'; import { nextSortDir } from '../../utils'; import { MouseEvent } from '../../events'; @Component({ selector: 'datatable-header-cell', template: `
`, host: { class: 'datatable-header-cell' }, changeDetection: ChangeDetectionStrategy.OnPush }) export class DataTableHeaderCellComponent { @Input() sortType: SortType; @Input() sortAscendingIcon: string; @Input() sortDescendingIcon: string; @Input() isTarget: boolean; @Input() targetMarkerTemplate: any; @Input() targetMarkerContext: any; _allRowsSelected: boolean; @Input() set allRowsSelected(value) { this._allRowsSelected = value; this.cellContext.allRowsSelected = value; } get allRowsSelected() { return this._allRowsSelected; } @Input() selectionType: SelectionType; @Input() set column(column: TableColumn) { this._column = column; this.cellContext.column = column; this.cd.markForCheck(); } get column(): TableColumn { return this._column; } @HostBinding('style.height.px') @Input() headerHeight: number; @Input() set sorts(val: any[]) { this._sorts = val; this.sortDir = this.calcSortDir(val); this.cellContext.sortDir = this.sortDir; this.sortClass = this.calcSortClass(this.sortDir); this.cd.markForCheck(); } get sorts(): any[] { return this._sorts; } @Output() sort: EventEmitter = new EventEmitter(); @Output() select: EventEmitter = new EventEmitter(); @Output() columnContextmenu = new EventEmitter<{ event: MouseEvent, column: any }>(false); @HostBinding('class') get columnCssClasses(): any { let cls = 'datatable-header-cell'; if (this.column.sortable) cls += ' sortable'; if (this.column.resizeable) cls += ' resizeable'; if (this.column.headerClass) { if (typeof this.column.headerClass === 'string') { cls += ' ' + this.column.headerClass; } else if (typeof this.column.headerClass === 'function') { const res = this.column.headerClass({ column: this.column }); if (typeof res === 'string') { cls += res; } else if (typeof res === 'object') { const keys = Object.keys(res); for (const k of keys) { if (res[k] === true) cls += ` ${k}`; } } } } const sortDir = this.sortDir; if (sortDir) { cls += ` sort-active sort-${sortDir}`; } return cls; } @HostBinding('attr.title') get name(): string { // guaranteed to have a value by setColumnDefaults() in column-helper.ts return this.column.headerTemplate === undefined ? this.column.name : undefined; } @HostBinding('style.minWidth.px') get minWidth(): number { return this.column.minWidth; } @HostBinding('style.maxWidth.px') get maxWidth(): number { return this.column.maxWidth; } @HostBinding('style.width.px') get width(): number { return this.column.width; } get isCheckboxable(): boolean { return this.column.checkboxable && this.column.headerCheckboxable && this.selectionType === SelectionType.checkbox; } sortFn = this.onSort.bind(this); sortClass: string; sortDir: SortDirection; selectFn = this.select.emit.bind(this.select); cellContext: any = { column: this.column, sortDir: this.sortDir, sortFn: this.sortFn, allRowsSelected: this.allRowsSelected, selectFn: this.selectFn }; private _column: TableColumn; private _sorts: any[]; constructor(private cd: ChangeDetectorRef) { } @HostListener('contextmenu', ['$event']) onContextmenu($event: MouseEvent): void { this.columnContextmenu.emit({ event: $event, column: this.column }); } calcSortDir(sorts: any[]): any { if (sorts && this.column) { const sort = sorts.find((s: any) => { return s.prop === this.column.prop; }); if (sort) return sort.dir; } } onSort(): void { if (!this.column.sortable) return; const newValue = nextSortDir(this.sortType, this.sortDir); this.sort.emit({ column: this.column, prevValue: this.sortDir, newValue }); } calcSortClass(sortDir: SortDirection): string { if (sortDir === SortDirection.asc) { return `sort-btn sort-asc ${this.sortAscendingIcon}`; } else if (sortDir === SortDirection.desc) { return `sort-btn sort-desc ${this.sortDescendingIcon}`; } else { return `sort-btn`; } } }