import { PercentPipe } from '@angular/common'; import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild, inject, AfterViewInit } from '@angular/core'; import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; import { MatSort, MatSortModule } from '@angular/material/sort'; import { MatTableModule } from '@angular/material/table'; import { ActivatedRoute, Router, RouterLink } from '@angular/router'; import { debounceTime, distinctUntilChanged, Observable } from 'rxjs'; import { Customer } from '../../core/customer'; import { PagedResult } from '../../core/paged-result'; import { CustomerListDatasource } from './customer-list-datasource'; @Component({ selector: 'app-customer-list', templateUrl: './customer-list.component.html', styleUrls: ['./customer-list.component.css'], imports: [ MatButtonModule, MatIconModule, MatTableModule, PercentPipe, RouterLink, MatInputModule, MatPaginatorModule, MatSortModule, ReactiveFormsModule, ], }) export class CustomerListComponent implements OnInit, AfterViewInit { private route = inject(ActivatedRoute); private router = inject(Router); private cdr = inject(ChangeDetectorRef); @ViewChild('filterElement', { static: true }) filterElement!: ElementRef; @ViewChild(MatPaginator, { static: true }) paginator!: MatPaginator; @ViewChild(MatSort, { static: true }) sort!: MatSort; data: PagedResult = new PagedResult([], 0, 0, 0); filter: Observable; dataSource: CustomerListDatasource; form: FormGroup<{ filter: FormControl; }>; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['name', 'phone', 'address', 'printInBill', 'discounts']; constructor() { this.form = new FormGroup({ filter: new FormControl('', { nonNullable: true }), }); this.filter = this.form.controls.filter.valueChanges.pipe(debounceTime(150), distinctUntilChanged()); this.dataSource = new CustomerListDatasource(this.data, this.paginator, this.sort); } ngOnInit() { const q = this.route.snapshot.queryParamMap.get('q'); if (q) { this.form.controls.filter.setValue(q, { emitEvent: false }); // Prevent infinite loop } this.route.data.subscribe((value) => { const data = value as { data: PagedResult }; data.data.items.forEach((c: Customer) => (c.discounts = c.discounts.filter((d) => d.discount !== 0))); this.data = data.data; this.dataSource = new CustomerListDatasource(this.data, this.paginator, this.sort); this.cdr.detectChanges(); }); this.sort.sortChange.subscribe({ next: () => this.router.navigate([], { relativeTo: this.route, queryParams: { f: this.sort?.active ?? 'name', d: this.sort?.direction }, queryParamsHandling: 'merge', }), }); this.paginator.page.subscribe({ next: () => this.router.navigate([], { relativeTo: this.route, queryParams: { s: this.paginator.pageSize, p: this.paginator.pageIndex }, queryParamsHandling: 'merge', }), }); this.filter.subscribe({ next: (value) => { this.router.navigate([], { relativeTo: this.route, queryParams: { q: value }, queryParamsHandling: 'merge', }); }, }); } ngAfterViewInit() { setTimeout(() => { this.filterElement.nativeElement.focus(); }, 0); } }