exercises

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

paginate.component.ts (2343B)


      1 import { Component, input, computed, inject } from '@angular/core';
      2 import { CommonModule } from '@angular/common';
      3 import { Router, ActivatedRoute } from '@angular/router';
      4 
      5 @Component({
      6   selector: 'div.pagination',
      7   templateUrl: './paginate.component.html',
      8   styleUrls: ['./paginate.component.scss'],
      9   standalone: true,
     10   imports: [CommonModule],
     11 })
     12 export class PaginateComponent {
     13   private router = inject(Router);
     14   private route = inject(ActivatedRoute);
     15 
     16   // Inputs from parent
     17   readonly totalPages = input.required<number>();
     18   readonly total = input.required<number>();
     19   readonly page = input.required<number>();
     20   readonly pageSize = input.required<number>();
     21 
     22   // Available page sizes
     23   readonly pageSizes = [10, 20, 50, 100];
     24 
     25   // Computed properties
     26   readonly canGoPrevious = computed(() => this.page() > 1);
     27   readonly canGoNext = computed(() => this.page() < this.totalPages());
     28   readonly startItem = computed(() => (this.page() - 1) * this.pageSize() + 1);
     29   readonly endItem = computed(() => Math.min(this.page() * this.pageSize(), this.total()));
     30 
     31   // Update URL query params - Angular inputs will auto-update from URL changes
     32   private navigate(page: number, pageSize = this.pageSize()): void {
     33     this.router.navigate([], {
     34       relativeTo: this.route,
     35       queryParams: { page, pageSize },
     36       queryParamsHandling: 'merge',
     37     });
     38   }
     39 
     40   // Get visible page numbers with smart ellipsis
     41   getVisiblePages(): (number | string)[] {
     42     const total = this.totalPages();
     43     const current = this.page();
     44 
     45     if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1);
     46 
     47     const pages: (number | string)[] = [1];
     48 
     49     if (current <= 4) {
     50       pages.push(...[2, 3, 4, 5], '...', total);
     51     } else if (current >= total - 3) {
     52       pages.push('...', ...Array.from({ length: 5 }, (_, i) => total - 4 + i));
     53     } else {
     54       pages.push('...', current - 1, current, current + 1, '...', total);
     55     }
     56 
     57     return pages;
     58   }
     59 
     60   // Navigation methods
     61   goToPage(page: number): void {
     62     if (page >= 1 && page <= this.totalPages()) {
     63       this.navigate(page);
     64     }
     65   }
     66 
     67   onPageSizeChange(event: Event): void {
     68     const size = +(event.target as HTMLSelectElement).value;
     69     if (this.pageSizes.includes(size)) {
     70       this.navigate(1, size); // Reset to page 1 when changing page size
     71     }
     72   }
     73 }