11import { DecimalPipe , CommonModule } from '@angular/common' ;
2- import { Component , ViewChild , OnInit , inject , signal } from '@angular/core' ;
3- import { FormsModule , ReactiveFormsModule } from '@angular/forms' ;
2+ import { Component , ViewChild , OnInit , inject , signal , computed , AfterViewInit } from '@angular/core' ;
3+ import { FormsModule , ReactiveFormsModule } from '@angular/forms' ;
44import { Router , RouterModule } from '@angular/router' ;
5- import { MatPaginatorModule } from '@angular/material/paginator' ;
5+ import { MatPaginator , MatPaginatorModule , PageEvent } from '@angular/material/paginator' ;
66import { MatFormFieldModule } from '@angular/material/form-field' ;
77import { MatInputModule } from '@angular/material/input' ;
88import { MatTableModule } from '@angular/material/table' ;
99import { MatIconModule } from '@angular/material/icon' ;
1010import { MatButtonModule } from '@angular/material/button' ;
1111import { MatTooltipModule } from '@angular/material/tooltip' ;
12- import { MatSort , MatSortModule } from '@angular/material/sort' ;
12+ import { MatSort , MatSortModule , Sort } from '@angular/material/sort' ;
1313import { MatTableDataSource } from '@angular/material/table' ;
1414import { ContactService } from '@features/contact/contact.service' ;
1515import { HasPermissionDirective } from '@core/directives/permission.directive' ;
@@ -37,22 +37,38 @@ import { NotificationService } from '@core/services/notification.service';
3737 styleUrl : './contact-list.component.scss' ,
3838 providers : [ DecimalPipe , ContactService ]
3939} )
40- export class ContactListComponent implements OnInit {
40+ export class ContactListComponent implements OnInit , AfterViewInit {
4141 private contactService = inject ( ContactService ) ;
4242 private router = inject ( Router ) ;
4343 private notificationService = inject ( NotificationService ) ;
4444
4545 contacts = signal < any [ ] > ( [ ] ) ;
46+ filteredContacts = signal < any [ ] > ( [ ] ) ;
4647 dataSource = signal < MatTableDataSource < any > > ( new MatTableDataSource ( [ ] ) ) ;
4748 displayedColumns = [ 'name' , 'email' , 'phone' , 'city' , 'actions' ] ;
4849 loading = signal < boolean > ( false ) ;
4950
51+ // Pagination related signals
52+ pageSize = signal < number > ( 10 ) ;
53+ currentPage = signal < number > ( 0 ) ;
54+ pageSizeOptions = [ 5 , 10 , 25 , 50 ] ;
55+ totalItems = computed ( ( ) => this . filteredContacts ( ) . length ) ;
56+
5057 @ViewChild ( MatSort ) sort ! : MatSort ;
58+ @ViewChild ( MatPaginator ) paginator ! : MatPaginator ;
5159
5260 ngOnInit ( ) : void {
5361 this . loadContacts ( ) ;
5462 }
5563
64+ ngAfterViewInit ( ) {
65+ // Connect the sort and paginator after the view is initialized
66+ if ( this . dataSource ( ) ) {
67+ this . dataSource ( ) . sort = this . sort ;
68+ this . dataSource ( ) . paginator = this . paginator ;
69+ }
70+ }
71+
5672 loadContacts ( ) : void {
5773 this . loading . set ( true ) ;
5874 this . contactService . getAll ( ) . subscribe ( {
@@ -61,8 +77,19 @@ export class ContactListComponent implements OnInit {
6177 new Date ( b . create_date ) . getTime ( ) - new Date ( a . create_date ) . getTime ( )
6278 ) ;
6379 this . contacts . set ( sortedData ) ;
64- this . dataSource . set ( new MatTableDataSource ( sortedData ) ) ;
65- this . dataSource ( ) . sort = this . sort ;
80+ this . filteredContacts . set ( sortedData ) ;
81+
82+ const dataSource = new MatTableDataSource ( sortedData ) ;
83+ this . dataSource . set ( dataSource ) ;
84+
85+ // Initialize sort and paginator if they're available
86+ if ( this . sort ) {
87+ dataSource . sort = this . sort ;
88+ }
89+ if ( this . paginator ) {
90+ dataSource . paginator = this . paginator ;
91+ }
92+
6693 this . loading . set ( false ) ;
6794 } ,
6895 error : ( error ) => {
@@ -75,6 +102,61 @@ export class ContactListComponent implements OnInit {
75102 applyFilter ( event : Event ) {
76103 const filterValue = ( event . target as HTMLInputElement ) . value ;
77104 this . dataSource ( ) . filter = filterValue . trim ( ) . toLowerCase ( ) ;
105+
106+ // Reset to first page when filtering
107+ if ( this . dataSource ( ) . paginator ) {
108+ this . dataSource ( ) . paginator . firstPage ( ) ;
109+ }
110+ }
111+
112+ pageChanged ( event : PageEvent ) : void {
113+ this . pageSize . set ( event . pageSize ) ;
114+ this . currentPage . set ( event . pageIndex ) ;
115+
116+ // Update the data source's pagination parameters
117+ if ( this . dataSource ( ) ) {
118+ // This ensures the MatTableDataSource is aware of the new page size
119+ this . dataSource ( ) . paginator = this . paginator ;
120+
121+ // Force the data source to reflect changes by resetting its data
122+ // This is important when items per page changes
123+ const currentData = this . dataSource ( ) . data ;
124+ this . dataSource ( ) . data = [ ...currentData ] ;
125+ }
126+ }
127+
128+ sortData ( sort : Sort ) : void {
129+ if ( ! sort . active || sort . direction === '' ) {
130+ // If sorting is cleared, revert to original data
131+ this . dataSource ( ) . data = this . filteredContacts ( ) ;
132+ return ;
133+ }
134+
135+ this . dataSource ( ) . data = [ ...this . filteredContacts ( ) ] . sort ( ( a , b ) => {
136+ const isAsc = sort . direction === 'asc' ;
137+ switch ( sort . active ) {
138+ case 'name' :
139+ return this . compareNames ( a , b , isAsc ) ;
140+ case 'email' :
141+ return this . compare ( a . email , b . email , isAsc ) ;
142+ case 'phone' :
143+ return this . compare ( a . mobile , b . mobile , isAsc ) ;
144+ case 'city' :
145+ return this . compare ( a . city , b . city , isAsc ) ;
146+ default :
147+ return 0 ;
148+ }
149+ } ) ;
150+ }
151+
152+ compareNames ( a : any , b : any , isAsc : boolean ) : number {
153+ const nameA = `${ a . firstName } ${ a . lastName } ` . toLowerCase ( ) ;
154+ const nameB = `${ b . firstName } ${ b . lastName } ` . toLowerCase ( ) ;
155+ return ( nameA < nameB ? - 1 : 1 ) * ( isAsc ? 1 : - 1 ) ;
156+ }
157+
158+ compare ( a : string | number , b : string | number , isAsc : boolean ) : number {
159+ return ( a < b ? - 1 : 1 ) * ( isAsc ? 1 : - 1 ) ;
78160 }
79161
80162 deleteContact ( contact : any ) : void {
0 commit comments