import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, forwardRef, Inject, Input, OnChanges, Output, SimpleChanges, TemplateRef, ViewChild, ViewContainerRef, } from '@angular/core'; import { AutoUnsubscribe } from '../../utils'; import { IListable, ListingModes, TableColumnConfig } from '../models'; import { ListingComponent } from '../listing-component.directive'; import { EntitiesService } from '../services'; import { TableContentComponent } from '../table-content/table-content.component'; const SCROLLBAR_WIDTH = 11; @Component({ selector: 'iqser-table [tableColumnConfigs] [itemSize]', templateUrl: './table.component.html', styleUrls: ['./table.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) export class TableComponent extends AutoUnsubscribe implements OnChanges { readonly listingModes = ListingModes; @Input() tableColumnConfigs!: readonly TableColumnConfig[]; @Input() bulkActions?: TemplateRef; @Input() headerTemplate?: TemplateRef; @Input() itemSize!: number; @Input() selectionEnabled = false; @Input() hasScrollButton = false; @Input() emptyColumnWidth?: string; @Input() totalSize?: number; @Input() classes?: string; @Input() noDataText?: string; @Input() noDataIcon?: string; @Input() noDataButtonIcon?: string; @Input() noDataButtonLabel?: string; @Input() showNoDataButton = false; @Input() noMatchText?: string; @Input() tableItemClasses?: Record boolean>; @Input() itemMouseEnterFn?: (entity: T) => void; @Input() itemMouseLeaveFn?: (entity: T) => void; @Output() readonly noDataAction = new EventEmitter(); @ViewChild(TableContentComponent, { static: true }) private readonly _tableContent!: TableContentComponent; constructor( @Inject(forwardRef(() => ListingComponent)) readonly listingComponent: ListingComponent, private readonly _hostRef: ViewContainerRef, private readonly _changeRef: ChangeDetectorRef, readonly entitiesService: EntitiesService, ) { super(); } get tableHeaderLabel(): string | undefined { return this.listingComponent.tableHeaderLabel; } ngOnChanges(changes: SimpleChanges): void { if (changes.tableColumnConfigs) { this._setStyles(); } } scrollToLastIndex(): void { this._tableContent.scrollToLastIndex(); } private _setStyles(): void { const element = this._hostRef.element.nativeElement as HTMLElement; this._setColumnsWidth(element); this._setItemSize(element); this._changeRef.markForCheck(); } private _setColumnsWidth(element: HTMLElement) { let gridTemplateColumnsHover = ''; if (this.selectionEnabled) { gridTemplateColumnsHover += '30px '; } for (const config of this.tableColumnConfigs) { gridTemplateColumnsHover += `${config.width || '1fr'} `; } gridTemplateColumnsHover += this.emptyColumnWidth || ''; const gridTemplateColumns = `${gridTemplateColumnsHover} ${SCROLLBAR_WIDTH}px`; element.style.setProperty('--gridTemplateColumns', gridTemplateColumns); element.style.setProperty('--gridTemplateColumnsHover', gridTemplateColumnsHover); } private _setItemSize(element: HTMLElement) { element.style.setProperty('--itemSize', `${this.itemSize}px`); } }