// /src/app/shared/components/table/generic-table/generic-table.component.ts import { Component, Input, Output, EventEmitter, SimpleChanges, OnChanges, OnInit } from '@angular/core'; import { CommonModule, CurrencyPipe } from '@angular/common'; import { StatusPillComponent } from '../../ui/status-pill/status-pill.component'; import { ButtonComponent } from '../../ui/button/button.component'; import { PaginatorComponent } from '../paginator/paginator.component'; export type ColumnType = 'text' | 'currency' | 'status' | 'image-text' | 'image' | 'actions' | 'date' | 'number'; export interface ColumnConfig { key: string; title: string; type: ColumnType; imageKey?: string; subKey?: string; cssClass?: string; } @Component({ selector: 'app-generic-table', standalone: true, imports: [ CommonModule, CurrencyPipe, StatusPillComponent, ButtonComponent, PaginatorComponent ], templateUrl: './generic-table.component.html', styleUrl: './generic-table.component.css', }) export class GenericTableComponent implements OnChanges, OnInit { @Input() data: any[] = []; @Input() columns: ColumnConfig[] = []; @Input() itemsPerPage = 10; @Output() view = new EventEmitter(); @Output() edit = new EventEmitter(); @Output() delete = new EventEmitter(); public displayedData: any[] = []; public currentPage = 1; public readonly fallbackImage = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MCIgaGVpZ2h0PSI1MCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNjY2NjY2MiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cmVjdCB3aWR0aD0iMTgiIGhlaWdodD0iMTgiIHg9IjMiIHk9IjMiIHJ4PSIyIiByeT0iMiIvPjxjaXJjbGUgY3g9IjkiIGN5PSI5IiByPSIyIi8+PHBhdGggZD0ibTIxIDE1LTUtNWwtNSA1bC0yLTJsLTUgNSIvPjwvc3ZnPg=='; ngOnInit(): void { this.updatePagination(); } ngOnChanges(changes: SimpleChanges): void { if (changes['data']) { this.currentPage = 1; this.updatePagination(); } } onPageChange(newPage: number): void { this.currentPage = newPage; this.updatePagination(); } private updatePagination(): void { const startIndex = (this.currentPage - 1) * this.itemsPerPage; const endIndex = startIndex + this.itemsPerPage; this.displayedData = this.data.slice(startIndex, endIndex); } getProperty(item: any, key: string): any { if (!key) return ''; return key.split('.').reduce((obj, part) => obj && obj[part], item); } }